如何在UIAlertController中验证邮箱并控制Sign Up按钮激活状态?
解决UIAlertController中“Sign Up”按钮按需激活的问题
嘿,作为Swift新手遇到这种UI交互的问题太正常了,我来一步步帮你实现这个需求——让“Sign Up”按钮只有在输入的文本包含@时才激活。
核心思路
- 先把“Sign Up”按钮保存为变量,方便后续修改它的启用状态
- 初始化时先禁用该按钮,避免用户输入无效内容就提交
- 给输入文本框添加编辑内容变化的监听,实时检查输入是否符合要求
- 根据输入内容的合法性,动态切换按钮的启用状态
修改后的完整代码
@IBAction func loginTapped(_ sender: UIButton) { // 用户未登录,因此提示其输入邮箱地址 let loginAlert = UIAlertController(title: "Sign Up For LivNao", message: "Please enter your email address to join the LivNao study", preferredStyle: .alert) // 1. 先创建Sign Up按钮并设置为禁用状态 let signUpAction = UIAlertAction(title: "Sign Up", style: .default) { [weak self] action in guard let self = self else { return } self.handleLogin(loginAlert) } signUpAction.isEnabled = false loginAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) loginAlert.addAction(signUpAction) loginAlert.addTextField { textField in textField.placeholder = "Enter email" // 2. 添加文本编辑变化的监听,触发检查方法 textField.addTarget(self, action: #selector(self.checkEmailInput(_:)), for: .editingChanged) // 把signUp按钮绑定到文本框上,方便在检查方法里获取 objc_setAssociatedObject(textField, &AssociatedKeys.signUpAction, signUpAction, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } loginAlert.view.setNeedsLayout() self.present(loginAlert, animated: true, completion: nil) } // 用于存储关联对象的Key(避免命名冲突) private struct AssociatedKeys { static var signUpAction = "signUpAction" } // 3. 实时检查邮箱输入的方法 @objc private func checkEmailInput(_ textField: UITextField) { // 基础验证:判断输入文本是否包含@ let isEmailValid = textField.text?.contains("@") == true // 从文本框的关联对象中取出Sign Up按钮,更新启用状态 if let signUpAction = objc_getAssociatedObject(textField, &AssociatedKeys.signUpAction) as? UIAlertAction { signUpAction.isEnabled = isEmailValid } }
额外优化建议
如果需要更严谨的邮箱格式验证(比如包含域名后缀、符合RFC标准),可以把基础的contains("@")替换成正则表达式验证:
// 更严谨的邮箱正则 let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}" let isEmailValid = NSPredicate(format:"SELF MATCHES %@", emailRegex).evaluate(with: textField.text)
这样修改后,用户输入符合要求的邮箱时,“Sign Up”按钮会自动变成可点击状态;输入不合法时按钮保持禁用,完全满足你的需求~
内容的提问来源于stack exchange,提问作者Daniel Leung
相关产品推荐
相关产品推荐

