Ios 如何重置我的UIScrollView';从模式转换返回后的位置?

Ios 如何重置我的UIScrollView';从模式转换返回后的位置?,ios,objective-c,uiscrollview,Ios,Objective C,Uiscrollview,我有一个简单的视图,其中包含一个带有许多按钮的长视图,整个视图都位于UIScrollView中。滚动条工作正常,我可以滚动到底部并单击按钮。每个按钮都会触发一个模式序列另一个视图。新的视图随后被用户交互取消,导致原始的UIScrollView视图再次加载 问题是:如果我单击UIScrollView顶部的按钮,我将进入模式segue,关闭新的视图,然后毫无问题地返回到UIScrollView的视图。但是,如果我点击UIScrollView底部的一个按钮,当我返回seque并返回时,我的滚动都是乱七

我有一个简单的视图,其中包含一个带有许多按钮的长视图,整个视图都位于
UIScrollView
中。
滚动条
工作正常,我可以
滚动
到底部并单击
按钮
。每个
按钮
都会触发一个模式
序列
另一个
视图
。新的
视图
随后被用户交互取消,导致原始的
UIScrollView视图
再次加载

问题是:如果我单击
UIScrollView
顶部的按钮,我将进入模式
segue
,关闭新的
视图
,然后毫无问题地返回到
UIScrollView的视图
。但是,如果我点击
UIScrollView
底部的一个按钮,当我返回
seque
并返回时,我的滚动都是乱七八糟的。我只能看到我的
滚动条下的区域
,无法
滚动
回到顶部

我很确定一定有办法在
视图出现时重置
UIScrollView的
起点和终点,但我想不出来。感谢您的帮助


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

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

请尝试以下代码:

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

    [self.scrollview scrollRectToVisible:CGRectMake(0, 0, 1, 1)
                                animated:NO];   
}
请注意:这个问题和答案所涉及的bug在iOS 7中似乎已经修复。这个答案的其余部分仅与iOS 6相关(可能更早)。 这里展示的行为是
UIScrollView
类中的一个bug。正如OP所指出的,在从模式呈现的
UIViewController
返回到包含
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
如果您更愿意在
UIViewController
中执行此操作,而不是在
UIScrollView
子类中执行此操作,请更改
视图中的内容偏移量将出现:
viewdideaked
方法

如果您不想在用户从模式返回时保留其滚动位置,而只想按照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

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

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

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

使用下面的代码段恢复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;
}

首先,感谢您提供上述经批准的答案。有人提到它不再适用,但我在table view单元格中有一个滚动视图,当单元格被重用时,它需要重置

以下是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)

您是否已初始化您的滚动视图,视图将出现,如果是,则将代码放在viewdidload中,因为当您取消一个视图时,它的视图将显示为Call。您可以在您描述的场景中发布您当前的代码或它前后的一些屏幕截图吗?@Isaahnelson复制大约需要5分钟,如果您感兴趣的话。使用故事板创建新项目。初始
UIViewController
包含一个长滚动视图(足够高,必须滚动),顶部有一个标签,底部有一个按钮,触发到第二个VC的序列。第二个VC有一个按钮,该按钮有一个操作,该操作将关闭第二个VC(这是重新编程所需的唯一代码行)。在模拟器中运行。向下滚动。单击第一个按钮。单击第二个按钮。Boom-在第一个VC中,你不能再向上滚动到
UIScrollView
的顶部。答案很好。非常感谢@kirti mali.Swift3:yourscrollview.setContentOffset(CGPoint.zero,动画:true)如果我们使用navigationcontroller怎么办?@GajendraKChauhan:上面的代码将与navigationcontroller一起工作