【问题标题】:Disable UIButton w/ textFieldDidBeginEditing requires clicking off of UITextField to take effect禁用带有 textFieldDidBeginEditing 的 UIButton 需要单击 UITextField 才能生效
【发布时间】:2014-09-23 00:43:24
【问题描述】:

使用UITextFieldDelegate,我将根据 3 UITextFields 是否包含信息来禁用我的UIButton“btnSignup”。目前,它可以正常工作,但要使UIButton 响应式(再次运行if 语句),我必须单击关闭UITextField。当我输入一些东西然后我回去删除它时也是如此。 UIButton 一直处于活动状态,直到我单击关闭 UITextField(如果我单击提交而不单击其他位置,我可以提交,但情况不应该如此。)

class MainVC: UIViewController, UITextFieldDelegate {

    @IBOutlet var receiveName: UITextField!
    @IBOutlet var receiveEmail: UITextField!
    @IBOutlet var receivePhone: UITextField!
    @IBOutlet var btnSignup: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.btnSignup.enabled = false
        self.btnSignup.alpha = 0.3

        self.receiveName.delegate = self
        self.receiveEmail.delegate = self
        self.receivePhone.delegate = self

    func textFieldDidBeginEditing(textField: UITextField) {

        if countElements(receiveName.text) > 0 && countElements(receiveEmail.text) > 0 && countElements(receivePhone.text) > 0 {
            self.btnSignup.enabled = true
            self.btnSignup.alpha = 1
        } else {
            self.btnSignup.enabled = false
            self.btnSignup.alpha = 0.3
        }
    }
}

我正在寻找一种能够提供更实时效果的解决方案。如果在任何时候 UITextField 正在被编辑,该函数应该会监听和响应。

