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

Ios 在新行的前两个字符上调整UITextView的大小无法正常工作,ios,objective-c,uitextview,uitextviewdelegate,Ios,Objective C,Uitextview,Uitextviewdelegate,我有一个名为messageTextView的UITextView,它是我称之为messageFieldContainer的UIView的子视图 随着用户在UITextView中键入更多字符,我需要调整我的UITextView和容器的大小 以下是我目前用于实现此目的的方法: - (void)textViewDidChange:(UITextView *)textView { CGFloat fixedWidth = textView.frame.size.width; CGSize

我有一个名为
messageTextView
UITextView
,它是我称之为
messageFieldContainer
UIView
的子视图

随着用户在
UITextView
中键入更多字符,我需要调整我的
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
帧大小,如果帧大小发生变化,我会增加
messageFieldContainer
的大小以适应增加的文本视图帧大小

除两种情况外,这在大多数情况下都能正常工作:

  • 新行,第一个字符
  • 以下是一个屏幕截图,显示了当新行开始并键入该行的第一个字符时,文本视图的外观:

  • 新行,第二个字符
  • 下面是一个屏幕截图,显示了当新行开始并键入该行的第二个字符时,文本视图的外观:

    下面是键入新行的第三个字符后文本视图的屏幕截图。这就是它在所有情况下的外观:


    我需要修正这个逻辑,使文本视图始终看起来像第三个图像,甚至当您键入新行的第一个或第二个字符时。

    我可以通过在我的
    nib/xib
    文件中禁用
    Autolayout
    ,并将
    UITextView的
    滚动启用
    属性设置为
    NO
    来解决新行问题

    禁用
    AutoLayout
    只做了一点小小的改进,但是
    UITextView
    在开始新行时仍然会失真。解决这个问题的唯一方法是禁用滚动


    希望有人觉得这很有用。我花了几个小时试图实现复杂的
    自动布局
    解决方案,直到我发现一条提到上述内容的随机评论。

    我处理了两天,关闭自动布局对我来说不是一个选择。在搜索和尝试之后,我找到了一个解决方案。代码是用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)
    
    }
    

    我不熟悉文本API,所以我可能遗漏了一些东西,但我注意到一些流行的应用程序也有这个问题。当我尝试在textviewDidChange中设置格式时,我在日志中注意到contentSize确实发生了变化,但如果我将textView框架设置为contentSize并增加容器框架,则不会发生任何事情。。。即使使用layoutifneed、updateconstraint、setNeedsDisplay,我还是尝试了所有这些方法。

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

    要解决此问题,请使用
    UITextViewDelegate
    textViewDidChange
    方法侦听文本视图文本的更改,并调用
    sizeToFit()
    layoutifneed()

    示例

    func textViewDidChange(textView: UITextView) {
    
        textView.sizeToFit()
        textView.layoutIfNeeded()
    
    }
    

    您是否尝试使用自动布局?当您找到任何解决方案时,请提供此答案,它将完全用于其他人。
    func textViewDidChange(textView: UITextView) {
    
        textView.sizeToFit()
        textView.layoutIfNeeded()
    
    }