调整UITextView的大小在新行的前2个字符上无法正常工作

时间:2014-11-29 20:28:17

标签: ios objective-c uitextview uitextviewdelegate

我有一个名为UITextView的{​​{1}},这是messageTextView的子视图,我称之为UIView

我需要调整messageFieldContainer和容器UITextView的大小,因为用户会在UIView中输入更多字符。

以下是我用来完成此操作的当前方法:

UITextView

我使用- (void)textViewDidChange:(UITextView *)textView { CGFloat fixedWidth = textView.frame.size.width; CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, CGFLOAT_MAX)]; CGRect newFrame = textView.frame; newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height); if (self.previousFrameSize.height && self.previousFrameSize.height != newFrame.size.height) { self.messageFieldContainer.frame = CGRectMake(0, self.messageFieldContainer.frame.origin.y - 20, self.messageFieldContainer.bounds.size.width, newFrame.size.height + 20); } self.previousFrameSize = newFrame.size; textView.frame = newFrame; } 来跟踪不断变化的previousFrameSize帧大小,如果帧大小发生变化,那么我会增加UITextView的大小以适应增加的文本视图帧大小

除了两种情况外,大部分时间都能正常运行:

  1. 新行,第一个字符
  2. 下面是一个屏幕截图,显示当新行开始并输入行的第一个字符时文本视图的样子:

    enter image description here

    1. 新行,第二个字符
    2. 以下是新行开始时您输入行的第二个字符后文本视图的屏幕截图:

      enter image description here

      以下是键入新行的第三个字符后文本视图的截图。这是它应该100%的时间看起来:

      enter image description here

      我需要修复此逻辑,以便即使您键入新行的第一个或第二个字符,文本视图也总是看起来像第三个图像。

3 个答案:

答案 0 :(得分:0)

我能够通过在Autolayout文件中停用nib/xib并将UITextView's scrollEnabled属性设置为NO来解决新的问题。

禁用AutoLayout略有改进,但UITextView在开始新线时仍然会失真。解决这个问题的唯一方法是禁用滚动。

希望有人觉得这很有用。在我发现随机评论之前,我浪费了几个小时来尝试实施复杂的AutoLayout解决方案。

答案 1 :(得分:0)

我处理了这两天,并且关闭Autolayout对我来说不是一个选择。搜索和尝试后,我找到了解决方案。代码在Swift中,但它不应该太难。您基本上必须使用KVO来监控textView内容大小。

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
    println("Observed")

    //I have to format the textView twice, not sure why, but it is not a mistake.
    // Dont like having to do this, but this has been the only way to make the textview scroll properly on newline.
    let textView:UITextView = object as UITextView
    formatTextViewHeight(textView)
    var topOffset = (textView.bounds.size.height - textView.contentSize.height - textView.contentInset.top * textView.zoomScale) / 2.0
    textView.contentOffset = CGPoint(x: 0, y: -topOffset)
    formatTextViewHeight(textView)

}

我的格式textview方法必须在KVO中调用两次

func formatTextViewHeight(textView: UITextView) {

    let stryBrdPad:CGFloat = 4.0
    self.tableView.beginUpdates()
    self.replyView.frame.size.height = textView.contentSize.height + stryBrdPad
    textView.frame.size.height = textView.contentSize.height
    self.tableView.endUpdates()

}

我是Text API的新手,所以我可能会遗漏一些东西,但我注意到一些流行的应用程序也存在这个问题。当我在textviewDidChange中尝试格式化时,我在日志中注意到contentSize确实发生了变化,但如果我将textView框架设置为contentSize并增加了我的容器框架,则不会发生任何事情......即使使用layoutIfNeeded,updateConstrainst,setNeedsDisplay,我试过他们都是..

答案 2 :(得分:0)

我在网络上看到过几个有这个问题的人。如果您的scrollEnabled属性为false的UITextView,只有在输入其他字符后,它才会在换行符后自动扩展其高度。

要解决此问题,请使用UITextViewDelegate的{​​{1}}方法收听文本视图文字的更改,然后致电textViewDidChangesizeToFit()

示例

layoutIfNeeded()