iOS 7上的UITextView contentOffset

时间:2013-10-01 11:41:02

标签: iphone uitextview ios7

我的应用中有一个UITextView。每次添加新字符串时,我都需要动态更改内容偏移量。代码bellow在iOS 6及更早版本上运行良好,但在iOS 7上运行不正常。

CGPoint offset = CGPointMake(0, self.textView.contentSize.height - self.textView.frame.size.height);
[self.textView setContentOffset:bottomOffset animated:YES]; 

你有什么想法吗?

比你。

更新

UITextView没有设置它应该的contentOffset,或者其他东西弄乱了它。结果与预期不符(iOS 6或更早版本的版本)。

我也尝试过设置新属性“textContainerInset”,但仍然没有结果......

self.textView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0)    

更新

正如我在didScroll委托方法中看到的,当我传递内容偏移的正值时,它会滚动到(0,0)。例如,我将内容偏移设置为(0,35),并滚动到(0,0)...

6 个答案:

答案 0 :(得分:8)

我发现的解决方案根本不优雅,但它有效:

在将UITextView的contentOffset设置为所需的偏移量之前,我将其设置为(0,0)。我不知道为什么会这样,但现在是我找到的最佳解决方案。

CGPoint bottomOffset = CGPointMake(0, self.textView.contentSize.height - self.textView.frame.size.height);
[self.textView setContentOffset: CGPointMake(0,0) animated:NO]; 
[self.textView setContentOffset:bottomOffset animated:YES]; 

答案 1 :(得分:5)

我今天才注意到。在我的情况下,问题显然与文本视图是视图中的第一个控件有关。我把它移到文档大纲中的第二位(例如在UILabel之后)并且偏移消失了。

由于iOS7中的导航栏新行为,这很可能是故意这样做的。

答案 2 :(得分:4)

好的,根据我的研究和其他答案,问题是UITextView的内容高度,而不是滚动到特定的偏移量。这是一个解决方案,它的工作方式应该适用于iOS 7:

首先,您需要像这样重新创建UITextView

    NSString *reqSysVer = @"7.0";
    NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
    BOOL osVersionSupported = ([currSysVer compare:reqSysVer  options:NSNumericSearch] != NSOrderedAscending);

    if (osVersionSupported) {

        NSLog(@"reset chatoutput");

        CGRect outputFrame = self.chatOutput.frame;

        [chatOutput removeFromSuperview];
        [chatOutput release];
        chatOutput = nil;

        NSTextStorage* textStorage = [[NSTextStorage alloc] init];
        NSLayoutManager* layoutManager = [NSLayoutManager new];
        [textStorage addLayoutManager:layoutManager];
        NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:self.view.bounds.size];
        [layoutManager addTextContainer:textContainer];
        chatOutput = [[UITextView alloc] initWithFrame: outputFrame
                                           textContainer: textContainer];
        // if using ARC, remove these 3 lines
        [textContainer release];
        [layoutManager release];
        [textStorage release];

        [self.view addSubview: chatOutput];
    }

然后,使用此方法获取UITextView内容高度:

- (CGFloat)textViewHeightForAttributedText:(NSAttributedString*)text andWidth:(CGFloat)width
{
     UITextView *calculationView = [[UITextView alloc] init];
     [calculationView setAttributedText:text];
     CGSize size = [calculationView sizeThatFits:CGSizeMake(width, FLT_MAX)];

     NSLog(@"size: %f", size.height) ;

     return size.height;
}

现在您可以设置内容偏移量:

CGPoint bottomOffset;

bottomOffset = CGPointMake(0, [self textViewHeightForAttributedText: self.chatOutput.attributedText andWidth: self.chatOutput.frame.size.width] - self.chatOutput.frame.size.height);

[self.chatOutput setContentOffset:bottomOffset animated:YES];

<强>更新

我在Apple文档中已经为NSAttributedString阅读了这篇文章: “NSAttributedString对象的默认字体是Helvetica 12-point,这可能与平台的默认系统字体不同。”

总之,如果您使用不同大小的不同字体,则必须将它们设置为NSAttributeString实例。否则,返回的高度将与您的预期不符。你可能想要使用这样的东西:

    NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObject: [UIFont systemFontOfSize: 18.0] //or any other font or size
                                                                forKey: NSFontAttributeName];
    NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString: currentPost.postMessageText attributes: attrsDictionary];
    frame.size.height = [self textViewHeightForAttributedText: attributedString andWidth: 280.0];
    [attributedString release];

答案 3 :(得分:2)

@ vidonism的answer有效但这更好。

// in -viewDidLoad of UIViewController
self.automaticallyAdjustsScrollViewInsets = NO;

另请参阅此question上接受回答的热门评论。这可能解释了UIScrollView作为ViewController主视图的第一个子视图的行为 如果这是预期的行为或错误,我不会完全不清楚。

答案 4 :(得分:0)

我不得不求助于

[displayText scrollRangeToVisible:NSMakeRange([displayText.text length], 0)];

但是它的大问题是它从文本的顶部开始并在每次附加到文本时滚动到结尾。 Mihai的解决方案也是如此。

答案 5 :(得分:0)

以前的答案都不适合我,因为我有[textView setScrollEnabled:NO]。所以,我最终得到了这个:

[textView setScrollEnabled:YES]
[self.text setContentOffset:CGPointMake(0, page * self.text.frame.size.height) animated:NO];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [self.text setScrollEnabled:NO];
});