Swift 3提交表单 - UITextField仅在重新聚焦字段后才更改

时间:2017-07-04 18:56:06

标签: swift3

我正在处理登录视图,并尝试在文本字段验证失败时更改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;
    }

}

1 个答案:

答案 0 :(得分:1)

当您进行网络通话时,它总是在后台进行...所以为了进行任何类型的UI更新,您需要在主队列中。只需将self.userEmailTextField.errorField()放在DispatchQueue.main.async {...}内,即可立即完成。

还没有真正测试过您的代码。为什么呢?

即使在你当前的代码中,边框仍然会变为红色,但是在几乎像6-7秒之后变为红色(它可能需要更少或更多)...因为它是从后台线程运行的。

我不明白为什么再次点击textField会立即带来红色边框!?这就是我猜测发生的事情:

后台主题更新模型,即更改排队 用户界面/视图的textField颜色要更新...但由于我们在后台队列中,更新的UI可能需要几秒钟才会发生

然后你马上点击textField并强制超快速读取textField及其所有属性,其中包括border-from主线程(实际用户触摸总是通过主线程处理)...即使在屏幕上还没有红色,但由于它在模型上是红色的,它会从中读取并立即将颜色变为红色。