How to reset my UIScrollView's position after returning from a modal transition?

前端 未结 6 850
-上瘾入骨i
-上瘾入骨i 2021-02-07 12:46

I have a simple view containing a long view with many buttons, with the whole thing being in a UIScrollView. The scroller works well, and I can s

相关标签:
6条回答
  • 2021-02-07 13:00

    To solve this problem i use this code:

    -(void) viewWillAppear:(BOOL)animated{
        [super viewWillAppear:animated];
    
        [self.scrollview scrollRectToVisible:CGRectMake(0, 0, 1, 1)
                                    animated:NO];   
    }
    
    0 讨论(0)
  • 2021-02-07 13:03

    try this code:

    - (void)viewWillAppear:(BOOL)animated
    {
      [yourscrollview setContentOffset:CGPointZero animated:YES];
    }
    
    0 讨论(0)
  • 2021-02-07 13:03

    First, thanks for the approved answer above. Someone mentioned that it was no longer applicable but I have a scrolling view inside of table view cell and it needs to be reset when the cell is reused.

    Here is the solution in Swift.

    @IBOutlet var scrollView: UIScrollView!
    
    // many lines of code later inside a function of some sort...
    
    scrollView.setContentOffset(CGPointMake(0.0, 0.0), animated: false)
    
    0 讨论(0)
  • 2021-02-07 13:11

    Please note: the bug this question and answer is about appears to be fixed in iOS 7. The rest of this answer is only relevant to iOS 6 (and probably earlier).

    The behaviour being exhibited here is a bug in the UIScrollView class. As noted by the OP, after returning from a modally presented UIViewController to a scene containing a UIScrollView, the UIScrollView takes whatever point it's currently scrolled to and starts behaving as though that is its origin. That means that if you'd scrolled down your scroll view before modally presenting another View Controller, you can't scroll back up upon returning to the scene with the scroll view.

    The same thing happens when you remove the Scroll View from the view hierarchy and re-add it, even without changing its window.

    You can work around this by setting the contentOffset of the scroll view back to {0,0} before it gets displayed again after dismissing the modal View Controller. If you actually want to preserve the point the user had scrolled to before they triggered the modal, then after the UIScrollView is redisplayed you can set the contentOffset back to whatever it was before you reset it.

    Here's a UIScrollView subclass that fixes the bug without resetting the scroll view to the top whenever you return from a modal:

    @interface NonBuggedScrollView : UIScrollView
    
    @end
    
    @implementation NonBuggedScrollView {
        CGPoint oldOffset;
    }
    
    -(void)willMoveToWindow:(UIWindow *)newWindow {
        oldOffset = self.contentOffset;
        self.contentOffset = CGPointMake(0,0);
    }
    
    -(void)willMoveToSuperview:(UIView *)newSuperview {
        oldOffset = self.contentOffset;
        self.contentOffset = CGPointMake(0,0);
    }
    
    -(void)didMoveToWindow {
        self.contentOffset = oldOffset;
    }
    
    -(void)didMoveToSuperview {
        self.contentOffset = oldOffset;
    }
    
    @end
    

    If you'd rather do this in a UIViewController than in a UIScrollView subclass, change the content offset in the viewWillAppear: and viewDidAppear methods.

    If you don't want to preserve where the user's scroll position when they return from a modal, and just want to scroll the UIScrollView back to the top, as the OP asked for, then all you need is the even simpler:

    @interface NonBuggedScrollView : UIScrollView
    
    @end
    
    @implementation NonBuggedScrollView
    
    -(void)willMoveToWindow:(UIWindow *)newWindow {
        self.contentOffset = CGPointMake(0,0);
    }
    
    -(void)willMoveToSuperview:(UIView *)newSuperview {
        self.contentOffset = CGPointMake(0,0);
    }
    
    
    @end
    
    0 讨论(0)
  • 2021-02-07 13:16

    Use below code snippet to restore the scroll position for a UIScrollview

    Declare "scrollPosition" variable as CGPoint type.

    - (void)viewDidDisappear:(BOOL)animated 
    {
        [super viewDidDisappear:animated];
        //get the current offset
        scrollPosition = scrollView.contentOffset;
    
        //set current view to the beginning point
        self.scrollView.contentOffset = CGPointZero;
    }
    
    - (void)viewDidLayoutSubviews 
    {
        [super viewDidLayoutSubviews];
        //retrieve the previous offset
        self.scrollView.contentOffset = scrollPosition;
    }
    
    0 讨论(0)
  • 2021-02-07 13:21

    You can change the starting and ending points by calling scrollRectToVisible:animated:. But I'm not sure if this fixes your problem.

    0 讨论(0)
提交回复
热议问题