Demo project: link
在學習了 22 天了之後, 是時候實作了, 這次我們要做使用者登入的機制, 功能如下:
class ViewController: UIViewController {
// 1
@IBOutlet weak var accountTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var autoLoginSwitch: UISwitch!
@IBOutlet weak var loginButton: UIButton!
// 2
var set = Set<AnyCancellable>()
// 3
let setting = Setting()
override func viewDidLoad() {
super.viewDidLoad()
// 4
let accountPublisher = accountTextField
.publisher(for: .editingChanged)
.map(\.text)
.prepend(setting.keepAccount)
.replaceNil(with: "")
let passwordPublisher = passwordTextField
.publisher(for: .editingChanged)
.map(\.text)
.replaceNil(with: "")
// 5
Publishers.CombineLatest(accountPublisher, passwordPublisher)
.map{$0.0.count > 2 && $0.1.count > 2}
.assign(to: \UIButton.isEnabled, on: loginButton)
.store(in: &set)
// 6
setting.oneTimePublisher
.map{!$0.isEmpty}
.assign(to: \.isOn, on: autoLoginSwitch)
// 7
setting.oneTimePublisher
.map{$0 as String?}
.assign(to: \.text, on: accountTextField)
// 8
autoLoginSwitch
.publisher(for: .valueChanged)
.map(\.isOn)
.prepend(autoLoginSwitch.isOn)
.combineLatest(accountPublisher.debounce(for: .seconds(0.5), scheduler: RunLoop.main))
.map{ $0.0 ? $0.1 : ""}
.receive(on: RunLoop.main)
.assign(to: \Setting.keepAccount, on: setting).store(in: &set)
}
}
@IBOutlet
的方式取得.switch.isOn = !setting.account.isEmpty
textField.text = setting.account
prepend
, 讓使用者可以不用觸發 switch 就能夠更新 Modal