我正在处理登录视图,并尝试在文本字段验证失败时更改Xcode / swift3中UITextField的边框颜色。 UITextField应该是红色边框颜色。
问题如果输入电子邮件,然后输入密码然后按提交按钮,我必须在获得红色边框之前再次关注电子邮件文本字段。
到目前为止,这是我的 LoginViewController.swift :
import Foundation
import UIKit
class LoginViewController : UIViewController, UITextFieldDelegate {
@IBOutlet weak var userEmailTextField: UITextField!
@IBOutlet weak var userPasswordTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
// login button action
@IBAction func loginButtonTabbed(_ sender: Any) {
// getting values from text fields
let userEmail = userEmailTextField.text;
let userPassword = userPasswordTextField.text;
// set enpoind data
let requestURL = NSURL(string: Constants.apiUrl)
//creating a task to send the post request
var request = URLRequest(url: requestURL as! URL)
request.httpMethod = "POST"
let postString = "cmd=addUser&email="+userEmail!+"&password="+userPassword!
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
do {
let json = try? JSONSerialization.jsonObject(with: data, options: [])
// store json response to dictionary
if let dictionary = json as? [String: Any] {
// check if we got validation errors
if let nestedDictionary = dictionary["validation"] as? [String: Any] {
// display validation messages on device
if let emailMsg = nestedDictionary["Email"] as? String { // change color of textfield
self.userEmailTextField.errorField()
}
}
}
} catch let error as NSError {
print(error)
}
}
//executing the task
task.resume()
}
}
和UITextField扩展 UITextField.swift :
import Foundation
import UIKit
extension UITextField {
func errorField(){
self.layer.borderColor = UIColor(red: 255/255.0, green: 59/255.0, blue: 48/255.0, alpha: 1.0).cgColor
self.layer.borderWidth = 1.0;
}
}
答案 0 :(得分:1)
当您进行网络通话时,它总是在后台进行...所以为了进行任何类型的UI更新,您需要在主队列中。只需将self.userEmailTextField.errorField()
放在DispatchQueue.main.async {...}
内,即可立即完成。
还没有真正测试过您的代码。为什么呢?
即使在你当前的代码中,边框仍然会变为红色,但是在几乎像6-7秒之后变为红色(它可能需要更少或更多)...因为它是从后台线程运行的。
我不明白为什么再次点击textField会立即带来红色边框!?这就是我猜测发生的事情:
从后台主题更新模型,即更改排队 用户界面/视图的textField颜色要更新...但由于我们在后台队列中,更新的UI可能需要几秒钟才会发生
然后你马上点击textField并强制超快速读取textField及其所有属性,其中包括border-from主线程(实际用户触摸总是通过主线程处理)...即使在屏幕上还没有红色,但由于它在模型上是红色的,它会从中读取并立即将颜色变为红色。