编辑 UITextField 时检查用户名是否在 Firestore 数据库中
Check if username is in Firestore Database while editing UITextField
我正在尝试检查在用户键入名称时是否使用了用户名。目前我有这两个功能,它们几乎按照我希望的方式工作,但不是 100% 正确:
textFieldDidChange
:
@objc private func textFieldDidChange(_ textField: UITextField) {
switch textField {
// ... //
case usernameTextField:
if textField.text?.isEmpty == false {
checkUsername(field: textField.text!) { (success) in
print(textField.text!)
if success == true {
// username is taken
print("Username is taken")
self.setupUsernameTextField()
self.checkUsernameImage.image = UIImage(named: "false")
self.checkUserNameLabel.text = "Benutzername ist bereits vergeben"
} else {
// username is not taken
print("Username is not taken")
self.checkUsernameImage.image = UIImage(named: "correct")
self.checkUserNameLabel.text = "gültiger Benutzername"
}
}
}else {
self.checkUsernameImage.image = UIImage(named: "false")
self.checkUserNameLabel.text = "kein gültiger Benutzername"
}
default:
break
}
}
// helper function to check if username is in databse -> later in Datahandler
func checkUsername(field: String, completion: @escaping (Bool) -> Void) {
let db = Firestore.firestore()
let collectionRef = db.collection("users")
collectionRef.whereField("username", isEqualTo: field).getDocuments { (snapshot, err) in
if let err = err {
print("Error getting document: \(err)")
} else if (snapshot?.isEmpty)! {
completion(false)
} else {
for document in (snapshot?.documents)! {
if document.data()["username"] != nil {
completion(true)
}
}
}
}
}
问题: 如果您输入的内容非常快,或者如果您的互联网连接不是很好,它会显示 Username is not taken
而实际上是。
如果您查看 Instagram 应用程序,他们会以完美的方式做到这一点:
- 输入内容,速度更快
- 在您停止输入一秒钟后,
loading indicator
会弹出,然后您才会收到反馈,无论用户名是否被占用
- 在
loading indicator
处于活动状态时输入内容,它会停止,只有在您再次停止输入时才会重新开始。
我的问题:我如何意识到这一点???比如我怎么知道用户 "stops" 打字但 textField
仍然是 editing
?我用 shouldEndEditing
尝试过,但只有当 textfield
不再被选中时才有效,这不是我想要实现的。最后,我希望拥有与 Instagram 应用程序完全相同的流程。
关于如何实现这一点的任何想法?
在@Jays 的建议下我成功了:
我的 textField
与 didChange
方法连接,如下所示:
timer.invalidate() // reset timer
// start the timer
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
连接的 timerAction
方法如下所示:
// called every time interval from the timer
@objc func timerAction() {
checkUsername(field: usernameTextField.text!) { (success) in
print(self.usernameTextField.text!)
if success == true {
// username is taken
print("Username is taken")
self.setupUsernameTextField()
self.checkUsernameImage.image = UIImage(named: "false")
self.checkUserNameLabel.text = "Benutzername ist bereits vergeben"
// stop timer
self.timer.invalidate()
} else {
// username is not taken
print("Username is not taken")
// stop timer
self.timer.invalidate()
}
}
}
完全按照我想要的方式工作,感谢您的帮助:)
我正在尝试检查在用户键入名称时是否使用了用户名。目前我有这两个功能,它们几乎按照我希望的方式工作,但不是 100% 正确:
textFieldDidChange
:
@objc private func textFieldDidChange(_ textField: UITextField) {
switch textField {
// ... //
case usernameTextField:
if textField.text?.isEmpty == false {
checkUsername(field: textField.text!) { (success) in
print(textField.text!)
if success == true {
// username is taken
print("Username is taken")
self.setupUsernameTextField()
self.checkUsernameImage.image = UIImage(named: "false")
self.checkUserNameLabel.text = "Benutzername ist bereits vergeben"
} else {
// username is not taken
print("Username is not taken")
self.checkUsernameImage.image = UIImage(named: "correct")
self.checkUserNameLabel.text = "gültiger Benutzername"
}
}
}else {
self.checkUsernameImage.image = UIImage(named: "false")
self.checkUserNameLabel.text = "kein gültiger Benutzername"
}
default:
break
}
}
// helper function to check if username is in databse -> later in Datahandler
func checkUsername(field: String, completion: @escaping (Bool) -> Void) {
let db = Firestore.firestore()
let collectionRef = db.collection("users")
collectionRef.whereField("username", isEqualTo: field).getDocuments { (snapshot, err) in
if let err = err {
print("Error getting document: \(err)")
} else if (snapshot?.isEmpty)! {
completion(false)
} else {
for document in (snapshot?.documents)! {
if document.data()["username"] != nil {
completion(true)
}
}
}
}
}
问题: 如果您输入的内容非常快,或者如果您的互联网连接不是很好,它会显示 Username is not taken
而实际上是。
如果您查看 Instagram 应用程序,他们会以完美的方式做到这一点:
- 输入内容,速度更快
- 在您停止输入一秒钟后,
loading indicator
会弹出,然后您才会收到反馈,无论用户名是否被占用 - 在
loading indicator
处于活动状态时输入内容,它会停止,只有在您再次停止输入时才会重新开始。
我的问题:我如何意识到这一点???比如我怎么知道用户 "stops" 打字但 textField
仍然是 editing
?我用 shouldEndEditing
尝试过,但只有当 textfield
不再被选中时才有效,这不是我想要实现的。最后,我希望拥有与 Instagram 应用程序完全相同的流程。
关于如何实现这一点的任何想法?
在@Jays 的建议下我成功了:
我的 textField
与 didChange
方法连接,如下所示:
timer.invalidate() // reset timer
// start the timer
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
连接的 timerAction
方法如下所示:
// called every time interval from the timer
@objc func timerAction() {
checkUsername(field: usernameTextField.text!) { (success) in
print(self.usernameTextField.text!)
if success == true {
// username is taken
print("Username is taken")
self.setupUsernameTextField()
self.checkUsernameImage.image = UIImage(named: "false")
self.checkUserNameLabel.text = "Benutzername ist bereits vergeben"
// stop timer
self.timer.invalidate()
} else {
// username is not taken
print("Username is not taken")
// stop timer
self.timer.invalidate()
}
}
}
完全按照我想要的方式工作,感谢您的帮助:)