14

我有一个简单的视图,其中包含一个带有许多按钮的长视图,整个视图都在UIScrollView. scroller效果很好,我可以到底scroll部并单击button. 每一个都会button触发seque to另一个模态view。然后新view的被用户交互解除,导致原件UIScrollView's view再次加载。

这就是问题所在:如果我单击顶部的按钮UIScrollView,我会进入 modal segue,关闭 new ,然后毫无问题view地返回到modal 。UIScrollView's view但是,如果我单击底部的按钮之一UIScrollView,当我返回seque然后过渡回来时,我的滚动就会一团糟。我只能看到下面scroller的区域,不能再scroll回到顶部了!

我很确定必须有某种方法可以重置UIScrollView's起点和终点ViewWillAppear,但我无法弄清楚。任何帮助表示赞赏!

另外,仅供参考,我只是添加了UIScrollView通过接口构建器,还没有在任何地方实现或合成它。

4

6 回答 6

30

试试这个代码:

- (void)viewWillAppear:(BOOL)animated
{
  [yourscrollview setContentOffset:CGPointZero animated:YES];
}
于 2013-06-06T04:53:59.683 回答
4

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

这里展示的行为是UIScrollView类中的一个错误。正如 OP 所指出的,在从模态呈现UIViewController的场景返回到包含 a 的场景后UIScrollView,它UIScrollView会采用它当前滚动到的任何点并开始表现得好像那是它的起源。这意味着如果您在模态显示另一个视图控制器之前向下滚动滚动视图,则在返回带有滚动视图的场景时无法向上滚动。

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

您可以通过在关闭模式视图控制器后将contentOffset滚动视图设置回{0,0}它再次显示之前来解决此问题。如果您确实想保留用户在触发模态之前滚动到的点,那么重新显示之后,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

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

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

@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
于 2013-08-24T16:30:18.940 回答
4

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

这是 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)
于 2015-04-22T18:08:56.763 回答
2

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];   
}
于 2013-10-07T03:14:16.000 回答
0

您可以通过调用scrollRectToVisible:animated:来更改起点和终点。但我不确定这是否能解决您的问题。

于 2013-06-06T04:43:52.747 回答
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;
}
于 2014-09-25T06:08:45.037 回答