【问题标题】:How do I keep scroll position when navigating in a navigation controller?在导航控制器中导航时如何保持滚动位置?
【发布时间】:2014-01-21 12:19:50
【问题描述】:

一直在环顾四周,但我没有找到对我有帮助的答案。我想知道当我在导航控制器中向前和向后移动时如何将滚动位置保持在滚动视图中。目前,当我转到导航控制器中的另一个视图时,滚动视图会重置并在我返回时位于顶部。任何代码将不胜感激。对不起,如果我的解释不够好。到目前为止,这就是我所拥有的,我知道这行不通,但是我该怎么办?

- (void)viewWillAppear:(BOOL)animated {
    scrollView.contentOffset.y = scrollSave;
    [super viewWillAppear:YES];
}

- (void)viewWillDisappear:(BOOL)animated {
    CGFloat scrollSave = scrollView.contentOffset.y;
    [super viewWillDisappear:animated];
}

【问题讨论】:

  • 首先将 [super viewWillAppear:YES] 方法放在 scrollView.contentOffset.y = scrollSave;其次,如果没有帮助,请尝试在 viewDidAppear 方法中执行此操作

标签: ios uiscrollview uinavigationcontroller


【解决方案1】:

您上面的代码甚至不应该编译。您可以将此滚动位置保存在另一个变量中,但通常滚动位置不应该自行重置。您应该完全删除任何试图操纵内容偏移的代码,并查看它是否在返回视图时将其恢复到正确的滚动位置。

【讨论】:

    【解决方案2】:

    使用您当前的方法,scrollSave 是在 viewWillDisappear 中声明的局部变量,因此您无法访问 viewWillAppear 中的值。您将需要创建一个实例变量或属性。 (如果视图控制器仍在内存中,它应该维护 contentOffset 所以这可能不是必需的

     @interface MyViewController ()
       @property (nonatomic) CGPoint scrollSave;
     @end
    
     @implementation MyViewController
     - (void)viewWillAppear:(BOOL)animated {
       [scrollView setContentOffset:self.scrollSave];
       [super viewWillAppear:YES];
     }
    
     - (void)viewWillDisappear:(BOOL)animated {
       self.scrollSave = scrollView.contentOffset;
       [super viewWillDisappear:animated];
     }
    

    现在存在持久性问题。如果你在导航控制器中导航回来,这个视图控制器将从内存中释放。如果您需要保存用户位置,那么我建议使用 NSUserDefaults。

     @interface MyViewController ()
       @property (nonatomic)  NSUserDefaults *defaults
     @end
    
     @implementation MyViewController
     - (void)viewWillAppear:(BOOL)animated { 
       CGPoint scrollSave = CGPointFromString([_defaults objectForKey:@"scrollSaveKey"]);
       scrollView.contentOffset = scrollSave;
       [super viewWillAppear:YES];
     }
    
     - (void)viewWillDisappear:(BOOL)animated {
       [_defaults setObject:NSStringFromCGPoint(scrollView.contentOffset) forKey:@"scrollSaveKey"];
       [_defaults synchronize];
       [super viewWillDisappear:animated];
     }
    

    【讨论】:

    • 如果我这样做,scrollView.contentOffset.y 是不可分配的
    • 没有理由保留 NSUserDefaults 的属性,顺便说一句,您的代码永远不会显示您设置它的位置。您可以随时通过调用 [NSUserDefaults standardUserDefaults] 来获取 NSUserDefaults,这是一个方法调用,但它的开销如此之小,这并不重要。而且您无论如何都不需要使用 NSUserDefaults 来保存保存的位置,因为如果视图控制器仍在导航堆栈上,它就不会被释放。事实上,在 iOS 6 和更高版本上,视图甚至不会在内存不足的情况下被释放。
    • 我注意到你说如果你向后导航,所以是的,在这种情况下你需要使用 NSUserDefaults 来持久化它,但问题是先前进然后后退,所以没关系无论如何。
    • @Gavin NSUserDefaults 属性纯粹是为了方便和美观。问题说“向前和向后移动”所以我在弹出视图控制器时采取了这种情况,如果VC仍在导航堆栈中,则绝对没有必要
    • @KyleC,这听起来像是在推动然后弹出另一个视图控制器时发生的。一般认为,如果有人后退再前进,他们前进的视图将被重置回顶部。
    【解决方案3】:

    Kyle 的回答应该让您可以存储变量,但关于分配 contentOffset.y,请尝试为滚动视图设置动画。

    [scrollView scrollRectToVisible:
    CGRectMake(scrollView.frame.origin.x, scrollSave.y, scrollView.frame.size.width, scrollView.frame.size.height) 
    animated:NO];
    

    该代码将进入 viewWillAppear。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多