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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16953610/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:49:05  来源:igfitidea点击:

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

iosobjective-cuiscrollview

提问by jake9115

I have a simple view containing a long view with many buttons, with the whole thing being in a UIScrollView. The scrollerworks well, and I can scrollto the bottom and click a button. Every buttontriggers a modal seque toanother view. That new viewis then dismissed by user interaction, causing the original UIScrollView's viewto load again.

我有一个简单的视图,其中包含一个带有许多按钮的长视图,整个视图都在一个UIScrollView. 该scroller工作得很好,我可以scroll在底部和点击button。Everybutton触发一个模态seque toanother viewview然后用户交互取消那个新的,导致原始的UIScrollView's view再次加载。

Here's the problem: If I click on a button toward the top of the UIScrollView, I enter the modal segue, dismiss the new view, and return to the UIScrollView's viewwithout a problem. But, if I click on one of the buttons toward the bottom of the UIScrollView, when I return sequeout and then transition back, my scrolling is all messed up. I can only see the area beneathmy scroller, and can't scrollback up to the top anymore!

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

I'm pretty sure there must be some way to reset the UIScrollView'sstarting and ending points upon ViewWillAppear, but I can't figure it out. Any help is appreciated!

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

Also, FYI, I simply added the UIScrollViewthrough interface builder, and haven't implemented or synthesized it anywhere yet.

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

回答by kirti Chavda

try this code:

试试这个代码:

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

回答by Christopher Wade Cantley

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.

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

回答by Mark Amery

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).

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

The behaviour being exhibited here is a bug in the UIScrollViewclass. As noted by the OP, after returning from a modally presented UIViewControllerto a scene containing a UIScrollView, the UIScrollViewtakes 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.

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

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 contentOffsetof 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 afterthe UIScrollViewis redisplayed you can set the contentOffsetback to whatever it was before you reset it.

您可以通过将contentOffset滚动视图的 设置回{0,0}在关闭模式视图控制器后再次显示之前来解决此问题。如果您真的想保留用户在触发模态之前滚动到的点,那么UIScrollView重新显示之后,您可以将contentOffset返回设置为重置之前的任何值。

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

这是一个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

If you'd rather do this in a UIViewControllerthan in a UIScrollViewsubclass, change the content offset in the viewWillAppear:and viewDidAppearmethods.

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

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 UIScrollViewback to the top, as the OP asked for, then all you need is the even simpler:

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

回答by Micho

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

回答by Anooj VM

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

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

Declare "scrollPosition" variable as CGPoint type.

将“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;
}

回答by Venkat S. Rao

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

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