I have a UICollectionView that is used to simulate the new calendar in iOS 7. This collection view is inside a controller that has a selectedDate property. Whenever the selectedDate property is set the collection view should scroll to the date in the collection view.
The calendar controller's viewWillAppear also ensure the selected date is visible because this controller is cached and reused.
-(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.calendarView scrollToDate:[self selectedDate] animated:NO]; }
The problem is that the VERY first time the calendar controller is shown the scroll does not work. The contentOffset of the collection view is not updated.
My current workaround is to schedule the scroll to occur on the next run loop using
dispatch_after(DISPATCH_TIME_NOW, dispatch_get_main_queue(), ^(void) { // Scroll to the date. });
It looks like when the UICollectionView is not in a window you cannot scroll. Scheduling the scroll to happen on the next run loop ensure that the view has been added to the window and can be properly scrolled.
Has anyone else experienced this issue and what their workarounds?
If you are using auto layout, the issue may be that the constraints haven't set the frames yet. Try calling the scrollToDate: method in viewDidLayoutSubviews (without 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; }
you can always force auto-layout to layout.
override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) self.view.layoutIfNeeded() self.collectionView.scrollToItemAtIndexPath...... }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With