With Voice Over enabled scroll views reset their preset contentOffset a second after view did appear. It happens on iOS 8.4 devices, no reproduction for 9.0. Looks some internal UIScrollViewAccessibility
code forces scroll view to setContent:
for zero when becoming focused. Didn't find any way to evade this.
Any thoughts?
Related code sample illustrates the bug. Just create a view with collection view, create a cell with reuse id "Cell" and put a label on it.
@interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>
@property (nonatomic, weak) IBOutlet UICollectionView *collectionView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.collectionView.backgroundColor = [UIColor clearColor];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.collectionView reloadData];
//set there 4 seconds and bug will disappear
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:5 inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
});
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
NSLog(@"Why you scroll second time?");
}
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return self.view.bounds.size;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 10;
}
- (UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
UILabel *label = (UILabel*)cell.contentView.subviews[0];
label.text = @(indexPath.item + 1).stringValue;
if (indexPath.item == 5) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, label);
});
}
return cell;
}
@end
It's doing this intentionally. If users are using swipe gestures to navigate. If you navigate into a scroll view, the first element in the view should be focused. For sighted VoiceOver users, obviously not scrolling up to the top would be jarring, as potentially your focus rectangle could be off screen. This is a feature, not a bug.
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