CredentialsController.swift 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. //
  2. // CredentialsController.swift
  3. // deltachat-ios
  4. //
  5. // Created by Jonas Reinsch on 15.11.17.
  6. // Copyright © 2017 Jonas Reinsch. All rights reserved.
  7. //
  8. import UIKit
  9. class TextFieldCell:UITableViewCell {
  10. let textField = UITextField()
  11. init(description: String, placeholder: String) {
  12. super.init(style: .value1, reuseIdentifier: nil)
  13. textLabel?.text = "\(description):"
  14. contentView.addSubview(textField)
  15. textField.translatesAutoresizingMaskIntoConstraints = false
  16. // see: https://stackoverflow.com/a/35903650
  17. // this makes the textField respect the trailing margin of
  18. // the table view cell
  19. let margins = contentView.layoutMarginsGuide
  20. let trailing = margins.trailingAnchor
  21. textField.trailingAnchor.constraint(equalTo: trailing).isActive = true
  22. textField.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
  23. textField.textAlignment = .right
  24. textField.placeholder = placeholder
  25. selectionStyle = .none
  26. textField.enablesReturnKeyAutomatically = true
  27. }
  28. override func setSelected(_ selected: Bool, animated: Bool) {
  29. if selected {
  30. textField.becomeFirstResponder()
  31. }
  32. }
  33. required init?(coder aDecoder: NSCoder) {
  34. fatalError("init(coder:) has not been implemented")
  35. }
  36. static func makeEmailCell() -> TextFieldCell {
  37. let emailCell = TextFieldCell(description: "Email", placeholder: "you@example.com")
  38. emailCell.textField.keyboardType = .emailAddress
  39. // switch off quicktype
  40. emailCell.textField.autocorrectionType = .no
  41. emailCell.textField.autocapitalizationType = .none
  42. return emailCell
  43. }
  44. static func makePasswordCell() -> TextFieldCell {
  45. let passwordCell = TextFieldCell(description: "Password", placeholder: "your IMAP password")
  46. passwordCell.textField.textContentType = UITextContentType.password
  47. passwordCell.textField.isSecureTextEntry = true
  48. return passwordCell
  49. }
  50. static func makeNameCell() -> TextFieldCell {
  51. let nameCell = TextFieldCell(description: "Name", placeholder: "new contacts nickname")
  52. nameCell.textField.autocapitalizationType = .words
  53. nameCell.textField.autocorrectionType = .no
  54. // .namePhonePad doesn't support autocapitalization
  55. // see: https://stackoverflow.com/a/36365399
  56. // therefore we use .default to capitalize the first character of the name
  57. nameCell.textField.keyboardType = .default
  58. return nameCell
  59. }
  60. }
  61. class CredentialsController: UITableViewController {
  62. let emailCell = TextFieldCell.makeEmailCell()
  63. let passwordCell = TextFieldCell.makePasswordCell()
  64. var doneButton:UIBarButtonItem?
  65. let progressBar = UIProgressView(progressViewStyle: .default)
  66. func readyForLogin() -> Bool {
  67. return Utils.isValid(model.email) && !model.password.isEmpty
  68. }
  69. var model:(email:String, password:String) = ("", "") {
  70. didSet {
  71. if readyForLogin() {
  72. doneButton?.isEnabled = true
  73. } else {
  74. doneButton?.isEnabled = false
  75. }
  76. }
  77. }
  78. let cells:[UITableViewCell]
  79. init() {
  80. cells = [emailCell, passwordCell]
  81. super.init(style: .grouped)
  82. doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(CredentialsController.saveAccountButtonPressed))
  83. doneButton?.isEnabled = false
  84. navigationItem.rightBarButtonItem = doneButton
  85. emailCell.textField.addTarget(self, action: #selector(CredentialsController.emailTextChanged), for: UIControlEvents.editingChanged)
  86. passwordCell.textField.addTarget(self, action: #selector(CredentialsController.passwordTextChanged), for: UIControlEvents.editingChanged)
  87. emailCell.textField.textContentType = UITextContentType.emailAddress
  88. emailCell.textField.delegate = self
  89. passwordCell.textField.delegate = self
  90. emailCell.textField.returnKeyType = .next
  91. passwordCell.textField.returnKeyType = .done
  92. }
  93. override func viewDidAppear(_ animated: Bool) {
  94. emailCell.textField.becomeFirstResponder()
  95. }
  96. @objc func emailTextChanged() {
  97. let emailText = emailCell.textField.text ?? ""
  98. model.email = emailText
  99. }
  100. @objc func passwordTextChanged() {
  101. let passwordText = passwordCell.textField.text ?? ""
  102. model.password = passwordText
  103. }
  104. @objc func saveAccountButtonPressed() {
  105. dismiss(animated: true) {
  106. initCore(withCredentials: true, email: self.model.email, password: self.model.password)
  107. }
  108. }
  109. required init?(coder aDecoder: NSCoder) {
  110. fatalError("init(coder:) has not been implemented")
  111. }
  112. override func viewDidLoad() {
  113. super.viewDidLoad()
  114. title = "Account"
  115. navigationController?.navigationBar.prefersLargeTitles = true
  116. }
  117. override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  118. return cells.count
  119. }
  120. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  121. let row = indexPath.row
  122. return cells[row]
  123. }
  124. override func didReceiveMemoryWarning() {
  125. super.didReceiveMemoryWarning()
  126. // Dispose of any resources that can be recreated.
  127. }
  128. }
  129. extension CredentialsController: UITextFieldDelegate {
  130. func textFieldShouldReturn(_ textField: UITextField) -> Bool {
  131. if textField == emailCell.textField {
  132. if let emailText = emailCell.textField.text {
  133. // only jump to next field if valid email
  134. if Utils.isValid(emailText) {
  135. passwordCell.textField.becomeFirstResponder()
  136. }
  137. }
  138. }
  139. if textField == passwordCell.textField {
  140. if readyForLogin() {
  141. self.saveAccountButtonPressed()
  142. }
  143. }
  144. return true
  145. }
  146. }