註冊與登入需要的元素差不多,因此簡單帶過註冊的程式碼。
前一天在輸入欄位的部分,使用了textField
。
而其中有個重要的觀念: 委任模式 Delegate。委任模式的意思是,在設計元件或功能時,會定義數個不等的方法(method),但只會定義出這些方法的名稱,而這些方法要做什麼事,則是要交由委任(delegate)的對象來實作。
透過設置delegate,可以指定委託對象。在這邊我們將對象指定為自己。不過我也不知道,什麼時候、什麼情境下可能為其他物件,QQ
除了設定delegate外,也要注意該物件有被加上相對應的protocal。在這邊是UITextFieldDelegate
。
loginButton.addTarget(self,
action: #selector(loginButtonTapped),
for: .touchUpInside)
emailField.delegate = self
passwordField.delegate = self
上面我們在viewDidLoad
方法中加上按下按鈕後觸發的方法、以及剛剛提到的委派對象。
方法loginButtonTapped
中,我們將textField清除指標,然後確認欄位都已輸入資料,接著進行登入的部分。後端的串接,因為使用firebase auth,因此邏輯都包含在firebase的服務,這邊就先不多描述。
// validate text fields
@objc private func loginButtonTapped(){
// dismiss the keyboard
emailField.resignFirstResponder()
passwordField.resignFirstResponder()
guard let email = emailField.text, let password = passwordField.text,
!email.isEmpty, !password.isEmpty //, password.count >= 6
else {
alertUserLoginError()
return
}
//firebase login
}
func alertUserLoginError(){
let alert = UIAlertController(title: "Oops",
message: "Please enter valid information",
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Dismiss",
style: .cancel,
handler: nil))
present(alert, animated: true)
}
當然,也有例外的處理。
最後,別忘了加上剛剛提到的UITextFieldDelegate
。
在此需要寫上方法textFieldShouldReturn
。
extension LoginViewController: UITextFieldDelegate{
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField == emailField {
passwordField.becomeFirstResponder()
}
else if textField == passwordField {
loginButtonTapped()
}
// true if the text field should implement its default behavior for the return button
return true
}
}
接下來,註冊的流程其實大同小異、只是多了一些欄位。因此不多加描述,直接貼上完整的程式碼。
import UIKit
class RegisterViewController: UIViewController {
private let scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.clipsToBounds = true
return scrollView
}()
private let imageView: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(systemName: "person")
imageView.tintColor = .lightGray
imageView.contentMode = .scaleAspectFit
return imageView
}()
private let firstNameField: UITextField = {
let field = UITextField()
field.autocorrectionType = .no
field.autocapitalizationType = .none
field.returnKeyType = .continue
field.layer.cornerRadius = 12
field.layer.borderWidth = 1
field.layer.borderColor = UIColor.lightGray.cgColor
field.placeholder = "First Name"
field.leftView = UIView(frame: CGRect(x: 0, y:0, width: 5, height: 0)) // padding
field.leftViewMode = .always
field.backgroundColor = .white
return field
}()
private let lastNameField: UITextField = {
let field = UITextField()
field.autocorrectionType = .no
field.autocapitalizationType = .none
field.returnKeyType = .continue
field.layer.cornerRadius = 12
field.layer.borderWidth = 1
field.layer.borderColor = UIColor.lightGray.cgColor
field.placeholder = "Last Name"
field.leftView = UIView(frame: CGRect(x: 0, y:0, width: 5, height: 0)) // padding
field.leftViewMode = .always
field.backgroundColor = .white
return field
}()
private let emailField: UITextField = {
let field = UITextField()
field.autocorrectionType = .no
field.autocapitalizationType = .none
field.returnKeyType = .continue
field.layer.cornerRadius = 12
field.layer.borderWidth = 1
field.layer.borderColor = UIColor.lightGray.cgColor
field.placeholder = "Email Address"
field.leftView = UIView(frame: CGRect(x: 0, y:0, width: 5, height: 0)) // padding
field.leftViewMode = .always
field.backgroundColor = .white
return field
}()
private let passwordField: UITextField = {
let field = UITextField()
field.autocorrectionType = .no
field.autocapitalizationType = .none
field.returnKeyType = .done // enter: automatically login
field.layer.cornerRadius = 12
field.layer.borderWidth = 1
field.layer.borderColor = UIColor.lightGray.cgColor
field.placeholder = "Password"
field.leftView = UIView(frame: CGRect(x: 0, y:0, width: 5, height: 0)) // padding
field.leftViewMode = .always
field.backgroundColor = .white
field.isSecureTextEntry = true
return field
}()
private let registerButton: UIButton = {
let button = UIButton()
button.setTitle("Sign Up", for: .normal)
button.backgroundColor = .systemGreen
button.setTitleColor(.white, for: .normal)
button.layer.cornerRadius = 12
button.layer.masksToBounds = true
button.titleLabel?.font = .systemFont(ofSize: 20, weight: .bold)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
title = "Sign Up"
view.backgroundColor = .white
registerButton.addTarget(self,
action: #selector(registerButtonTapped),
for: .touchUpInside)
emailField.delegate = self
passwordField.delegate = self
view.addSubview(scrollView)
scrollView.addSubview(imageView)
scrollView.addSubview(firstNameField)
scrollView.addSubview(lastNameField)
scrollView.addSubview(emailField)
scrollView.addSubview(passwordField)
scrollView.addSubview(registerButton)
imageView.isUserInteractionEnabled = true
//scrollView.isUserInteractionEnabled = true
let gesture = UITapGestureRecognizer(target: self, action: #selector(didTapChangeProfilePic))
imageView.addGestureRecognizer(gesture)
}
@objc private func didTapChangeProfilePic(){
print("Change pic called")
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.frame = view.bounds
let size = scrollView.width/3
imageView.frame = CGRect(x: (scrollView.width-size)/2,
y: 20,
width: size,
height: size)
firstNameField.frame = CGRect(x: 30,
y: imageView.bottom+10,
width: scrollView.width-60,
height: 50)
lastNameField.frame = CGRect(x: 30,
y: firstNameField.bottom+10,
width: scrollView.width-60,
height: 50)
emailField.frame = CGRect(x: 30,
y: lastNameField.bottom+10,
width: scrollView.width-60,
height: 50)
passwordField.frame = CGRect(x: 30,
y: emailField.bottom+10,
width: scrollView.width-60,
height: 50)
registerButton.frame = CGRect(x: 30,
y: passwordField.bottom+10,
width: scrollView.width-60,
height: 50)
}
// validate text fields
@objc private func registerButtonTapped(){
emailField.resignFirstResponder()
passwordField.resignFirstResponder()
firstNameField.resignFirstResponder()
lastNameField.resignFirstResponder()
guard let firstname = firstNameField.text, let lastname = lastNameField.text,
let email = emailField.text, let password = passwordField.text,
!email.isEmpty, !password.isEmpty, //, password.count >= 6
!firstname.isEmpty, !lastname.isEmpty
else {
alertUserLoginError()
return
}
//firebase register
}
func alertUserLoginError(){
let alert = UIAlertController(title: "Oops",
message: "Please enter valid information",
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Dismiss",
style: .cancel,
handler: nil))
present(alert, animated: true)
}
}
extension RegisterViewController: UITextFieldDelegate{
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField == emailField {
passwordField.becomeFirstResponder()
}
else if textField == passwordField {
registerButtonTapped()
}
// true if the text field should implement its default behavior for the return button
return true
}
}
今天寫了很多程式,可喜可賀。
接下來終於要進到firebase的連線與服務了,好期待呀!
若上述內容有誤或可以改進的部分,歡迎留言以及提出任何指教~
謝謝 o(〃^▽^〃)o