16

我的应用程序中有一个 UITextView。每次添加新字符串时,我都需要动态更改它的内容偏移量。下面的代码在 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)...

4

6 回答 6

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]; 
于 2013-10-02T12:42:43.453 回答
5

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

这很可能是故意的,因为 iOS7 中导航栏的新行为。

于 2014-03-10T10:11:16.530 回答
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];
于 2013-11-26T11:03:22.147 回答
2

@vidonism 的答案有效,但这更好。

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

另请参阅有关此问题的已接受答案的顶级评论。这可能解释了 UIScrollView 作为 ViewController 主视图的第一个子视图的行为。
如果这是预期的行为或错误,我无法完全辨别。

于 2014-07-15T23:52:11.610 回答
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];
});
于 2014-10-01T07:21:57.650 回答
0

I've had to resort to

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

but the BIG problem with it is that it starts from the top of the text and scrolls to the end each time you append to the text. Mihai's solution also does that.

于 2013-11-14T00:16:48.590 回答