Я работаю над представлением входа в систему и пытаюсь изменить цвет границы UITextField в Xcode / swift3, когда проверка текстового поля не выполняется. 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 ответ
Когда вы выполняете сетевой вызов, это всегда происходит в фоновом режиме ... поэтому для выполнения каких-либо обновлений пользовательского интерфейса вам необходимо находиться в основной очереди. Просто поместите self.userEmailTextField.errorField()
внутрь DispatchQueue.main.async {...}
, чтобы это было сделано немедленно.
Также не очень хорошо тестировал ваш код. Почему?
Даже в вашем текущем коде граница все равно станет красной, но она станет красной примерно через 6-7 секунд (это может занять меньше или больше для вас) ... потому что она запускается из фонового потока.
Я не понимаю, почему при повторном нажатии на текстовое поле сразу появляется красная граница !? Вот что, как я догадываюсь , происходит:
Из фонового потока вы обновляете модель , т. Е. Меняете цвет textField, который ставит в очередь пользовательский интерфейс / представление для обновления. ... но поскольку мы находимся в фоновой очереди, обновление пользовательского интерфейса может занять несколько секунд
Но затем вы сразу же нажали на textField и заставили сверхбыстрое чтение textField и всех его свойств, включая границу, из основного потока (фактические действия пользователя всегда обрабатываются через основной поток) ... которые, хотя еще не красный на экране, но поскольку он красный на модели, он будет считывать с него и сразу же изменит цвет на красный.
Похожие вопросы
Связанные вопросы
Новые вопросы
swift3
Используйте этот тег только для вопросов, непосредственно связанных с изменениями в версии 3 языка программирования Apple Swift. Используйте тег [swift] для более общих языковых вопросов или теги [ios], [cocoa], [apple-watch] и т. Д. Для вопросов о разработке на платформах Apple.
self.userEmailTextField.errorField()
внутрьDispatchQueue.main.async {...}
, чтобы это было сделано немедленно