SwiftUI Login View

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Moin Moin,

    sag mal, was hat dir das kleine TextEdit denn getan? UI und Logik gehören getrennt. In deinen Fall sähe das ungefär so aus...

    Quellcode

    1. struct VMain: View {
    2. @StateObject private var loginController = LoginController()
    3. var body: some View {
    4. if loginController.loggedIn {
    5. VWelcome()
    6. } else {
    7. VPassword(controller: loginController)
    8. }
    9. }
    10. }
    11. struct VPassword: View {
    12. @ObservedObject var controller: LoginController
    13. var body: some View {
    14. TextEdit("Begrüssung", $controller.password) {
    15. controller.prüfen() //kann sein, muss aber nicht
    16. }
    17. }
    18. }
    19. struct VWelcome: View {
    20. var body: some View {
    21. }
    22. }
    23. class LoginController: ObservableObject {
    24. @Published private(set) var loggedIn: Bool = false
    25. @Published public var password: String = "" {
    26. didSet {
    27. //auch hier kann man wunderbar prüfen
    28. }
    29. }
    30. public func prüfen() {
    31. //Prüfe Password nach allen regeln der Kunst und setze loggedIn
    32. }
    33. }
    Alles anzeigen
  • Wow, cool. Ist aber anscheinend doch nicht so gaaaanz trivial. Ich habe mir deinen ( @Wolf ) Code mal kopiert und in meine App implementiert. Funktioniert soweit nahezu alles gut, nur nach dem einloggen landet man nicht in der ListenView (2. Tab) sonder in der ScannerView (1. Tab) und muss dann rüber wechseln auf den 2. Tab. Das verstehe ich noch nicht.

    Hoffentlich liegt das nicht an dem Scanner, ich verwende diesen hier: github.com/twostraws/CodeScanner
  • Die VMain, ist deine HauptView. Da kommt dann deine App rein. Wo du Landest kannst mit einen Tag steuern. Wenn du das Login sistieren. möchtest, brauchst nur .disabled() an die VPasswort() anhängen. über ein neues Property im LoginController kannst du das fein steuern.

    Alternativ, kannst ach dene App in die VWelcome verpacken, ist noch schöner, da dann der gesamte Login balast nicht ht mehr sichtbar ist.
  • Quellcode

    1. import SwiftUI
    2. struct PersonsView: View {
    3. @StateObject private var loginController = LoginController()
    4. var body: some View {
    5. if loginController.loggedIn {
    6. ListView(controller: loginController)
    7. } else {
    8. PasswordView(controller: loginController)
    9. } }
    10. }
    11. struct ListView: View {
    12. @ObservedObject var controller: LoginController
    13. @Environment(\.managedObjectContext) private var viewContext
    14. @FetchRequest(entity: Person.entity(), sortDescriptors: [
    15. NSSortDescriptor(keyPath: \Person.checkInDate, ascending: false),
    16. ])
    17. var persons: FetchedResults<Person>
    18. var body: some View {
    19. List {
    20. ForEach(persons) { pers in
    21. HStack {
    22. VStack (alignment: .leading) {
    23. HStack() {
    24. Image(systemName: "square.and.arrow.down")
    25. Text(pers.checkInDate ?? Date(), formatter: dateFormatter)
    26. }
    27. Divider()
    28. HStack {
    29. Image(systemName: "square.and.arrow.up")
    30. if pers.checkOutDate == nil {
    31. Text("")
    32. } else {
    33. Text(pers.checkOutDate ?? Date(timeIntervalSince1970: 0), formatter: dateFormatter)
    34. }
    35. }
    36. }
    37. .frame(width:190)
    38. Text("\(pers.familyName ?? ""), \(pers.givenName ?? "")")
    39. }
    40. }
    41. .onDelete(perform: deleteItems)
    42. .onDisappear(perform:{
    43. })
    44. }
    45. .onDisappear {
    46. controller.password = ""
    47. }
    48. }
    49. private func deleteItems(offsets: IndexSet) {
    50. withAnimation {
    51. offsets.map { persons[$0] }.forEach(viewContext.delete)
    52. do {
    53. try viewContext.save()
    54. } catch {
    55. // Replace this implementation with code to handle the error appropriately.
    56. // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
    57. let nsError = error as NSError
    58. fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
    59. }
    60. }
    61. }
    62. private let dateFormatter: DateFormatter = {
    63. let formatter = DateFormatter()
    64. formatter.timeZone = TimeZone.current
    65. formatter.dateFormat = "dd.MM.YYYY hh:mm:ss"
    66. formatter.locale = Locale(identifier: "de_DE")
    67. // formatter.dateStyle = .short
    68. // formatter.timeStyle = .medium
    69. return formatter
    70. }()
    71. }
    72. struct PasswordView: View {
    73. @ObservedObject var controller: LoginController
    74. var body: some View {
    75. SecureField("Sprich Freund und tritt ein", text: $controller.password)
    76. .padding(EdgeInsets(top: 20, leading: 15.0, bottom: 20, trailing: 5))
    77. .background(lightGreyColor)
    78. .cornerRadius(5.0)
    79. }
    80. }
    81. struct PersonsView_Previews: PreviewProvider {
    82. static var previews: some View {
    83. PersonsView()
    84. }
    85. }
    86. struct passwordView_Previews: PreviewProvider {
    87. static var previews: some View {
    88. PasswordView(controller: LoginController())
    89. }
    90. }
    91. class LoginController: ObservableObject {
    92. @Published private(set) var loggedIn: Bool = false
    93. @Published public var password: String = "" {
    94. didSet {
    95. if password == "mellon" {
    96. loggedIn = true
    97. } else {
    98. loggedIn = false
    99. }
    100. }
    101. }
    102. public func prüfen() {
    103. if password == "mellon" {
    104. loggedIn = true
    105. }
    106. }
    107. }
    Alles anzeigen
    Nun, ich denke das haben ich
  • Langsam wird ein Schuh draus…

    Nur weshalb übergibst in die ListView() den loginController? brauchst doch da nicht mehr, oder sollte ich mich täuschen?

    So, nach deinen ursprünglichen Coding, fehlt dir noch eine Funktion. Die Zeitverzögerung bei fehleingaben des Passworts?

    Weisst wie es geht?

    Im didSet würde ich das Passwort nicht prüfen, da der User nicht wissen muss wie lang es sein soll. Daher am besten nur im onCommit{}
  • Ich glaube ich wollte das Passwort um ListView zurücksetzen so das man sich jedes Mal einloggen muss.

    Das Problem ist ja weiterhin, das nach dem Login nicht diese ListView angezeigt wird sondern die Tabview erstmal auf den Scanner zurück springt und ich dann das Tabitem "List" auswählen muss, damit ich die ListView sehen kann.

    Wie soll man denn herausfinden wie lange das Passwort ist, nur weil es im didSet geprüft wird? Man kann ja auch im onCommit sehen wie lange das Passwort ist, wenn man das richtige Passwort dort eintippt und ein dritter Beobachter die Punkte zählt....

    das deaktivieren des SecureField würde ich mit einem @State machen das das SecureField disabled und einen Timer der es wieder einschaltet.
  • Mmhhhh,

    hattest da nichts mit fehlerhaften Versuchen drin?

    Ne State Variable brauchst Du nicht, liess mal ein paar Beiträge früher, da ist alles beschrieben

    Da musst einfach auf den richtigen Tab verzweigen, das hat mit dem Thema nix zu tun. Da gibts genügend threats wo es beschrieben ist, wie man einen Tab anspringt.

    Im Prinzip, reicht dir onCommit. das andere ist das filtern des Strings

    By the way, hast auch an das Ausloggen gedacht…