I have register screen in SwiftUI, and I want to use two screen for register users, one view have mail and password, and other view have name surname and occupation, but I am still do not understand how I will connect both register view, any idea?
RegistrationViewModel:
enum RegistrationState {
case successfullyRegistered
case failed(error: Error)
case na
}
protocol RegistrationViewModel {
func create()
var service: RegistrationService { get }
var state: RegistrationState { get }
var hasError: Bool { get }
var newUser: RegistrationCredentials { get }
init(service: RegistrationService)
}
final class RegistrationViewModelImpl: ObservableObject, RegistrationViewModel {
let service: RegistrationService
@Published var state: RegistrationState = .na
@Published var newUser = RegistrationCredentials(email: "",
password: "",
firstName: "",
lastName: "",
occupation: "")
@Published var hasError: Bool = false
private var subscriptions = Set<AnyCancellable>()
init(service: RegistrationService) {
self.service = service
setupErrorSubscription()
}
func create() {
service
.register(with: newUser)
.sink { [weak self] res in
switch res {
case .failure(let error):
self?.state = .failed(error: error)
default: break
}
} receiveValue: { [weak self] in
self?.state = .successfullyRegistered
}
.store(in: &subscriptions)}}
private extension RegistrationViewModelImpl {
func setupErrorSubscription() {
$state
.map { state -> Bool in
switch state {
case .successfullyRegistered,
.na:
return false
case .failed:
return true}}
.assign(to: &$hasError)}}
firstscreen:
struct RegisterView: View {
@StateObject private var viewModel = RegistrationViewModelImpl(
service: RegistrationServiceImpl()
)
var body: some View {
NavigationView {
VStack(spacing: 32) {
VStack(spacing: 16) {
InputTextFieldView(text: $viewModel.newUser.email,
placeholder: "Email",
keyboardType: .emailAddress,
systemImage: "envelope")
InputPasswordView(password: $viewModel.newUser.password,
placeholder: "Password",
systemImage: "lock")
}
ButtonView(title: "Next") {
viewModel.create()
}
}
.padding(.horizontal, 15)
.alert(isPresented: $viewModel.hasError,
content: {
if case .failed(let error) = viewModel.state {
return Alert(
title: Text("Error"),
message: Text(error.localizedDescription))
} else {
return Alert(
title: Text("Error"),
message: Text("Something went wrong"))
}})}}}
secondscreen:
import SwiftUI
struct SecondRegisterView: View {
@StateObject private var viewModel = RegistrationViewModelImpl(
service: RegistrationServiceImpl()
)
var body: some View {
NavigationView {
VStack(spacing: 32) {
VStack(spacing: 16) {
InputTextFieldView(text: $viewModel.newUser.firstName,
placeholder: "First Name",
keyboardType: .namePhonePad,
systemImage: nil)
InputTextFieldView(text: $viewModel.newUser.lastName,
placeholder: "Last Name",
keyboardType: .namePhonePad,
systemImage: nil)
InputTextFieldView(text: $viewModel.newUser.occupation,
placeholder: "Occupation",
keyboardType: .namePhonePad,
systemImage: nil)
}
ButtonView(title: "Sign up") {
viewModel.create()
}
}
.padding(.horizontal, 15)
.navigationTitle("Register")
.applyClose()
.alert(isPresented: $viewModel.hasError,
content: {
if case .failed(let error) = viewModel.state {
return Alert(
title: Text("Error"),
message: Text(error.localizedDescription))
} else {
return Alert(
title: Text("Error"),
message: Text("Something went wrong"))
}
})
}
}
}
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I have a problem in my SwiftUI project, I try to use mobile authentication with firebase, when I put my number and click the button , it is throw an error as a
If app delegate swizzling is disabled, remote notifications received by UIApplicationDelegate need to be forwarded to FIRAuth's canHandleNotification: method.
I am still do not understand what I missed?
@State var no = ""
@State var show = false
@State var msg = ""
@State var alert = false
@State var ID = ""
var body : some View{
VStack{
TextField("No",text:self.$no)
NavigationLink(destination: CodeView(show: $show, ID: $ID), isActive: $show)
{
Button {
PhoneAuthProvider.provider().verifyPhoneNumber(self.no, uiDelegate: nil)
{ (ID, err) in
if err != nil{
self.msg = (err?.localizedDescription)!
self.alert.toggle()
return
}
self.ID = ID!
self.show.toggle()
}
} label: {
Text("OK")
.padding()
}
}
} .alert(isPresented: $alert) {
Alert(title: Text("Error"), message: Text(self.msg), dismissButton:
.default(Text("Ok")))
}
}
CodeView:
@State var scode = ""
@State var show = false
@State var msg = ""
@State var alert = false
@State var ID = ""
VStack {
TextField("SMS Code", text: self.$scode)
NavigationLink(destination: HomeView(), isActive:
$show) {
Button {
let credential = PhoneAuthProvider.provider().credential(withVerificationID:
self.ID, verificationCode: self.scode)
Auth.auth().signIn(with: credential) { (res, err) in
if err != nil{
self.msg = (err?.localizedDescription)!
self.alert.toggle()
return
}
UserDefaults.standard.set(true, forKey: "status")
NotificationCenter.default.post(name:
NSNotification.Name("statusChange"), object: nil)
}
} label: {
Text("Next")
.padding()
}
} .alert(isPresented: $alert) {
Alert(title: Text("Error"), message: Text(self.msg),
dismissButton: .default(Text("Ok")))
}
MyApp:
import SwiftUI
import Firebase
@main
struct App: App {
init() {
FirebaseApp.configure()
}
var body: some Scene {
WindowGroup {
ZStack{
ContentView()
}
}
}
}
I have simple chat app, and it is work for image picker, but I have custom image view and it fetch the images from internet, I want to use them instead of the image picker in my phone, but I did not find any solution, is there any idea about it?
struct Home: View {
@State var message = ""
@State var imagePicker = false
@State var imgData: Data = Data(count: 0)
@StateObject var allMessages = Messages()
var body: some View {
ZStack {
VStack {
VStack {
// Displaying Message
ScrollView(.vertical, showsIndicators: true) {
ScrollViewReader { reader in
VStack(spacing: 20) {
ForEach(allMessages.messages) { msg in
ChatBubble(msg: msg)
}
.onChange(of: allMessages.messages) {
value in
if value.last!.myMsg {
reader.scrollTo(value.last?.id)
}}}}}}}
.clipShape(RoundedRectangle(cornerRadius: 35))}
VStack {
HStack(spacing: 15) {
HStack(spacing: 15) {
TextField("Message", text: $message)
Button(action: {
// toggling image picker
imagePicker.toggle()
}) {
Image(systemName: "paperclip.circle.fill")
.font(.system(size: 22))
.foregroundColor(.gray)}
.background(Color.black.opacity(0.06))
.clipShape(Capsule())
if message != "" {
Button(action: {
withAnimation(.easeIn) {
allMessages.messages.append(Message(id: Date(), message: message, myMsg: true, profilePic: "p1", photo: nil))
}
message = ""
}) {
Image(systemName: "paperplane.fill")
.font(.system(size: 22))
.foregroundColor(Color("Color"))
// rotating the image
.rotationEffect(.init(degrees: 45))
.clipShape(Circle())}}}
.padding(.bottom)
.padding(.horizontal)
.background(Color.white)
.animation(.easeOut)
}
.fullScreenCover(isPresented: $imagePicker, onDismiss: {
if imgData.count != 0 {
allMessages.writeMessage(id: Date(), msg: "", photo: imgData, myMsg: true, profilePic: "p1")
}
}) {
ImagePicker(imagePicker: $imagePicker, imgData: $imgData)
}}}}
struct ChatBubble: View {
var msg: Message
var body: some View {
HStack(alignment: .top, spacing: 10) {
if msg.myMsg {
if msg.photo == nil {
Text(msg.message)
.padding(.all)
.background(Color.black.opacity(0.06))
.clipShape(BubbleArrow(myMsg: msg.myMsg))
} else {
Image(uiImage: UIImage(data: msg.photo!)!)
.resizable()
.frame(width: UIScreen.main.bounds.width - 150, height: 150)
.clipShape(BubbleArrow(myMsg: msg.myMsg))
}
Image(msg.profilePic)
.resizable()
.frame(width: 30, height: 30)
.clipShape(Circle())
} else {
Image(msg.profilePic)
.resizable()
.frame(width: 30, height: 30)
.clipShape(Circle())
if msg.photo == nil {
Text(msg.message)
.foregroundColor(.white)
.padding(.all)
.background(Color("Color"))
.clipShape(BubbleArrow(myMsg: msg.myMsg))
} else {
Image(uiImage: UIImage(data: msg.photo!)!)
.resizable()
.frame(width: UIScreen.main.bounds.width - 150, height: 150)
.clipShape(BubbleArrow(myMsg: msg.myMsg))}}}
.id(msg.id)}}
struct RoundedShape: Shape {
func path(in rect: CGRect) -> Path {
let path = UIBezierPath(roundedRect: rect, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 35, height: 35))
return Path(path.cgPath)
}
}
struct Message: Identifiable, Equatable {
var id: Date
var message: String
var myMsg: Bool
var profilePic: String
var photo: Data?
}
class Messages: ObservableObject {
@Published var messages: [Message] = []
init() {
let strings = ["Hii", "Hello!!", "What's up?", "What Are you doing?", "Nothing, just enjoying quarantine holidays.. you??", "Same :))", "Ohhh", "What about your country?", "Very very bad..", "Ok, be safe.", "Ok", "Bye"]
for i in 0..<strings.count {
// simple logic for two side message View
messages.append(Message(id: Date(), message: strings[i], myMsg: i % 2 == 0, profilePic: i % 2 == 0 ? "p1" : "p2"))
}
}
func writeMessage(id: Date, msg: String, photo: Data?, myMsg: Bool, profilePic: String) {
messages.append(Message(id: id, message: msg, myMsg: myMsg, profilePic: profilePic, photo: photo))
}
}
CustomImageView:
struct CustomImageView: View {
private let threeColumnGrid = [
GridItem(.flexible(minimum: 40)),
GridItem(.flexible(minimum: 40)),
GridItem(.flexible(minimum: 40)),
]
var body: some Scene {
LazyVGrid(columns: threeColumnGrid, alignment: .center) {
ForEach(model.imageNames, id: \.self) { item in
GeometryReader { gr in
Image(item)
.resizable()
.scaledToFill()
.frame(height: gr.size.width)
}
.clipped()
.aspectRatio(1, contentMode: .fit)
}
}
}
}
I have a simple app and it has simple properties, like user register to app, and it connect the webview, webview has payment also, but I am search on internet, and many people says like that apps will reject by apple, any idea?
I have side bar menu in my project, it is work correctly, but I want to use every side bar option menu, when I click any side bar menu, it may router to other Swift UI. How can I create Swift UI for every side option menu?
SideMenuViewModel:
enum SideMenuViewModel: Int, CaseIterable {
case profile
case lists
case bookmarks
case messages
var title: String {
switch self {
case .profile: return "Profile"
case .lists:
return "lists"
case .bookmarks:
return "bookmarks"
case .messages:
return "messages"
}}
var imageName: String {
switch self {
case .profile:
return "profile"
case .lists:
return "list.bullet"
case .bookmarks:
return "bookmark"
case .messages:
return "message"
}}}
SideMenuView:
struct SideMenuView: View {
@Binding var isShowing: Bool
var body: some View {
ZStack {
LinearGradient(gradient: Gradient(colors: [Color("red"),
Color("blue")]), startPoint: .top, endPoint: .bottom)
.ignoresSafeArea()
VStack {
SideMenuHeaderView(isShowing: $isShowing)
.frame(height: 240)
ForEach(SideMenuViewModel.allCases, id:\.self) { option in
NavigationLink(
destination: Text(option.title),
label: {
SideMenuOptionView(viewModel: option)
})}
Spacer()
}}.navigationBarHidden(true)
}}
I have sidebar menu, I want to integrate with my app. In app, I have tabbar, sidebar menu not work correctly with tab bar. Any idea will be appreciated?
var body: some View {
SideMenuView()
TabView(selection: $selection){
PeopleView()
.tabItem {
selection == 0 ? Image("people-selected") : Image("people")
}
.tag(0)
AnimalView()
.tabItem {
selection == 1 ? Image("animal-selected") : Image("animal")
}
.tag(1)
PlantsView()
.tabItem {
selection == 2 ? Image("plants-selected") : Image("plants")
}
.tag(2)
}
I have a SwiftUI project, since long time I try to customize my project toolbar in SwiftUI, but SwiftUI 2.0 not support it. When new version of SwiftUI will release? Any idea?
I have a simple slide menu project in SwiftUI, and I want to add bottom navigation bar in my project, but when I click the slide menu button, I want to draw bottom navigation bar as well like in image. - https://stackoverflow.com/questions/66693507/using-slide-menu-with-bottom-navigation-bar Any idea will be appreciated.
Drawer:
struct Home: View {
// Hiding tab Bar...
init() {
UITabBar.appearance().isHidden = true
}
@StateObject var menuData = MenuViewModel()
@Namespace var animation
var body: some View {
HStack(spacing: 0){
// Drawer And Main View...
// Drawer...
Drawer(animation: animation)
// Main View...
TabView(selection: $menuData.selectedMenu){
Catalogue()
.tag("Catalogue")
Orders()
.tag("Your Orders")
Cart()
.tag("Your Cart")
Favourites()
.tag("Favourites")
}
.frame(width: UIScreen.main.bounds.width)
}
// Max Frame...
.frame(width: UIScreen.main.bounds.width)
// Moving View....
// 250/2 = 125....
.offset(x: menuData.showDrawer ? 125 : -125)
.overlay(
ZStack{
if !menuData.showDrawer{
DrawerCloseButton(animation: animation)
.padding()
}
},
alignment: .topLeading
)
// Setting As Environment Object....
// For Avoiding Re-Declarations...
.environmentObject(menuData)
}
}
I have list item, and all item destination view routed to EndView, how can I add multiple destination view for every item, for example: when I click the first item it will open EndView, when I click the second item it will open NewView...., any idea will be appreciated.
Option:
struct InnerOptionValues: Codable {
var title: String
var image: String
var isAddSection: Bool
var isUseToggle: Bool
var headerTitle: String
}
extension Option {
static let listValues: [InnerOptionValues] = [
.init(title: "title1", image: "image1", isAddSection: true, isUseToggle: false, headerTitle: ""),
.init(title: "title2",image: "image2", isAddSection: false, isUseToggle: false, headerTitle: ""),
.init(title: "title3", image: "image3", isAddSection: false, isUseToggle: false, headerTitle: ""),
.init(title: "4", image: "image4", isAddSection: false, isUseToggle: false, headerTitle: ""),
.init(title: "5", image: "image5", isAddSection: false, isUseToggle: false, headerTitle: ""),
]
InnerView:
struct InnerView: View {
let value: InnerOptionValues
var body: some View {
return NavigationLink(destination: EndView(value: value)) {
HStack {
Image(value.image)
.resizable()
.frame(width: 16, height: 16)
.aspectRatio(contentMode: .fill)
Text(value.title)
.foregroundColor(.blue)
.font(.system(size: 18))
}
}
}
}
struct EndView: View {
let value: InnerOptionValues
var body: some View {
return NavigationLink(destination: EndView(value: value)) {
Text("Coming Soon!!!")
.font(.system(size: 25))
.foregroundColor(.blue)
} .navigationBarTitle(Text(value.title), displayMode: .inline)
}
}
When I pod install in terminal it say "[!] Error installing MaterialControls", Cloning into '/var/folders/w_/46rzmwwn0k73x1dtmmqk4m_r0000gn/T/d20210618-4079-1b04w72'...
remote: Repository not found.
fatal: repository 'https://github.com/fpt-software/Material-Controls-For-iOS.git/' not found. Any idea?
I have bottom navigation bar and in fist view I have list item, when I click the list item, it is open detail view, but bottom navigation bar still stay in detail view, I want to hide navigation bar when I click open the detail view. Is it possible?
ContentView:
struct TabView : View {
@State private var selection = 0
@State var index = 0
var body: some View{
VStack(spacing: 0){
ZStack{
ListView()
.opacity(self.index == 0 ? 1 : 0)
}
HStack{
Button(action: {
self.index = 0
}) {
HStack(spacing: 6){
Image("List")
.foregroundColor(self.index == 0 ? Color("blue") : .black)
if self.index == 0{
Text("List")
.foregroundColor(Color("blue"))
}
}
.padding(.vertical,10)
.padding(.horizontal)
.background(self.index == 0 ? Color("tabbar-background") : Color.clear)
.clipShape(Capsule())
}
Spacer(minLength: 0)
Button(action: {
self.index = 1
}) {
HStack(spacing: 6){
Image("SecondList")
.foregroundColor(self.index == 1 ? Color("blue") : .black)
if self.index == 1{
Text("SecondList")
.foregroundColor(Color("blue"))
}
}
.padding(.vertical,10)
.padding(.horizontal)
.background(self.index == 1 ? Color("tabbar-background"): Color.clear)
.clipShape(Capsule())
}}}
.edgesIgnoringSafeArea(.bottom)
}
}
ListView:
struct ListView: View {
var body: some View {
VStack{
ScrollView(.vertical, showsIndicators: false, content: {
VStack(spacing: 15){
RowView(docs: docs)
}
}
}
}
}
}
struct RowView: View {
@State var docs: Datas
var body: some View {
HStack(spacing: 15){
NavigationLink(destination: ListDetailView(docs: docs)) {
HStack{
Image(docs.image)
.resizable()
.frame(width: 64, height: 48)
}
}
}
.padding(.horizontal)
}
}
ListDetailView:
import SwiftUI
struct ListDetailView: View {
@State var docs: Datas
var body: some View {
ZStack{
Image(docs.image)
.resizable()
.aspectRatio(contentMode: .fit)
}
}
}
struct ListDetailView_Previews: PreviewProvider {
static var previews: some View {
ListDetailView(docs: datas[0])
}
}
I am have a problem in general in SwiftUI, when we click any items we are open new view, but bottom nav bar still not hide, why there is not any solution in SwiftUI still?
I want to use many buttons like background have custom colors with grid view in swiftUI, is it possible? I know how to use grid layout for images, but I have confused to use for custom colors.
I have project in SwiftUI 2.0 but when I update to SwiftUI 3.0 it is throw an error for
windows
as a
windows' was deprecated in iOS 15.0: Use UIWindowScene.windows on a relevant window scene instead
any idea?
.padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top)
I have simple chat app, and I want to use simple emoji in this chat app, my emoji is located in
EmojiView
an when I click the emoji button, I want to add in live chat, but I do not know how I will forward for it, I was look at many resources but I did not find any example on internet, is it possible to do it?
import SwiftUI
struct MessageDetailsView: View {
var body: some View {
HomeMessageDetails()}}
struct MessageDetailsView_Previews: PreviewProvider {
static var previews: some View {
MessageDetailsView()
}}
struct HomeMessageDetails : View {
@State var message = ""
@StateObject var allMessages = Messages()
@State private var emojiData = false
var body: some View{
ZStack {
VStack{
ScrollView(.vertical, showsIndicators: false, content: {
ScrollViewReader{reader in
VStack{
ForEach(allMessages.messages){message in
ChatBubble(message: message)
}
.onChange(of: allMessages.messages) { (value) in
if value.last!.chatMessages{
reader.scrollTo(value.last?.id)}}}
.padding([.horizontal,.bottom])}})
HStack {
HStack{
TextField("Message", text: self.$message)
Button(action: {
emojiData = true
}, label: {
Image("emoji")
}) .sheet(isPresented: $emojiData) {
EmojiView()
} }
.padding(.vertical, 10)
.padding(.horizontal)
Button(action: {
allMessages.messages.append(Message(id: Date(), message: message, chatMessages: true))
message = ""
}, label: {
Image("reply")
}) }
.padding(.horizontal)
}} }}
struct ChatBubble : View {
var message : Message
var body: some View{
HStack(alignment: .top,spacing: 10){
if message.chatMessages{
Text(message.message)
.foregroundColor(Color("black))
}
else{
Text(message.message)
.foregroundColor(.white) }}
.id(message.id)}}
struct Message : Identifiable,Equatable{
var id : Date
var message : String
var chatMessages : Bool
}
class Messages : ObservableObject{
@Published var messages : [Message] = []
init() {
let strings = ["Hii","Hello !!!!"]
for i in 0..<strings.count{
messages.append(Message(id: Date(), message: strings[i], chatMessages: i % 2 == 0 ? true : false))}}
func writeMessage(id: Date,message: String,chatMessages: Bool){
messages.append(Message(id: id, message: message, chatMessages: chatMessages))}}
struct EmojiView: View {
var body: some View {
Button(action: {
}, label: {
Image("smile_emoji")
}) }}