【问题标题】:How to change background color of UIDatePicker set as UITextField inputView?如何更改设置为 UITextField inputView 的 UIDatePicker 的背景颜色?
【发布时间】:2017-07-05 18:19:26
【问题描述】:

请不要标记为重复。可用的答案还没有回答我的问题。

我使用UIDatePicker 作为UITextField's inputView(在UITableViewCell 内):

@IBOutlet weak var theTextField: UITextField!

func textFieldDidBeginEditing(_ textField: UITextField) {

        let picker = UIDatePicker()
        picker.setValue(Colors.CI2, forKeyPath: "textColor")

        picker.datePickerMode = .date

        textField.inputView = picker
        textField.inputView?.backgroundColor = Colors.CI1 // my desired color

        picker.addTarget(self, action: #selector(datePickerValueChanged), for: .valueChanged)

}

问题:颜色只会在第二次调用选取器时发生变化。

我猜,出现这个问题是因为 inputView 是可选的,并且只有在第二次调用选择器时,inputView 才会在我想更改颜色的那一刻被实例化。

我尝试继承 UITextField 并观察 inputView

class DateTextField: UITextField {

    override var inputView: UIView? {

        didSet {

            self.inputView?.backgroundColor = Colors.CI1
            self.reloadInputViews()

        }

    }

}

很遗憾没有成功。相同的行为。我错过了什么?非常感谢您的帮助。

【问题讨论】:

  • 我在应用程序中有类似的功能,但我在viewDidLoad 中定义了选择器,然后稍后再引用它。使用这种方法,backgroundColor 更改对我来说没有问题。此外,在inputView 更改之前,您的didSet 不会被调用,因此这也可能导致您的问题。根据 Apple,“首次初始化属性时不会调用 willSet 和 didSet 观察者。仅当属性的值在初始化上下文之外设置时才会调用它们。”
  • textField 是 UITableViewCell 的一部分。因此 viewDidLoad 不会生效。抱歉,如果这会影响您的回答
  • 你应该仍然可以提前定义它,也许不是在viewDidLoad,而是在另一个地方。另外,请参阅我评论的第二部分,我不会尝试在 didSet 中设置 bg 颜色
  • 我得到了你的第二部分。但是这个解决方案无论如何都是表格的,因为它不起作用。这只是第一个猜测的选项
  • 对不起,我不太明白你的评论。

标签: ios swift uitextfield uidatepicker


【解决方案1】:

错误是我在 Interface Builder 中设置了键盘外观。一旦设置回default,它就可以正常工作了。

【讨论】:

  • 这是一个很好的方法,它可以工作,但是有什么方法可以改变背景颜色并使键盘外观变暗吗?
【解决方案2】:

您可以使用以下库来自定义颜色 https://github.com/prolificinteractive/PIDatePicker

【讨论】:

    【解决方案3】:

    这段代码对我有用

    func textFieldDidBeginEditing(_ textField: UITextField) {   
            let picker = UIDatePicker()
            picker.datePickerMode = .date
    
            textField.inputView = picker
            textField.inputView?.backgroundColor = UIColor.blue
    
    }
    

    即使在第一次编辑时,它也会显示为蓝色。

    还有:

    您可以在 viewDidLoad 方法中创建选择器,设置它的背景颜色,给它一个标签,然后使用委托方法中的标签访问这个选择器,而不是在那里创建变量,而不是在 textField 委托方法中创建一个选择器实例.

    【讨论】:

      【解决方案4】:

      创建一个保存日期选择器颜色的函数,并在textFieldDidBeginEditing 中调用它。我认为这应该可以解决您的问题。

      【讨论】:

      • 这与当前的方法有何不同?
      • 该函数将被单独调用,因此您无需等到值更改后才能看到响应。
      • 如果它在 'textFieldDidBeginEditing' 内或直接在 textFieldDidBeginEditing 内作为函数调用不会影响我错了吗?
      • 是的。正如预期的那样没有变化。自从。正如预期的那样。如果您直接在textFieldDidBeginEditing 中设置值,或者同时调用一个函数-> 生命周期调用同时发生-> 在inputView 实例化之前
      • 感谢您的意见。我已经按照你的方法试过了,但它仍然需要第二次加载才能改变颜色。在cellForRowAt,还有awakeFromNib,还有textFieldShouldBeginEditing都试过了
      【解决方案5】:

      所以你提到这个文本字段在 UITableViewCell... 我建议将第一块代码添加到 UITextFieldDelegate 然后在 tableView(_:willDisplay:forRowAt:) 函数中的 UITableViewDelegate 中,设置将文本字段委托给您的自定义 UITextFieldDelegate

      在不了解您的代码结构的情况下,我只能为您提供一个非常通用的实现:

      @IBOutlet weak var theTextField: UITextField!
      
      //Add your customisation to the textField...
      extension ViewController : UITextFieldDelegate {
          func textFieldDidBeginEditing(_ textField: UITextField) {
      
                  let picker = UIDatePicker()
                  picker.setValue(Colors.CI2, forKeyPath: "textColor")
      
                  picker.datePickerMode = .date
      
                  textField.inputView = picker
                  textField.inputView?.backgroundColor = Colors.CI1 // my desired color
      
                  picker.addTarget(self, action: #selector(datePickerValueChanged), for: .valueChanged)
      
          }
      }
      
      extension ViewController : UITableViewDelegate {
          //Set the delegate when the UITableViewCell appears:
          func tableView(_ tableView: UITableView, 
                      willDisplay cell: UITableViewCell, 
                         forRowAt indexPath: IndexPath) {
              let dateCell = = self.tableView.dequeueReusableCellWithIdentifier("cell") as! DateCell
      
              dateCell.delegate = self
      
              return dateCell
          }
      }
      

      【讨论】:

        【解决方案6】:

        不要在textFieldDidBeginEditing() 中更改inputView。最后一次可以更改textField.inputView 属性是在textFieldShouldBeginEditing()

        至于最佳实践:您应该将textView.inputView 配置的所有代码移动到您创建textView 的位置以进行一次性配置。例如:

        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            // get the cell
            // get your instance of textField
            // ...
        
            // Configure everything you want about your input view
            let picker = UIDatePicker()
            picker.setValue(Colors.CI2, forKeyPath: "textColor")
            picker.datePickerMode = .date
            picker.backgroundColor = Colors.CI1
            textField.inputView = picker // <-- You just have to assign this ONCE
        
            // ... Continue your setup ...
            return cell
        }
        

        如果您需要更改inputView 的配置每次必须在屏幕上出现,请在textFieldShouldBeginEditing(){ ... } 中更改textView.inputView = ...


        为什么它不起作用

        在您的代码中(当您在textField DID BeginEditing 中进行更改时),显示的UIDatePicker 始终是先前创建的。当您创建 textField 实例时,似乎已设置(但未配置)灰色。

        textFieldDidBeginEditing()中,系统已经绘制了textView.inputView不会修改inputView属性再查看。

        【讨论】:

        • 感谢您的意见。我已经按照你的方法试过了,但它仍然需要第二次加载才能改变颜色。在cellForRowAt,还有awakeFromNib,还有textFieldShouldBeginEditing都试过了
        • 我怀疑你已经在某个地方实例化了 UIDatePicker 而没有改变颜色(这就是为什么它一开始看起来是灰色的)。您很可能已经这样做了,否则默认键盘会显示而不是灰色日期选择器。请检查您文件中的一些搜索:- 在哪里设置 .inputView 属性,- 在哪里实例化代码文件中的 UIDatePicker 元素。
        猜你喜欢
        • 2014-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-18
        • 1970-01-01
        • 2014-08-01
        • 1970-01-01
        • 2011-11-11
        相关资源
        最近更新 更多