UITextView在粘贴文本时可视地改变内容位置

时间:2012-05-31 03:31:34

标签: iphone objective-c ios uitextview

我有一个UITextView,它可以在需要时放大以适应contentView。但是,当我粘贴一段文本时,它会将内容的起点和终点垂直放在错误的位置。输入或删除字符会将其重置回正确的位置。

为什么会这样?

-(void)textViewDidChange:(UITextView *)textView {
    self.textView.frame = CGRectMake(
        self.textView.frame.origin.x,
        self.textView.frame.origin.y,
        self.textView.frame.size.width,
        self.textView.contentSize.height + HEADER_ADDITIONAL_HEIGHT);

    self.textView.contentOffset = CGPointMake(0, 0);

    self.previousContentSize = textView.contentSize;
}

2 个答案:

答案 0 :(得分:1)

我用的时候:

textView.contentSize = textView.frame.size;  
textView.contentOffset = CGPointZero;  

它解决了我的问题,但创建了一个新问题,我们有时会在键入或删除文本时进行奇怪的滚动。所以,我用过这个:

textView.contentSize = CGSizeMake( textView.contentSize.width,
                                   textView.contentSize.height+1);  

这也解决了这个问题。我认为我们在这里需要的是每当textview的contentSize发生变化时我们得到的效果。不幸的是,我不知道这是什么影响。如果有人知道,请告诉。

更新: 我找到了一个方法,你可以用来解决你的问题(我用它来解决我的问题)。 您可以要求NSLayoutMAnager刷新整个布局:

[textView.textStorage edited:NSTextStorageEditedCharacters range:NSMakeRange(0, textView.textStorage.length) changeInLength:0];

NSLayoutManager尝试避免刷新布局,因为它耗时并且需要大量工作,所以它设置为仅在绝对必要时(懒惰地)执行。 有许多与此类相关的invalidateLayout函数,但在调用时它们都不会导致实际的重新布局。

答案 1 :(得分:-1)

我知道这件事迟到了,但我遇到了这个问题并且认为我应该分享我想出来的事情以防其他人发现自己处于相同的情况。

你走在正确的轨道上,但在textViewDidChange:中你缺少一件重要的事情:在更新帧高后设置contentSize。

// I used 0.f for the height, but you can use another value because according to the docs:
//  "the actual bounding rectangle returned by this method can be larger 
//    than the constraints if additional space is needed to render the entire 
//    string. Typically, the renderer preserves the width constraint and 
//    adjusts the height constraint as needed."
CGSize size = CGSizeMake(textview.frame.size.width, 0.f);
CGRect rect = [string boundingRectWithSize:size
                                   options:OptionsYouNeedIfAny // NSStringDrawingOptions
                                   context:nil];

// Where MinTextViewHeight is the smallest height for a textView that 
//   your design can handle
CGFloat height = MAX(ceilf(rect.size.height), MinTextViewHeight); 
CGRect rect = textView.frame;
rect.size.height = height;
textView.frame = rect;

// Adjusting the textView contentSize after updating the frame height is one of the things you were missing
textView.contentSize = textView.frame.size;
textView.contentOffset = CGPointZero;

我希望这有帮助!

See the docs了解有关使用boundingRectWithSize:options:context:的更多信息。