无法更改UITextField inputView框架大小

时间:2015-10-03 11:52:22

标签: ios xcode swift uitextfield uikeyboard

我使用inputView为UITextField设置了自定义键盘。我可以再次切换到原生键盘,此时键盘的高度可以改变(例如,在自动提示上向上/向下滑动,更换键盘)。这就是为什么我的自定义键盘inputView需要能够改变它的高度。

但是,当inputView的帧高度发生变化时,它会再次神奇地重置自己!

(我在iOS 8.4模拟器上这样做。)

将问题简化为最基本的例子:

func createInputView(#height:CGFloat) -> UIView {
    let view = ViewSubclass(frame: CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), height))
    view.backgroundColor = UIColor.redColor()
    let label = UILabel(frame: CGRectMake(0, 0, 100, 30))
    label.backgroundColor = UIColor.yellowColor()
    label.text = "Hello!"
    view.addSubview(label)
    return view
}

// halves the view's frame height
func changeFrameHeightForView(view: UIView) {
    view.frame = {
        var f = view.frame
        f.size.height = f.size.height / 2.0
        return f
    }()
}

override func viewDidLoad() {
    super.viewDidLoad()
    view1 = createInputView(height: 200)
    view2 = createInputView(height: 150)
    myTextField.inputView = view1
}

// to reproduce this scenario, you would first focus on the text field to open the keyboard, and then tap on the controller's view, which triggers the below action:

// example 1
@IBAction func viewTapped(sender: AnyObject) {
    let currentInputView = self.myTextField.inputView!
    println("starting height: \(currentInputView.frame.height)")
    // starting height: 200.0

    changeFrameHeightForView(currentInputView)
    println("height after frame changed: \(currentInputView.frame.height)")
    // height after frame changed: 100.0

    self.myTextField.reloadInputViews()
    println("height after reloadInputViews: \(currentInputView.frame.height)")
    // height after reloadInputViews: 100.0

    // if I stopped here, the view will update and be shorter, but it shows a grey area underneath - the keyboard itself hasn't changed height! So try to dismiss the keyboard and reload it again...

    myTextField.resignFirstResponder()
    println("height after resign first responder: \(currentInputView.frame.height)")
    // height after resign first responder: 200.0   // --> HOW DID IT GET REVERTED???

    myTextField.becomeFirstResponder()
    println("height after become first responder: \(currentInputView.frame.height)")
    // height after become first responder: 200.0

}

因此,例1的问题是: 为什么一旦调用resignFirstResponder就会恢复帧?

我开始思考,也许文本字段正在对inputView做一些事情。那么如果我把它弄清楚怎么办?那么它应该不能影响原始视图吧?这就是它变得奇怪的地方......

// example 2
@IBAction func viewTapped(sender: AnyObject) {
    let currentInputView = self.myTextField.inputView!
    println("starting height: \(currentInputView.frame.height)")
    // starting height: 200.0

    // remove the inputView and close the keyboard.
    self.myTextField.inputView = nil
    self.myTextField.reloadInputViews()
    myTextField.resignFirstResponder()

    // change the frame height
    changeFrameHeightForView(currentInputView)
    println("height after frame changed: \(currentInputView.frame.height)")
    // height after frame changed: 100.0

    // set it as the inputView again
    self.myTextField.inputView = currentInputView
    self.myTextField.reloadInputViews()
    println("height after reloadInputViews: \(currentInputView.frame.height)")
    // height after reloadInputViews: 100.0

    // open the keyboard
    myTextField.becomeFirstResponder()
    println("height after become first responder: \(currentInputView.frame.height)")
    // height after become first responder: 200.0    // --> HOW DID IT GET REVERTED??? Shouldn't the keyboard use the new frame height?

}

转到示例3 ...... 那些敏锐的眼睛会注意到我有2个输入视图设置。在这里,我将在它们之间切换inputView。有趣的是,如果分配了不同的视图对象,它将按预期工作:

// example 3
@IBAction func viewTapped(sender: AnyObject) {
    let currentInputView = self.myTextField.inputView!
    let otherView = (currentInputView == self.view1 ? self.view2 : self.view1)
    self.myTextField.inputView = otherView
    self.myTextField.reloadInputViews()
}

对于长期问题道歉,但我在本次调查中记录了我的发现。每次键盘改变高度时,我都不想创建一个全新的视图。

Facebook messenger的自定义键盘可以做类似的事情,所以我希望有人可以对此有所了解。

谢谢!

0 个答案:

没有答案