在 iOS 7 中滚动到 UITextView 不稳定的底部

2022-01-12 00:00:00 ios ios7 uiscrollview uitextview

以下代码在 iOS 中可以正常工作

7.0.在 iOS 7 中,当 UITextView 更新时,滚动会断断续续且不稳定.我不确定这是否是 iOS 7 中的错误,或者我做错了什么.

The following code will work fine in iOS < 7.0. In iOS 7 the scrolling will be choppy and erratic while the UITextView is updating. I'm not sure if this is a bug in iOS 7, or I am doing something wrong.

TestController.h

//TODO: Add UITextView in storyboard and tie to textView outlet

#define MAX_TEXT_VIEW_CHARACTERS 1000
@interface TestController : UIViewController  {
    NSMutableString *_outputText;
    NSTimer *_outputTimer;
}

@property (strong, nonatomic) IBOutlet UITextView *textView;

@end

TestController.m

@implementation TestController
@synthesize textView;

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    _outputText = [NSMutableString stringWithCapacity:MAX_TEXT_VIEW_CHARACTERS];
    _outputTimer =  [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(outputLine:) userInfo:nil repeats:YES];
}

-(void)outputLine:(NSTimer *) theTimer {
    static int i = 0;
    //Run this 100 times
    if (i > 99) {
        [_outputTimer invalidate];
        return;
    }
    [self outputToScreen:[NSString stringWithFormat:@"Some string %d", ++i]];
}

-(void)outputToScreen:(NSString *)str {
    if (!str || !str.length) return;  //Nothing to output

    NSInteger outputTextSize = _outputText.length;
    [_outputText appendString:str];
    if (outputTextSize > MAX_TEXT_VIEW_CHARACTERS)
        [_outputText deleteCharactersInRange:NSMakeRange(0, outputTextSize - MAX_TEXT_VIEW_CHARACTERS)];
    self.textView.text = _outputText;

    [self scrollOutputToBottom];
}

-(void)scrollOutputToBottom {
    CGPoint p = [textView contentOffset];
    [textView setContentOffset:p animated:NO];
    [textView scrollRangeToVisible:NSMakeRange([textView.text length], 0)];
}

@end

推荐答案

这显然是 iOS 7 的 bug.这是一个解决方法,直到苹果修复它.解决方法基本上是通过从头开始创建 NSTextStorageNSLayoutManager 来实例化 UITextView.苹果一定是忘记在 UITextView 初始化方法中进行初始化了.我提交了错误报告,希望你也这样做.

This is obviously an iOS 7 bug. Here is a workaround until apple fixes it. The workaround is basically instantiates a UITextView by creating an NSTextStorage and NSLayoutManager from scratch. Apple must have forgotten to initialize something in UITextView initialization method. I filed a bug report and I hope you do too.

// ios7 bug fix
// check if the device is running iOS 7.0 or later
NSString *reqSysVer = @"7.0";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
BOOL osVersionSupported = ([currSysVer compare:reqSysVer  options:NSNumericSearch] != NSOrderedAscending);

if (osVersionSupported) {
    NSTextStorage* textStorage = [[NSTextStorage alloc] init];
    NSLayoutManager* layoutManager = [NSLayoutManager new];
    [textStorage addLayoutManager:layoutManager];
    NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:self.view.bounds.size];
    [layoutManager addTextContainer:textContainer];
    yourTextView = [[UITextView alloc] initWithFrame:someFrameForYourTextView
                                       textContainer:textContainer];
    // if using ARC, remove these 3 lines
    [textContainer release];
    [layoutManager release];
    [textStorage release];
}
else {
    yourTextView = [[UITextView alloc] initWithFrame:someFrameForYourTextView];
}

相关文章