在警报中选择选项时,如何防止我的文本字段成为第一响应者?

Posted

技术标签:

【中文标题】在警报中选择选项时,如何防止我的文本字段成为第一响应者?【英文标题】:How do I prevent my text field from becoming the first responder when selecting a choice in an alert? 【发布时间】:2018-04-06 20:52:56 【问题描述】:

我正在尝试对 textFieldShouldEndEditing 中的文本字段中的条目进行验证,我检查该值是否为非数字或超出范围,然后调用显示警报的函数。显示警报后,我将值设置为默认值,然后调用其他函数进行计算。

无论我选择什么操作来解除警报,都会触发文本字段的编辑。这是我想要的第一个选项(“再试一次”),但对于“设置为默认值”选项,我只想提醒您离开而不开始编辑文本字段,因为已经分配了默认值。我不明白警报如何与第一响应者状态交互,或者为什么文本字段再次被赋予第一响应者状态。相关代码:

func textFieldShouldEndEditing(_ textField: UITextField) -> Bool 
    var InvalidFlagText: String = ""
    let WindIntBool = isStringAnInt(string: textField.text!)
    if WindIntBool  //if entered wt is numeric, check to see if out of bounds of data loaded in table
        if WindInt < LowestWind || WindInt > HighestWind  //value is out of bounds of data, set to default
                txtWind.text = "0"
    //                display alert
                InvalidFlagText = "OutofBounds"
                DisplayAlert(InvalidFlag: InvalidFlagText)
        
    else  // if not numeric, set to default value
            txtWind.text = "0"

            //                display alert
            InvalidFlagText = "Nonnumeric"
            DisplayAlert(InvalidFlag: InvalidFlagText)

   
CalculateResults()
    return true



 func DisplayAlert (InvalidFlag: String) 
    var messageText: String = ""
    if InvalidFlag == "Nonnumeric" 
        messageText = "Please enter a numeric value."
     else if InvalidFlag == "OutofBounds" 
        messageText = "Entered value is outside of the valid numeric range. Please enter a valid numeric value"
    

       let alert = UIAlertController(title: "That is an invalid entry.", message: "\(messageText)", preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "Try Again", style: .cancel, handler: nil))
    alert.addAction(UIAlertAction(title: "Set to Default", style: .default, handler:  action in

    ))

    self.present(alert, animated: true)

【问题讨论】:

提个醒 - 命名约定并不酷。 【参考方案1】:

尝试让所有响应者辞职

alert.addAction(UIAlertAction(title: "Set to Default", style: .default, handler:  action in
      //// set your text value before ////
      self.view.endEditing(true)
))

正确或更好的方法:

func DisplayAlert (InvalidFlag: String) 
    self.view.endEditing(true)
    var messageText: String = ""
    if InvalidFlag == "Nonnumeric" 
        messageText = "Please enter a numeric value."
     else if InvalidFlag == "OutofBounds" 
        messageText = "Entered value is outside of the valid numeric range. Please enter a valid numeric value"
    

    let alert = UIAlertController(title: "That is an invalid entry.", message: "\(messageText)", preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "Try Again", style: .cancel, handler:  action in
         self.txtWind.becomeFirstResponder()
    ))
    alert.addAction(UIAlertAction(title: "Set to Default", style: .default, handler:  action in
         /// set default value ////
    ))

    self.present(alert, animated: true)

【讨论】:

我不确定,但这可能会导致 - 解除警报 - 解除键盘。理想的方法是在显示警报之前关闭键盘。但同样,我可能错了。 我以前试过这个;这让我进入一个循环,不幸的是它一直显示警报。 是的...您必须先将文本值设置为默认值。 @Nitish 我同意。【参考方案2】:

不确定CalculateResults() 方法的作用,我也假设了isStringAnInt 方法。以下是您期望的功能的代码。

import UIKit

let kDEFAULT_WIND = "0"

class ViewController: UIViewController, UITextFieldDelegate 

@IBOutlet weak var txtWind: UITextField!
let HighestWind = 200
let LowestWind = 100
var WindInt = -1
override func viewDidLoad() 
    super.viewDidLoad()
    txtWind.delegate = self


func textFieldShouldReturn(_ textField: UITextField) -> Bool 
    self.view.endEditing(true)

    return true

func textFieldShouldEndEditing(_ textField: UITextField) -> Bool 
    if textField.text == kDEFAULT_WIND
        return true
    
    var InvalidFlagText: String = ""
    let WindIntBool = isStringAnInt(s: textField.text!)
    if WindIntBool  //if entered wt is numeric, check to see if out of bounds of data loaded in table
        if WindInt < LowestWind || WindInt > HighestWind  //value is out of bounds of data, set to default
            InvalidFlagText = "OutofBounds"
            DisplayAlert(InvalidFlag: InvalidFlagText)
        
     else  // if not numeric, set to default value
        InvalidFlagText = "Nonnumeric"
        DisplayAlert(InvalidFlag: InvalidFlagText)

    
//        CalculateResults()
    return true


func isStringAnInt(s : String) -> Bool
    if let val = Int(s)
        WindInt = val
        return true
    
    return false

func DisplayAlert (InvalidFlag: String) 
    var messageText: String = ""
    if InvalidFlag == "Nonnumeric" 
        messageText = "Please enter a numeric value."
     else if InvalidFlag == "OutofBounds" 
        messageText = "Entered value is outside of the valid numeric range. Please enter a valid numeric value"
    
    let alert = UIAlertController(title: "That is an invalid entry.", message: "\(messageText)", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "Try Again", style: .cancel, handler:  action in
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now(), execute: 
            self.txtWind.text = kDEFAULT_WIND
            self.txtWind.becomeFirstResponder()
        )
    ))
    alert.addAction(UIAlertAction(title: "Set to Default", style: .default, handler:  action in
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now(), execute: 
            self.txtWind.text = kDEFAULT_WIND
            self.txtWind.resignFirstResponder()
        )
    ))
    self.present(alert, animated: true)



【讨论】:

这行得通,你和 GIJOW 都是正确的。这个问题是我在调用 DisplayAlert 之前设置了默认值并依赖它,而不是在单击操作后设置它。谢谢你们。

以上是关于在警报中选择选项时,如何防止我的文本字段成为第一响应者?的主要内容,如果未能解决你的问题,请参考以下文章

SCLAlertView - 专注于文本字段

选择 UITextField 文本时隐藏选项菜单

如何防止 UIWindow 成为关键窗口?

如何在警报中访问 Uitextfield 的文本?

如何从警报窗口内的列表中显示所选项目的名称

如何在第一次单击日期文本字段时生成我的日期选择器 UI?