如何从模态转换返回后重置我的UIScrollView的位置?

时间:2013-06-06 04:17:11

标签: ios objective-c uiscrollview

我有一个包含许多按钮的长视图的简单视图,整个事情都在UIScrollViewscroller效果很好,我可以scroll到底部并点击button。每个button触发一个模态seque to另一个view。然后,新的view被用户互动关闭,导致原始UIScrollView's view再次加载。

问题在于:如果我点击UIScrollView顶部的按钮,我会输入模态segue,关闭新的view,然后返回{{1}没有问题。但是,如果我单击UIScrollView's view底部的其中一个按钮,当我返回UIScrollView然后转回时,我的滚动就会搞砸了。我只能在<{1}} 下面看到区域,并且seque不能再回到顶部了!

我很确定必须有某种方法可以在scroller上重置scroll起点和终点,但我无法弄明白。任何帮助表示赞赏!

另外,仅供参考,我只是通过界面构建​​器添加了UIScrollView's,并且尚未在任何地方实现或合成它。

6 个答案:

答案 0 :(得分:27)

试试这段代码:

- (void)viewWillAppear:(BOOL)animated
{
  [yourscrollview setContentOffset:CGPointZero animated:YES];
}

答案 1 :(得分:4)

请注意:这个问题和答案的错误似乎在iOS 7中得到修复。此答案的其余部分仅与iOS 6(可能更早)相关。

此处展示的行为是UIScrollView类中的错误。正如OP所指出的那样,在从模态呈现的UIViewController返回到包含UIScrollView的场景之后,UIScrollView将获取当前滚动到的任何点并开始表现,就像它的起源一样。这意味着如果您在以模态方式呈现另一个视图控制器之前向下滚动滚动视图,则在使用滚动视图返回场景时无法向上滚动。

当您从视图层次结构中删除Scroll View并重新添加它时,即使不更改其窗口,也会发生同样的事情。

您可以通过将滚动视图的contentOffset设置回{0,0}来解决此问题,然后再解除模态View Controller后再次显示它。如果你真的想要保留用户在触发模态之前滚动到的点,那么在重新显示 UIScrollView后,你可以将contentOffset设置回原来的状态在重置之前。

这是一个UIScrollView子类,可以修复错误,而无需在从模式返回时将滚动视图重置为顶部:

@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

如果您希望在UIViewController而不是UIScrollView子类中执行此操作,请更改viewWillAppear:viewDidAppear方法中的内容偏移量。

如果您不希望保留用户从模态返回时滚动位置的位置,并且只想按照OP要求将UIScrollView滚动回顶部,那么您需要的只是更简单:

@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

答案 2 :(得分:3)

首先,感谢上面批准的答案。有人提到它已不再适用,但我在表格视图单元格中有一个滚动视图,需要在重复使用单元格时重置它。

这是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)

答案 3 :(得分:2)

要解决此问题,请使用以下代码:

-(void) viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];

    [self.scrollview scrollRectToVisible:CGRectMake(0, 0, 1, 1)
                                animated:NO];   
}

答案 4 :(得分:0)

您可以致电scrollRectToVisible:animated:更改起点和终点。但我不确定这是否可以解决您的问题。

答案 5 :(得分:0)

使用下面的代码段恢复UIScrollview的滚动位置

将“scrollPosition”变量声明为CGPoint类型。

- (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;
}