如果在viewWillAppear中调用scrollToItemAtIndexPath,则在UICollectionView上未更新contentOffset

Rei*_*ain 22 ios uicollectionview

我有一个UICollectionView用于模拟iOS 7中的新日历.此集合视图位于具有selectedDate属性的控制器内.每当设置selectedDate属性时,集合视图应滚动到集合视图中的日期.

日历控制器的viewWillAppear还确保所选日期可见,因为此控制器已缓存并重复使用.

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

    [self.calendarView scrollToDate:[self selectedDate] animated:NO];
}
Run Code Online (Sandbox Code Playgroud)

问题是,第一次显示日历控制器时滚动不起作用.集合视图的contentOffset未更新.

我目前的解决方法是使用安排滚动在下一个运行循环中进行

dispatch_after(DISPATCH_TIME_NOW, dispatch_get_main_queue(), ^(void)
{
        // Scroll to the date.
    });
Run Code Online (Sandbox Code Playgroud)

看起来当UICollectionView不在窗口中时,您无法滚动.将滚动调度到下一个运行循环,确保视图已添加到窗口并可以正确滚动.

还有其他人遇到过这个问题以及他们的解决方法吗?

bil*_*tum 22

如果您使用自动布局,问题可能是约束尚未设置帧.尝试在viewDidLayoutSubviews中调用scrollToDate:方法(不带dispatch_after).

@interface CustomViewController ()

@property (nonatomic) BOOL isFirstTimeViewDidLayoutSubviews; // variable name could be re-factored

@property (nonatomic, weak) IBOutlet UIScrollView *scrollView;

@end

@implementation CustomViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.isFirstTimeViewDidLayoutSubviews = YES;
}

- (void)viewDidLayoutSubviews
{
    // only after layoutSubviews executes for subviews, do constraints and frames agree (WWDC 2012 video "Best Practices for Mastering Auto Layout")

    if (self.isFirstTimeViewDidLayoutSubviews) {

        // execute geometry-related code...

        // good place to set scroll view's content offset, if its subviews are added dynamically (in code)

        self.isFirstTimeViewDidLayoutSubviews = NO;
    }
Run Code Online (Sandbox Code Playgroud)


max*_*wer 20

您可以随时强制自动布局布局.

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.view.layoutIfNeeded()
    self.collectionView.scrollToItemAtIndexPath......
}
Run Code Online (Sandbox Code Playgroud)