iOS 8.4:滚动视图重置 contentOffset 并在视图出现后不久启用 Voice Over

Posted

技术标签:

【中文标题】iOS 8.4:滚动视图重置 contentOffset 并在视图出现后不久启用 Voice Over【英文标题】:iOS 8.4: Scroll view resets contentOffset with Voice Over enabled shortly after view appear 【发布时间】:2016-01-14 15:21:52 【问题描述】:

启用 Voice Over 后,滚动视图会在视图出现后一秒重置其预设 contentOffset。它发生在 ios 8.4 设备上,9.0 没有复制。看起来一些内部UIScrollViewAccessibility 代码强制滚动视图到setContent: 为零时成为焦点。没有找到任何逃避的方法。

有什么想法吗?

相关代码示例说明了该错误。 只需创建一个带有集合视图的视图,创建一个重用 id 为“Cell”的单元格并在其上放置一个标签。

@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

【问题讨论】:

【参考方案1】:

这是故意的。如果用户使用滑动手势进行导航。如果您导航到滚动视图,则视图中的第一个元素应该是焦点。对于有视力的 VoiceOver 用户,显然不向上滚动到顶部会很不协调,因为您的焦点矩形可能会离开屏幕。这是一项功能,而不是错误。

【讨论】:

好吧,如果这是一项功能,那么为什么 iOS 9.x 中没有它?再次获得焦点时它也不会滚动到开始,仅在第一个视图出现 作为一名残疾用户,您不希望每次都在焦点上发生这种情况。如果您从视图中移除焦点并返回,您会期望视图在您离开它的位置(参见 WCAG 2.0)。功能确实会因操作系统而异。否则不会有 9.x。 @ChrisCM 你能看看***.com/users/1046037/user1046037,每次都发生在我身上。问题有时会隐藏在叠加层下 这似乎没有链接到问题,而是链接到您的个人资料...?

以上是关于iOS 8.4:滚动视图重置 contentOffset 并在视图出现后不久启用 Voice Over的主要内容,如果未能解决你的问题,请参考以下文章

滚动其他滚动视图时滚动视图重置

iOS 8.4 - iboutlet 未填充到以编程方式创建的视图控制器中

向上滚动时,Textview 重置为旧值

SwiftUI List 在任何视图更改时重置滚动

滚动浏览集合视图时重置按钮和标签

如何在滚动视图中重置文本字段