TRTCLoginRootView.swift 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. //
  2. // TRTCLoginRootView.swift
  3. // TXLiteAVDemo
  4. //
  5. // Created by gg on 2021/4/7.
  6. // Copyright © 2021 Tencent. All rights reserved.
  7. //
  8. import UIKit
  9. class TRTCLoginRootView: UIView {
  10. lazy var contentView: UIView = {
  11. let view = UIView(frame: .zero)
  12. view.backgroundColor = .white
  13. return view
  14. }()
  15. lazy var countryCodeTipsImageView: UIImageView = {
  16. let imageView = UIImageView(image: UIImage(named: "detail"))
  17. imageView.isUserInteractionEnabled = false
  18. return imageView
  19. }()
  20. lazy var textLable: UILabel = {
  21. let label = UILabel()
  22. label.text = .useNameText
  23. label.font = UIFont(name: "PingFangSC-Regular", size: 16)
  24. label.adjustsFontSizeToFitWidth = true
  25. return label
  26. }()
  27. lazy var phoneNumTextField: UITextField = {
  28. let textField = createTextField(.phoneNumPlaceholderText)
  29. return textField
  30. }()
  31. lazy var phoneNumBottomLine: UIView = {
  32. let view = createSpacingLine()
  33. return view
  34. }()
  35. lazy var verifyCodeBottomLine: UIView = {
  36. let view = createSpacingLine()
  37. return view
  38. }()
  39. lazy var loginBtn: UIButton = {
  40. let btn = UIButton(type: .custom)
  41. btn.setTitleColor(.white, for: .normal)
  42. btn.setTitle(.loginText, for: .normal)
  43. btn.adjustsImageWhenHighlighted = false
  44. btn.setBackgroundImage(UIColor.tui_color(withHex: "006EFF").trans2Image(), for: .normal)
  45. btn.titleLabel?.font = UIFont(name: "PingFangSC-Medium", size: 18)
  46. btn.layer.shadowColor = UIColor.tui_color(withHex: "006EFF").cgColor
  47. btn.layer.shadowOffset = CGSize(width: 0, height: 6)
  48. btn.layer.shadowRadius = 16
  49. btn.layer.shadowOpacity = 0.4
  50. btn.layer.masksToBounds = true
  51. btn.isEnabled = false
  52. return btn
  53. }()
  54. private func createSpacingLine() -> UIView {
  55. let view = UIView(frame: .zero)
  56. view.backgroundColor = UIColor.tui_color(withHex: "EEEEEE")
  57. return view
  58. }
  59. private func createTextField(_ placeholder: String) -> UITextField {
  60. let textField = UITextField(frame: .zero)
  61. textField.backgroundColor = .white
  62. textField.font = UIFont(name: "PingFangSC-Regular", size: 16)
  63. textField.textColor = UIColor.tui_color(withHex: "333333")
  64. textField.attributedPlaceholder = NSAttributedString(string: placeholder,
  65. attributes:
  66. [NSAttributedString.Key.font :
  67. UIFont(name: "PingFangSC-Regular", size: 16) ?? UIFont.systemFont(ofSize: 16),
  68. NSAttributedString.Key.foregroundColor :
  69. UIColor.tui_color(withHex: "BBBBBB"),])
  70. textField.delegate = self
  71. return textField
  72. }
  73. override func draw(_ rect: CGRect) {
  74. super.draw(rect)
  75. contentView.roundedRect(rect: contentView.bounds, byRoundingCorners: .topRight, cornerRadii: CGSize(width: 40, height: 40))
  76. loginBtn.layer.cornerRadius = loginBtn.frame.height * 0.5
  77. }
  78. override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
  79. super.touchesBegan(touches, with: event)
  80. if let current = currentTextField {
  81. current.resignFirstResponder()
  82. currentTextField = nil
  83. }
  84. UIView.animate(withDuration: 0.3) {
  85. self.transform = .identity
  86. }
  87. }
  88. weak var currentTextField: UITextField?
  89. weak var rootVC: TRTCLoginViewController?
  90. override init(frame: CGRect) {
  91. super.init(frame: frame)
  92. NotificationCenter.default.addObserver(self, selector: #selector(keyboardFrameChange(noti:)), name:
  93. UIResponder.keyboardWillChangeFrameNotification, object: nil)
  94. }
  95. deinit {
  96. NotificationCenter.default.removeObserver(self)
  97. }
  98. @objc func keyboardFrameChange(noti : Notification) {
  99. guard let info = noti.userInfo else {
  100. return
  101. }
  102. guard let value = info[UIResponder.keyboardFrameEndUserInfoKey], value is CGRect else {
  103. return
  104. }
  105. guard let superview = loginBtn.superview else {
  106. return
  107. }
  108. let rect = value as! CGRect
  109. let converted = superview.convert(loginBtn.frame, to: self)
  110. if rect.intersects(converted) {
  111. transform = CGAffineTransform(translationX: 0, y: -converted.maxY+rect.minY)
  112. }
  113. }
  114. required init?(coder: NSCoder) {
  115. fatalError("init(coder:) has not been implemented")
  116. }
  117. var isViewReady = false
  118. override func didMoveToWindow() {
  119. super.didMoveToWindow()
  120. loginBtn.isEnabled = true
  121. guard !isViewReady else {
  122. return
  123. }
  124. isViewReady = true
  125. constructViewHierarchy()
  126. activateConstraints()
  127. bindInteraction()
  128. }
  129. func constructViewHierarchy() {
  130. addSubview(contentView)
  131. contentView.addSubview(textLable)
  132. contentView.addSubview(phoneNumTextField)
  133. contentView.addSubview(phoneNumBottomLine)
  134. contentView.addSubview(loginBtn)
  135. }
  136. func activateConstraints() {
  137. contentView.snp.makeConstraints { (make) in
  138. make.top.equalToSuperview()
  139. make.leading.trailing.bottom.equalToSuperview()
  140. }
  141. textLable.snp.makeConstraints { (make) in
  142. make.top.equalToSuperview().offset(convertPixel(h: 300))
  143. make.leading.equalToSuperview().offset(convertPixel(w: 40))
  144. make.height.equalTo(convertPixel(h: 57))
  145. make.width.equalTo(convertPixel(w: 70))
  146. }
  147. phoneNumTextField.snp.makeConstraints { (make) in
  148. make.top.equalTo(textLable)
  149. make.leading.equalTo(textLable.snp.trailing).offset(convertPixel(w: 5))
  150. make.trailing.equalToSuperview().offset(-convertPixel(w: 40))
  151. make.height.equalTo(convertPixel(h: 57))
  152. }
  153. phoneNumBottomLine.snp.makeConstraints { (make) in
  154. make.bottom.trailing.equalTo(phoneNumTextField)
  155. make.leading.equalTo(textLable)
  156. make.height.equalTo(convertPixel(h: 1))
  157. }
  158. loginBtn.snp.makeConstraints { (make) in
  159. make.top.equalTo(phoneNumBottomLine.snp.bottom).offset(convertPixel(h: 50))
  160. make.leading.equalToSuperview().offset(convertPixel(w: 20))
  161. make.trailing.equalToSuperview().offset(-convertPixel(w: 20))
  162. make.height.equalTo(convertPixel(h: 52))
  163. }
  164. }
  165. func bindInteraction() {
  166. loginBtn.addTarget(self, action: #selector(loginBtnClick), for: .touchUpInside)
  167. }
  168. @objc func loginBtnClick() {
  169. if let current = currentTextField {
  170. current.resignFirstResponder()
  171. }
  172. guard let phone = phoneNumTextField.text else {
  173. return
  174. }
  175. loginBtn.isEnabled = false
  176. rootVC?.login(phone: phone, nickName: "")
  177. DispatchQueue.main.asyncAfter(deadline: .now() + 4.0) {
  178. self.loginBtn.isEnabled = true
  179. }
  180. }
  181. @objc func getVerifyCodeBtnClick() {
  182. }
  183. }
  184. extension TRTCLoginRootView: UITextFieldDelegate {
  185. func textFieldDidBeginEditing(_ textField: UITextField) {
  186. if let last = currentTextField {
  187. last.resignFirstResponder()
  188. }
  189. currentTextField = textField
  190. textField.becomeFirstResponder()
  191. }
  192. func textFieldDidEndEditing(_ textField: UITextField) {
  193. textField.resignFirstResponder()
  194. currentTextField = nil
  195. UIView.animate(withDuration: 0.3) {
  196. self.transform = .identity
  197. }
  198. checkLoginBtnState()
  199. }
  200. func textFieldShouldReturn(_ textField: UITextField) -> Bool {
  201. textField.resignFirstResponder()
  202. return true
  203. }
  204. func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
  205. var maxCount = 11
  206. if textField == phoneNumTextField {
  207. maxCount = 11
  208. }
  209. else {
  210. maxCount = 6
  211. }
  212. guard let textFieldText = textField.text,
  213. let rangeOfTextToReplace = Range(range, in: textFieldText) else {
  214. return false
  215. }
  216. let substringToReplace = textFieldText[rangeOfTextToReplace]
  217. let count = textFieldText.count - substringToReplace.count + string.count
  218. let res = count <= maxCount
  219. if res {
  220. var phoneCtt = 0
  221. var verifyCtt = 0
  222. if textField == phoneNumTextField {
  223. phoneCtt = count
  224. verifyCtt = 6
  225. }
  226. else {
  227. phoneCtt = phoneNumTextField.text?.count ?? 0
  228. verifyCtt = count
  229. }
  230. checkLoginBtnState(phoneCtt: phoneCtt, verifyCtt: verifyCtt)
  231. }
  232. return res
  233. }
  234. func checkLoginBtnState(phoneCtt: Int = -1, verifyCtt: Int = -1) {
  235. var phone = 0
  236. var code = 0
  237. if phoneCtt > -1 || verifyCtt > -1 {
  238. if phoneCtt > -1 {
  239. phone = phoneCtt
  240. }
  241. else {
  242. phone = phoneNumTextField.text?.count ?? 0
  243. }
  244. if verifyCtt > -1 {
  245. code = verifyCtt
  246. }
  247. else {
  248. code = 6
  249. }
  250. }
  251. else {
  252. phone = phoneNumTextField.text?.count ?? 0
  253. code = 6
  254. }
  255. loginBtn.isEnabled = phone > 0 && code == 6
  256. }
  257. }
  258. /// MARK: - internationalization string
  259. fileprivate extension String {
  260. static let titleText = LoginLocalize(key: "Welcome to Tencent Real-Time Communication")
  261. static let phoneNumPlaceholderText = LoginLocalize(key:"Enter a User Id")
  262. static let verifyCodePlaceholderText = LoginLocalize(key:"Enter a verification code")
  263. static let getVerifyCodeText = LoginLocalize(key:"Get")
  264. static let loginText = LoginLocalize(key:"Log In")
  265. static let useNameText = LoginLocalize(key: "User Name")
  266. }