Auto Scrolling UITextView Problem

2019-08-25 01:46发布

I am trying to auto scroll my text view and reset it to the top once it's arrived at the end.

I use this code:

-(void)scrollTextView
{

    CGPoint scrollPoint = stationInfo.contentOffset; 

    scrollPoint = CGPointMake(scrollPoint.x, scrollPoint.y + 2);

    if (scrollPoint.y == originalPoint.y + 100)
    {
        NSLog(@"Reset it");

        scrollPoint = CGPointMake(originalPoint.x, originalPoint.y);
        [stationInfo setContentOffset:scrollPoint animated:YES];

        [scroller invalidate];
        scroller = nil;

        scroller = [NSTimer
                    scheduledTimerWithTimeInterval:0.1
                    target:self
                    selector:@selector(scrollTextView)
                    userInfo:nil
                    repeats:YES];

    }
    else
    {
        [stationInfo setContentOffset:scrollPoint animated:YES];
    }

}

As a result, the text view jumps around wildly, but I don't quite know why. Is there maybe a better way of detecting that the text view is at the bottom? Am I setting the the scrollPoint value wrong?

Edit:

ISSUE SOLVED! I stuck to NSTimer - the missing key was calling -display for the layer.

    -(void)scrollTextView
    {
        //incrementing the original point to get movement
        originalPoint = CGPointMake(0, originalPoint.y + 2);
        //getting the bottom
        CGPoint bottom = CGPointMake(0, [stationInfo contentSize].height);
        //comparing the two to detect a reset
        if (CGPointEqualToPoint(originalPoint,bottom) == YES) 
        {
            NSLog(@"Reset");
            //killing the timer
            [scroller invalidate];
            scroller == nil;
            //setting the reset point
            CGPoint resetPoint = CGPointMake(0, 0);
            //reset original point
            originalPoint = CGPointMake(0, 0);
            //reset the view.
            [stationInfo setContentOffset:resetPoint animated:YES];
            //force display
            [stationInfo.layer display];

            scroller = [NSTimer
                        scheduledTimerWithTimeInterval:0.1
                        target:self
                        selector:@selector(scrollTextView)
                        userInfo:nil
                        repeats:YES];
        }
        else
        {   
            [stationInfo setContentOffset:originalPoint animated:YES];
        }


}

1条回答
啃猪蹄的小仙女
2楼-- · 2019-08-25 02:09

You could also use CoreAnimation and animate the bounds property directly. First animate the scrolling, then in the delegate callback that the animation has finished you reset the content offset.

The callback method has to have the signature

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context

You could also use the new block-based methods if you are targeting iOS 4.0 and above. Then there are two blocks to be passed: in the first one you specify what to animate and in the second what to do when the animation is over.

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

Your problem than collapses into a single line of code:

[stationInfo animateWithDuration:10.f delay:0.f options:0 animations:^{
    [stationInfo setContentOffset:CGPointMake(0, [stationInfo contentSize].height)];
} completion:^(BOOL finished){
    if (finished) [stationInfo setContentOffset:CGPointMake(0,0)];
}];

To be honest I am not 100% sure about the precise block syntax but this is how it should work.

查看更多
登录 后发表回答