【问题讨论】:

    标签: ios swift uibutton uitextfielddelegate


    【解决方案1】:

    使用与您的代码接近的东西,我可以按如下方式执行此操作。我添加了 3 级。变量以记录文本字段是否输入了某些内容。我在文本字段中添加了标签。我更改了 UITextFieldDelegate 类函数并测试了所有三个字段都有文本。在第三个字段中输入字段后,按钮就会亮起!

    import UIKit
    
    class ViewController: UIViewController, UITextFieldDelegate {
        var receiveNameBool = false
        var receiveEmailBool = false
        var receivePhoneBool = false
    
        @IBOutlet var receiveName: UITextField!
        @IBOutlet var receiveEmail: UITextField!
        @IBOutlet var receivePhone: UITextField!
        @IBOutlet var btnSignup: UIButton!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.btnSignup.enabled = false
            self.btnSignup.alpha = 0.3
    
            self.receiveName.delegate = self
            self.receiveEmail.delegate = self
            self.receivePhone.delegate = self
    
            }
    
        func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool {
    
            if textField.tag == 1 {
                receiveNameBool = true
            } else if textField.tag == 2 {
                receiveEmailBool = true
            } else if textField.tag == 3 {
                receivePhoneBool = true
            }
    
            if receiveNameBool && receiveEmailBool && receivePhoneBool {
                self.btnSignup.enabled = true
                self.btnSignup.alpha = 1
            } else {
                self.btnSignup.enabled = false
                self.btnSignup.alpha = 0.3
            }
            return true
        }
    }
    

    好的,在第二个版本中,我使用了您使用的 textFieldDidBeginEditing 函数。在这种情况下,当您在第三个字段内单击该按钮时,该按钮将被启用。在这两个示例中,如果用户删除他们输入的数据,您仍然需要编写代码来处理这种情况。但是上面的第一个示例可以满足您的需求。

    导入 UIKit

    class ViewController: UIViewController, UITextFieldDelegate {
        var receiveNameBool = false
        var receiveEmailBool = false
        var receivePhoneBool = false
    
        @IBOutlet var receiveName: UITextField!
        @IBOutlet var receiveEmail: UITextField!
        @IBOutlet var receivePhone: UITextField!
        @IBOutlet var btnSignup: UIButton!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.btnSignup.enabled = false
            self.btnSignup.alpha = 0.3
    
            self.receiveName.delegate = self
            self.receiveEmail.delegate = self
            self.receivePhone.delegate = self
    
            }
    
        func textFieldDidBeginEditing(textField: UITextField) {
    
            if textField.tag == 1 {
                receiveNameBool = true
            } else if textField.tag == 2 {
                receiveEmailBool = true
            } else if textField.tag == 3 {
                receivePhoneBool = true
            }
    
            if receiveNameBool && receiveEmailBool && receivePhoneBool {
                self.btnSignup.enabled = true
                self.btnSignup.alpha = 1
            } else {
                self.btnSignup.enabled = false
                self.btnSignup.alpha = 0.3
            }
        }
    }
    

    【讨论】:

    • 我复制并粘贴了您在此处所做的一切,但实际上它根本没有激活 btnSignup。它从未重新激活。你在回答的时候会漏掉一些东西吗?
    • 你连接 IBOutlets 了吗?您是否将标签添加到属性检查器的文本字段中?
    • 是的,他们从一开始就建立了联系
    • 您是否添加了文本字段标签?
    • 我逐字复制了所有内容,不知道发生了什么。
    【解决方案2】:

    我的一个应用也遇到了类似的问题。这发生在我身上,因为委托是在后台线程上调用的,它不会立即更新视图。您需要将所有 ui 更改同步到主线程。见以下代码:

    class MainVC: UIViewController, UITextFieldDelegate {
    
        @IBOutlet var receiveName: UITextField!
        @IBOutlet var receiveEmail: UITextField!
        @IBOutlet var receivePhone: UITextField!
        @IBOutlet var btnSignup: UIButton!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.btnSignup.enabled = false
            self.btnSignup.alpha = 0.3
    
            self.receiveName.delegate = self
            self.receiveEmail.delegate = self
            self.receivePhone.delegate = self
    
        func textFieldDidBeginEditing(textField: UITextField) {
            dispatch_sync(dispatch_get_main_queue(), {
                if countElements(self.receiveName.text) > 0 && countElements(self.receiveEmail.text) > 0 && countElements(self.receivePhone.text) > 0 {
                    self.btnSignup.enabled = true
                    self.btnSignup.alpha = 1
                } else {
                    self.btnSignup.enabled = false
                    self.btnSignup.alpha = 0.3
                }
            })
        }
    }
    

    另外,如果您的 countElements 函数是类的本地函数,请在调用前添加 self.

    【讨论】:

      【解决方案3】:

      为此,您可以使用文本字段委托方法stringByReplacingCharactersInRange

      enum tags: Int{
      
      case receiveNameTag = 1, receiveEmailTag, receivePhoneTag
      
      
      }
      

      导入 UIKit

      类 ViewController: UIViewController, UITextFieldDelegate {

      @IBOutlet var receiveName: UITextField!
      @IBOutlet var receiveEmail: UITextField!
      @IBOutlet var receivePhone: UITextField!
      @IBOutlet var btnSignup: UIButton!
      
      // here first assign the true because all the textfields are empty
      var isReceiveNameTextFieldEmpty = true
      var isReceiveEmailTextFieldEmpty = true
      var isReceivePhoneTextFieldEmpty = true
      
      override func viewDidLoad() {
          super.viewDidLoad()
          // Do any additional setup after loading the view, typically from a nib.
      
          self.btnSignup.enabled = false
          self.btnSignup.alpha = 0.3
      
      
          //here adding tags to the individual textfield and this is the best way to use tags
          receiveName.tag = tags.receiveNameTag.toRaw()
          receiveEmail.tag = tags.receiveEmailTag.toRaw()
          receivePhone.tag = tags.receivePhoneTag.toRaw()
      
          self.receiveName.delegate = self
          self.receiveEmail.delegate = self
          self.receivePhone.delegate = self
      
      }
      
      func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool {
      
          textField.text = (textField.text as NSString).stringByReplacingCharactersInRange(range,
              withString:string)
      
          //checking whether textfield is empty or not
          if countElements(textField.text) > 0 {
      
              if textField.tag == tags.receiveNameTag.toRaw() {
                  isReceiveNameTextFieldEmpty = false
              }
              if textField.tag == tags.receiveEmailTag.toRaw() {
                  isReceiveEmailTextFieldEmpty = false
              }
              if textField.tag == tags.receivePhoneTag.toRaw() {
                  isReceivePhoneTextFieldEmpty = false
              }
      
          }
          else {
      
              if textField.tag == tags.receiveNameTag.toRaw() {
              isReceiveNameTextFieldEmpty = true
              }
              if textField.tag == tags.receiveEmailTag.toRaw() {
                  isReceiveEmailTextFieldEmpty = true
              }
              if textField.tag == tags.receivePhoneTag.toRaw() {
                  isReceivePhoneTextFieldEmpty = true
              }
      
          }
      
          //if atleast one textfield is empty disable button other wise enable
          if isReceiveNameTextFieldEmpty && isReceiveEmailTextFieldEmpty && isReceivePhoneTextFieldEmpty {
              self.btnSignup.enabled = false
              self.btnSignup.alpha = 0.3
          }
          else {
              self.btnSignup.enabled = true
              self.btnSignup.alpha = 1
          }
      
      
      }
      

      }

      【讨论】:

      • 不幸的是,当我在 textFieldDidBeginEditing 函数中添加了相同的代码时,这不起作用。
      • 在 textFieldDidBeginEditing 中注释您的代码并执行您的代码。
      • 请将断点放在应该更改范围方法中的字符并检查这些文本字段是否为空。只需在每个文本字段中键入两个字符并删除一个文本字段文本。希望你能找到答案。
      • 修改后的答案。这是使用标签的最佳方式。
      【解决方案4】:

      可以使用textField(_:shouldChangeCharactersInRange:replacementString:)解决 只需使用您的定义定义此方法,如下所示:

      func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool {
      
              if countElements(receiveName.text) > 0 && countElements(receiveEmail.text) > 0 && countElements(receivePhone.text) > 0 {
                  self.btnSignup.enabled = true
                  self.btnSignup.alpha = 1
              } else {
                  self.btnSignup.enabled = false
                  self.btnSignup.alpha = 0.3
              }
              return true
        }
      

      我认为countElements() 正在计算字符串的长度。

      【讨论】:

        猜你喜欢
        • 2021-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-23
        • 2021-02-04
        • 2012-03-11
        相关资源
        最近更新 更多