diff --git a/MOB304/code/Complete/Landmarks/Landmarks/AppDelegate.swift b/MOB304/code/Complete/Landmarks/Landmarks/AppDelegate.swift index dcd1fd7..eaba213 100644 --- a/MOB304/code/Complete/Landmarks/Landmarks/AppDelegate.swift +++ b/MOB304/code/Complete/Landmarks/Landmarks/AppDelegate.swift @@ -119,6 +119,19 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } + public func signIn(username: String, password: String) { + _ = Amplify.Auth.signIn(username: username, password: password) { result in + switch result { + case .success(_): + print("Sign in succeeded") + // nothing else required, the event HUB will trigger the UI refresh + case .failure(let error): + print("Sign in failed \(error)") + // in real life present a message to the user + } + } + } + // signin with Cognito web user interface public func authenticateWithHostedUI() { diff --git a/MOB304/code/Complete/Landmarks/Landmarks/CustomLoginView.swift b/MOB304/code/Complete/Landmarks/Landmarks/CustomLoginView.swift new file mode 100644 index 0000000..311d0ce --- /dev/null +++ b/MOB304/code/Complete/Landmarks/Landmarks/CustomLoginView.swift @@ -0,0 +1,104 @@ +import SwiftUI +import Combine + +// +// this is a custom view to capture username and password +// +struct CustomLoginView : View { + + @State private var username: String = "" + @State private var password: String = "" + + private let app = UIApplication.shared.delegate as! AppDelegate + + var body: some View { // The body of the screen view + VStack { + Image("turtlerock") + .resizable() + .aspectRatio(contentMode: ContentMode.fit) + .padding(Edge.Set.bottom, 20) + + Text(verbatim: "Login").bold().font(.title) + + Text(verbatim: "Explore Landmarks of the world") + .font(.subheadline) + .padding(EdgeInsets(top: 0, leading: 0, bottom: 70, trailing: 0)) + + TextField("Username", text: $username) + .autocapitalization(.none) //avoid autocapitalization of the first letter + .padding() + .cornerRadius(4.0) + .background(Color(UIColor.systemFill)) + .padding(EdgeInsets(top: 0, leading: 0, bottom: 15, trailing: 0)) + + SecureField("Password", text: $password) + .padding() + .cornerRadius(4.0) + .background(Color(UIColor.systemFill)) + .padding(.bottom, 10) + + Button(action: { self.app.signIn(username: self.username, password: self.password) }) { + HStack() { + Spacer() + Text("Signin") + .foregroundColor(Color.white) + .bold() + Spacer() + } + + }.padding().background(Color.green).cornerRadius(4.0) + }.padding() + .keyboardAdaptive() // Apply the scroll on keyboard height + } +} + + +// The code below +// scrolls the view when the keyboard appears +// thanks to https://www.vadimbulavin.com/how-to-move-swiftui-view-when-keyboard-covers-text-field/ +struct KeyboardAdaptive: ViewModifier { + @State private var keyboardHeight: CGFloat = 0 + + func body(content: Content) -> some View { + content + .padding(.bottom, keyboardHeight) + .onReceive(Publishers.keyboardHeight) { self.keyboardHeight = $0 } + .animation(.easeOut(duration: 0.5)) + } +} + +extension View { + func keyboardAdaptive() -> some View { + ModifiedContent(content: self, modifier: KeyboardAdaptive()) + } +} + +extension Publishers { + // 1. + static var keyboardHeight: AnyPublisher { + // 2. + let willShow = NotificationCenter.default.publisher(for: UIApplication.keyboardWillShowNotification) + .map { $0.keyboardHeight } + + let willHide = NotificationCenter.default.publisher(for: UIApplication.keyboardWillHideNotification) + .map { _ in CGFloat(0) } + + // 3. + return MergeMany(willShow, willHide) + .eraseToAnyPublisher() + } +} + +extension Notification { + var keyboardHeight: CGFloat { + return (userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)?.height ?? 0 + } +} + +#if DEBUG +struct ContentView_Previews : PreviewProvider { +static var previews: some View { + CustomLoginView() // Renders your UI View on the Xcode preview + } +} +#endif diff --git a/MOB304/code/Complete/Landmarks/Landmarks/LandingView.swift b/MOB304/code/Complete/Landmarks/Landmarks/LandingView.swift index 0306978..977f8c5 100644 --- a/MOB304/code/Complete/Landmarks/Landmarks/LandingView.swift +++ b/MOB304/code/Complete/Landmarks/Landmarks/LandingView.swift @@ -15,13 +15,14 @@ struct LandingView: View { // .wrappedValue is used to extract the Bool from Binding type if (!$user.isSignedIn.wrappedValue) { - Button(action: { - let app = UIApplication.shared.delegate as! AppDelegate - app.authenticateWithHostedUI() - }) { - UserBadge().scaleEffect(0.5) - } - +// Button(action: { +// let app = UIApplication.shared.delegate as! AppDelegate +// app.authenticateWithHostedUI() +// }) { +// UserBadge().scaleEffect(0.5) +// } + CustomLoginView() + } else { LandmarkList().environmentObject(user) }