I want to use onboarding screen in my project, and it is work but I want to use it just once time for app, I do not know how I will do it, is there any way?
struct ContentView: View {
@State private var onboardinDone = false
var data = OnboardingData.data
var body: some View {
Group {
if !onboardinDone {
OnboardingView(data: data, doneFunction: {
print("done onboarding")
})
} else {
MainScreen()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Post
Replies
Boosts
Views
Activity
When I update my macbook to macOS13 Venture , I have a problem in top right corner, always give alots of notifications , how can I solve it?
I have list items in SwiftUI, and when I delete list items I want to delete after alert menu, like
"do want to delete your list items, ""yes" or "no"
is it possible?
struct MyView: View {
@State private var selectedUsers: MyModel?
var body: some View {
ScrollView(.vertical, showsIndicators: false, content: {
VStack(content: {
ForEach(datas){ data in
MyRowView(data: data)
.contextMenu {
Button(action: {
self.delete(item: data)
}) {
Text("delete")
}
}
.onTapGesture {
selectedUsers = data
}
} .onDelete { (indexSet) in
self.datas.remove(atOffsets: indexSet)
}})
})}
private func delete(item data: MyModel) {
if let index = datas.firstIndex(where: { $0.id == data.id }) {
datas.remove(at: index)
}
}}
I am trying to use confirmationDialog to delete an item in a List.
But what happens is that the wrong item gets deleted. Why?
Here is my code:
struct MyView: View {
@State private var selectedUsers: MyModel?
@State var datas: [MyModel]
@State private var confirmDelete = false
var body: some View {
ScrollView(.vertical, showsIndicators: false, content:
{
VStack(content: {
ForEach(datas){ data in
MyRowView(data: data)
.contextMenu {
Button(action: {
self.delete(item: data)
}) {
Text("delete")
}
}
.onTapGesture {
selectedUsers = data
}
.alert(isPresented: $confirmDelete) {
Alert(title: Text("title"),
message: Text("message"),
primaryButton: .destructive(Text("Delete")) {
self.delete(item: data)
},
secondaryButton: .cancel())
}
} .onDelete { (indexSet) in
self.datas.remove(atOffsets: indexSet)
}})
})}
private func delete(item data: MyModel) {
if let index = datas.firstIndex(where: { $0.id == data.id }) {
datas.remove(at: index)
}
}}
I am using bottom sheet for my app, and it is work correctly, but I want to use the half bottom sheet, is it possible?
Image( "color")
.resizable()
.frame(width:45, height: 45)
.sheet(isPresented: $showSheet, content: {
ScreenView()
})
I have a small app and I am using WKWebView for my app, so in WebView I have sign in, when I sign to WebView I have to import image, documents etc to WebView, so I have to use permission in my app, is it possible to apply WKWebView in below code?
import SwiftUI
import WebKit
struct ContentView: View {
var body: some View {
ZStack{
WebView()
}
}
}
struct WebView: UIViewRepresentable {
func makeUIView(context: Context) -> WKWebView {
WKWebView(frame: .zero)
}
func updateUIView(_ view: WKWebView, context: UIViewRepresentableContext<WebView>) {
let request = URLRequest(url: URL(string: "https://codepen.io/login")!)
view.load(request)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.navigationBarHidden(true)
}
}
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 a register view and when I complete my register, I want to pass register data in form from WebView, is there any way to do it?
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 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 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"))
}
})
}
}
}
I have small problem in my project, it throw an error as a
Extra arguments at positions #3, #4
for
Auth.auth().signIn()
line, I do not know what I missed?
func login(email: String, password: String, name: String, surname: String) -> Future<User?, Never> {
return Future<User?, Never> { promise in
Auth.auth().signIn(withEmail: email, password: password, name: name, surname: surname) {(authResult, _) in
guard let id = authResult?.user.providerID,
let email = authResult?.user.email else {
promise(.success(nil))
return
}
let user = User(id: id, email: email, name:name, surname:surname)
promise(.success(user))
}
}
}
model:
import Foundation
struct User {
let id: String
let email: String
let name: String
let surname: String
}
I have register screen and I am not able to register info to firebase, I put user info on simulator, but it just hold on on screen, and no any change on firebase, any idea? where I missed?
import SwiftUI
import Firebase
struct Register: View {
@State var name = ""
@State var about = ""
@Binding var show : Bool
var body: some View {
VStack(alignment: .center, spacing: 3){
TextField("Name",text:self.$name)
.padding()
TextField(" about", text: self.$about)
.padding()
if self.loading{
HStack{
Spacer()
Indicator()
Spacer()
}
}
else{
Button {
if self.name != "" && self.about != "" {
self.loading.toggle()
CreateUser(name: self.name, about: self.about) { (status) in
if status{
self.show.toggle()
}
}
}
else{
self.alert.toggle()
}
} label: {
Text("Next")
.padding()
}
}
}
import Foundation
import Firebase
func CreateUser(name: String,about : String, completion : @escaping (Bool)-> Void){
let db = Firestore.firestore()
let storage = Storage.storage().reference()
let uid = Auth.auth().currentUser?.uid
db.collection("users").document(uid!).setData(["name":name,"about":about, "uid":uid!]) { (err) in
if err != nil{
print((err?.localizedDescription)!)
return
}
completion(true)
UserDefaults.standard.set(true, forKey: "status")
UserDefaults.standard.set(name, forKey: "UserName")
NotificationCenter.default.post(name: NSNotification.Name("statusChange"), object: nil)
}
}
I have simple app in SwiftUI, when I use @Binding var show : Bool for second register screen,
it is throw an error for this line of code
init(state: AppState) {
self.viewModel = RegisterViewModel(authAPI: AuthService(), state: state)
}
as a "Return from initializer without initializing all stored properties" any idea?
first screen:
import SwiftUI
struct RegisterFirstScreen: View {
@Binding var show : Bool
init(state: AppState) {
self.viewModel = RegisterViewModel(authAPI: AuthService(), state: state)
}
var body: some View {
NavigationLink(destination: RegisterSecondScreen(state: viewModel.state, show: $show),
isActive: self.$pushActive) {
Button {
viewModel.signUp()
} label: {
Text("Register Now")
.padding()
}
}
}
second screen:
struct RegisterSecondScreen: View {
@ObservedObject var state: AppState
@Binding var show : Bool
var body: some View {
Text("Next main screen")
}}
I have multiple register screen in swiftUI, I did not understand how I will connect first register screen to second register screen, normally first register screen connect to main screen, but I want to connect first register screen to second register screen, and connect second register screen to main screen, how can I do it, any idea?
StatusViewModel:
class StatusViewModel: Identifiable, ObservableObject {
var title: String
var message: String
init(title: String = "", message: String = "") {
self.title = title
self.message = message
}
static var signUpSuccessStatus: StatusViewModel {
return StatusViewModel(title: "Successful", message: "Your account has been created successfully")
}
static var logInSuccessStatus: StatusViewModel {
return StatusViewModel(title: "Successful", message: "Your account has been logged in successfully")
}
static var errorStatus: StatusViewModel {
return StatusViewModel(title: "Error", message: "Oops! Something went wrong. Please try again.")
}
}
RegisterViewModel:
import Foundation
import Combine
class RegisterViewModel: ObservableObject {
@Published var email: String = ""
@Published var password: String = ""
@Published var statusViewModel: StatusViewModel?
@Published var state: AppState
private var cancellableBag = Set<AnyCancellable>()
private let authAPI: AuthAPI
init(authAPI: AuthAPI, state: AppState) {
self.authAPI = authAPI
self.state = state
}
func signUp() {
authAPI.signUp(email: email, password: password)
.receive(on: RunLoop.main)
.map(resultMapper)
.replaceError(with: StatusViewModel.errorStatus)
.assign(to: \.statusViewModel, on: self)
.store(in: &cancellableBag)
}
}
extension RegisterViewModel {
private func resultMapper(with user: User?) -> StatusViewModel {
if user != nil {
state.currentUser = user
return StatusViewModel.signUpSuccessStatus
} else {
return StatusViewModel.errorStatus
}
}
}
first register screen:
struct Register: View {
@ObservedObject private var viewModel: RegisterViewModel
@State var pushActive = false
init(state: AppState) {
self.viewModel = RegisterViewModel(authAPI: AuthService(), state: state)
}
var body: some View {
VStack(){
TextField("Email Address",text:$viewModel.email)
.autocapitalization(.none)
.padding()
HStack(spacing: 15){
TextField("Password", text: $viewModel.password)
.autocapitalization(.none)
}
NavigationLink(destination: HomeView(state: viewModel.state),
isActive: self.$pushActive) {
Button {
self.viewModel.signUp()
} label: {
Text("Register")
.padding()
}
}
}
}
second register screen:
struct SecondRegister: View {
var body: some View {
GeometryReader { geometry in
ZStack{
VStack(alignment: .center, spacing: 3){
TextField("First Name",text:self.$first_name)
.autocapitalization(.none)
.padding()
TextField("Last Name", text: self.$last_name)
.autocapitalization(.none)
.padding()
}
Button {
} label: {
Text("Next")
.padding()
}
}
}.padding()
}.padding(.top,60)
}
}