使用自动收缩调整UILabel文本

时间:2016-06-29 02:13:42

标签: ios xcode swift

背景

我正在创建一个应用程序,在其中我有一个动画,当键盘出现时,它会重新定位UILabelUITextField。它设置如下:

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(raiseTextField), name: UIKeyboardWillShowNotification, object: nil)

这就是功能:

func raiseTextField(sender: NSNotification){
    UIView.animateWithDuration(0.25, animations: { () -> Void in
        self.userInputTextFieldBottomContstraint.constant = sender.userInfo![UIKeyboardFrameEndUserInfoKey]!.CGRectValue().size.height
        self.view.layoutIfNeeded()
    })
}

我的故事板看起来像这样: Storyboard

我设置了约束,以便friendInputView的大小正确,并且自动收缩,因此字体会相应调整。

问题

当我拨打raiseTextField()时,一切正常,但friendInputView的字体大小需要很长时间才能更改。在动画发生时而不是更新,它会在之后更新

它最终会调整,而不是以首选速度调整。

我尝试在self.friendInputLabel.adjustsFontSizeToFitWidth = true内添加animateWithDuration(),但似乎没有改变任何内容。

实施例

在提高键盘之前:

(正确调整文字)

Before

提高键盘后立即:

(文字太大)

Middle

提升键盘后的第二个左右:

(正确调整文字)

After

底线

有没有办法让UILabel以编程方式调整文本大小,而不是仅仅等待它自己更新?与layoutIfNeeded()重新调整约束的方式类似,是否有任何函数可以重新调整自动收缩?

编辑1

我最终根据我得到的答案表示使用UITextFieldDelegate代替NSNotificationCenter来开始工作。我用以下代码替换了raiseTextField()函数:

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {

    self.userInputTextFieldBottomContstraint.constant = 250
    self.view.setNeedsUpdateConstraints()
    UIView.animateWithDuration(0.25, animations: { () -> Void in

        self.view.layoutIfNeeded()
    })

    return true
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
    textField.resignFirstResponder()

    self.userInputTextFieldBottomContstraint.constant = 10
    self.view.setNeedsUpdateConstraints()

    UIView.animateWithDuration(0.25, animations: { () -> Void in
        self.view.layoutIfNeeded()
    })

    return true
}

但是,现在我有一个新问题:如何才能使用真正的键盘大小?假设键盘大小始终为250并不是很有帮助。

我尝试通过创建此变量来实现:

var keyboardHeight: CGFloat?

将其放入viewDidLoad()

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(setTheKeyboardHeight), name: UIKeyboardWillShowNotification, object: nil)

创建此功能:

func setTheKeyboardHeight(sender: NSNotification){
    keyboardHeight = sender.userInfo![UIKeyboardFrameEndUserInfoKey]?.CGRectValue().height
}

然后我将其添加到textFieldShouldBeginEditing(),如下所示:

self.userInputTextFieldBottomContstraint.constant = keyboardHeight!

self.view.setNeedsUpdateConstraints()

UIView.animateWithDuration(0.25, animations: { () -> Void in
    self.view.layoutIfNeeded()
})

return true

然而,它最终只是给出错误:

fatal error: unexpectedly found nil while unwrapping an Optional value

我认为这是因为keyboardHeight textFieldShouldBeginEditing()被调用后被设置为,但我不知道如何修复它。

使用textFieldShouldBeginEditing()时有什么方法可以访问键盘高度,还是必须使用NSNotificationCenter

1 个答案:

答案 0 :(得分:0)

我已经完成了你所做的相同的演示,并观察了UIKeyboardNotification的一些奇怪的行为,我不确定它是奇怪的还是只是那样,

我观察到的是当您更改UIKeyboardNotification中的任何约束时,它会使用动画更改约束常量(或帧),即使您尚未使用UIView animationWithDuration块。所以我认为这种延迟可能是由于KeyboardNotification添加的动画效果,

func raiseTextField(sender: NSNotification){

    self.bottomConstraintTextField.constant = 250//sender.userInfo![UIKeyboardFrameEndUserInfoKey]!.CGRectValue().size.height
    self.view.setNeedsUpdateConstraints()

    //As you can see i have commented the animation block, still it changes the constraint with animation.
    //UIView.animateWithDuration(0.25, animations: { () -> Void in

        self.view.layoutIfNeeded()
    //})
}

所以在你的场景中我已经在textFields委托中添加了动画代码,它按预期工作了,

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {

    self.bottomConstraintTextField.constant = 250//sender.userInfo![UIKeyboardFrameEndUserInfoKey]!.CGRectValue().size.height
    self.view.setNeedsUpdateConstraints()
    UIView.animateWithDuration(0.25, animations: { () -> Void in

    self.view.layoutIfNeeded()
    })

    return true
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
    textField.resignFirstResponder()

    self.bottomConstraintTextField.constant = 10
    self.view.setNeedsUpdateConstraints()

    UIView.animateWithDuration(0.25, animations: { () -> Void in
        self.view.layoutIfNeeded()
    })

    return true
}

结果如下,

enter image description here

希望它对你有所帮助。

<强>更新

我已经玩了它并发现了一个解决方法,所以不是采用变量来保持键盘高度,你可以按照下面的方式进行操作,

func raiseTextField(sender: NSNotification){

    self.bottomConstraintTextField.constant = sender.userInfo![UIKeyboardFrameEndUserInfoKey]!.CGRectValue().size.height
    self.view.setNeedsUpdateConstraints()

    self.view.layoutIfNeeded()
}


func textFieldShouldBeginEditing(textField: UITextField) -> Bool {

    self.bottomConstraintTextField.constant = 200
    self.view.setNeedsUpdateConstraints()

    UIView.animateWithDuration(0.25, animations: { () -> Void in

    self.view.layoutIfNeeded()
    })

    return true
}

同时拥有textField委托和KeyboardNotification并更改textField委托中的底部约束,它将在键盘通知之前被调用,通过这样做,您将不会观察缩小标签文本的延迟。

请参阅下面的更新效果,

enter image description here