滚动到集合视图中的项目会导致应用崩溃

 寒江大哥_599 发布于 2023-02-13 10:41

我想滚动到某个UICollectionView内部的某个项目viewWillAppear

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

    [collectionView_ scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:selectedIndex_ inSection:0]
                            atScrollPosition:UICollectionViewScrollPositionLeft
                                    animated:NO];
}

在iOS 6上,此代码崩溃了返回的应用程序

*** Assertion failure in -[UICollectionViewData layoutAttributesForItemAtIndexPath:], /SourceCache/UIKit_Sim/UIKit-2372/UICollectionViewData.m:485
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'must return a UICollectionViewLayoutAttributes instance from -layoutAttributesForItemAtIndexPath: for path  2 indexes [0, 2]'

在iOS7上,它不会崩溃但只是什么都不做.

滚动到正确的项目只能用于viewDidAppear但是我想在正确的项目中显示带有集合的屏幕.我试图滚动它viewDidLayoutSubviews但它也崩溃了.将呼叫包含在内部try-catch可以避免崩溃,但仍然无法正常工作.

这有什么意义?是否无法显示正确的项目?

非常感谢.

编辑1

我打印了这个viewWillAppearviewDidLayoutSubviews(selectedIndex_是2,该集合有10个项目):

UICollectionViewLayoutAttributes *test = [collectionView_ layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:selectedIndex_ inSection:0]];

结果就是这两个地方.

 index path: ( {length = 2, path = 0 - 2}); frame = (0 0; 0 0);

编辑2

这是contentSize该集合的痕迹I打印

2013-12-09 08:56:59.300 - didLoad {0, 0}
2013-12-09 08:56:59.315 - willAppear {0, 0}
2013-12-09 08:56:59.350 - viewDidLayoutSubviews {0, 0}
2013-12-09 08:56:59.781 - viewDidLayoutSubviews {3200, 223}
2013-12-09 08:56:59.879 - didAppear {3200, 223}
2013-12-09 08:56:59.882 - viewDidLayoutSubviews {3200, 223}

集合视图以编程方式创建 viewDidLoad

UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
[layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
collectionView_ = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
[collectionView_ setTranslatesAutoresizingMaskIntoConstraints:NO];
[collectionView_ setDelegate:self];
[collectionView_ setDataSource:self];
[collectionView_ setShowsHorizontalScrollIndicator:NO];
[collectionView_ setPagingEnabled:YES];
[collectionView_ setBackgroundColor:[UIColor whiteColor]];
[collectionView_ registerClass:[MyCollectionViewCell class] forCellWithReuseIdentifier:[MyCollectionViewCell collectionCellIdentifier]];
[scrollView_ addSubview:collectionView_];

scrollView_是通过XIB(XIB中唯一的控件)创建的.我需要另一个滚动来将一些其他控件放在水平集合下面.设置此方法的约束updateViewConstraints

- (void)updateViewConstraints {
    [super updateViewConstraints];

    NSDictionary *views = [self viewsDictionary];
    NSDictionary *metrics = @{ @"bigMargin" : @12, @"collectionViewHeight" : @(collectionViewHeight_) };

    NSMutableString *verticalConstraints = [NSMutableString stringWithString:@"V:|[collectionView_(==collectionViewHeight)]"];

    [scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[collectionView_(==scrollView_)]|"
                                                                        options:0
                                                                        metrics:nil
                                                                          views:views]];

    if (extendedInformationView_) {

        [scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[extendedInformationView_(==scrollView_)]|"
                                                                            options:0
                                                                            metrics:nil
                                                                              views:views]];

        [verticalConstraints appendFormat:@"-bigMargin-[extendedInformationView_]"];
    }

    if (actionListView_) {

        [scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[actionListView_(==scrollView_)]|"
                                                                            options:0
                                                                            metrics:nil
                                                                              views:views]];

        [verticalConstraints appendFormat:@"-bigMargin-[actionListView_]"];
    }

    [verticalConstraints appendString:@"-bigMargin-|"];

    [scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:verticalConstraints
                                                                        options:0
                                                                        metrics:metrics
                                                                          views:views]];

}

MyCollectionViewCell在其initWithFrame方法中创建其所有控件,这是返回单元格的方法.

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    MyCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:[MyCollectionViewCell collectionCellIdentifier]
                                                                           forIndexPath:indexPath];

    // Data filling

    return cell;   
}

小智.. 7

我有同样的问题,可以解决它.首先,当你创建UICollectionView时,你必须指定一个宽度的框架,无论高度如何,但宽度对于滚动到正确的项目非常重要.

UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
[layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
collectionView_ = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, CGRectGetWidth([scrollView_ frame]), 0.0f)
                                     collectionViewLayout:layout];
[collectionView_ setDelegate:self];
[collectionView_ setDataSource:self];
[collectionView_ setBackgroundColor:[UIColor clearColor]];
[collectionView_ setTranslatesAutoresizingMaskIntoConstraints:NO];
[collectionView_ setShowsHorizontalScrollIndicator:NO];
[collectionView_ setPagingEnabled:YES];
[scrollView_ addSubview:collectionView_];

在创建UICollectionView之后,您必须告诉视图需要更新其约束,因为在iOS6中您必须强制它,因此调用updateViewConstraints:

[self updateViewConstraints]

覆盖方法updateViewConstraints,并在此处设置所有视图约束.记得在调用super之前删除视图的所有约束(在你的代码中你没有删除它们),并在metrics'字典上设置UICollectionView 的宽度而不要使用[collectionView _(== scrollView_)]因为有时它失败,主要是在iOS6中.

- (void)updateViewConstraints {

    [scrollView_ removeConstraints:[scrollView_ constraints]];
    [super updateViewConstraints];

    NSDictionary *views = [self viewsDictionary];
    NSDictionary *metrics = @{ @"bigMargin" : @12, @"collectionViewHeight" : @(collectionViewHeight_), @"viewWidth" : @(CGRectGetWidth([scrollView_ frame]) };

    NSMutableString *verticalConstraints = [NSMutableString stringWithString:@"V:|[collectionView_(==collectionViewHeight)]"];

    [scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[collectionView_(==viewWidth)]|"
                                                                        options:0
                                                                        metrics:nil
                                                                          views:views]];

    if (extendedInformationView_) {

        [scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[extendedInformationView_(==scrollView_)]|"
                                                                            options:0
                                                                            metrics:nil
                                                                              views:views]];

        [verticalConstraints appendFormat:@"-bigMargin-[extendedInformationView_]"];
    }

    if (actionListView_) {

        [scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[actionListView_(==scrollView_)]|"
                                                                            options:0
                                                                            metrics:nil
                                                                              views:views]];

        [verticalConstraints appendFormat:@"-bigMargin-[actionListView_]"];
    }

    [verticalConstraints appendString:@"-bigMargin-|"];

    [scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:verticalConstraints
                                                                        options:0
                                                                        metrics:metrics
                                                                          views:views]];

}

最后,要将UICollectionView滚动到正确的项目,请在viewWillLayoutSubviews上执行此操作,并且不要忘记检查UICollectionView的大小是否为零以避免应用程序崩溃:

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    if (!CGSizeEqualToSize([collectionView_ frame].size, CGSizeZero)) {

        [collectionView_ scrollToItemAtIndexPath:_selectedRowItem_ inSection:0]
                                atScrollPosition:UICollectionViewScrollPositionLeft
                                        animated:NO];
    }
}

就这样.希望能帮助到你!

1 个回答
  • 我有同样的问题,可以解决它.首先,当你创建UICollectionView时,你必须指定一个宽度的框架,无论高度如何,但宽度对于滚动到正确的项目非常重要.

    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    [layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    collectionView_ = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, CGRectGetWidth([scrollView_ frame]), 0.0f)
                                         collectionViewLayout:layout];
    [collectionView_ setDelegate:self];
    [collectionView_ setDataSource:self];
    [collectionView_ setBackgroundColor:[UIColor clearColor]];
    [collectionView_ setTranslatesAutoresizingMaskIntoConstraints:NO];
    [collectionView_ setShowsHorizontalScrollIndicator:NO];
    [collectionView_ setPagingEnabled:YES];
    [scrollView_ addSubview:collectionView_];
    

    在创建UICollectionView之后,您必须告诉视图需要更新其约束,因为在iOS6中您必须强制它,因此调用updateViewConstraints:

    [self updateViewConstraints]
    

    覆盖方法updateViewConstraints,并在此处设置所有视图约束.记得在调用super之前删除视图的所有约束(在你的代码中你没有删除它们),并在metrics'字典上设置UICollectionView 的宽度而不要使用[collectionView _(== scrollView_)]因为有时它失败,主要是在iOS6中.

    - (void)updateViewConstraints {
    
        [scrollView_ removeConstraints:[scrollView_ constraints]];
        [super updateViewConstraints];
    
        NSDictionary *views = [self viewsDictionary];
        NSDictionary *metrics = @{ @"bigMargin" : @12, @"collectionViewHeight" : @(collectionViewHeight_), @"viewWidth" : @(CGRectGetWidth([scrollView_ frame]) };
    
        NSMutableString *verticalConstraints = [NSMutableString stringWithString:@"V:|[collectionView_(==collectionViewHeight)]"];
    
        [scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[collectionView_(==viewWidth)]|"
                                                                            options:0
                                                                            metrics:nil
                                                                              views:views]];
    
        if (extendedInformationView_) {
    
            [scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[extendedInformationView_(==scrollView_)]|"
                                                                                options:0
                                                                                metrics:nil
                                                                                  views:views]];
    
            [verticalConstraints appendFormat:@"-bigMargin-[extendedInformationView_]"];
        }
    
        if (actionListView_) {
    
            [scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[actionListView_(==scrollView_)]|"
                                                                                options:0
                                                                                metrics:nil
                                                                                  views:views]];
    
            [verticalConstraints appendFormat:@"-bigMargin-[actionListView_]"];
        }
    
        [verticalConstraints appendString:@"-bigMargin-|"];
    
        [scrollView_ addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:verticalConstraints
                                                                            options:0
                                                                            metrics:metrics
                                                                              views:views]];
    
    }
    

    最后,要将UICollectionView滚动到正确的项目,请在viewWillLayoutSubviews上执行此操作,并且不要忘记检查UICollectionView的大小是否为零以避免应用程序崩溃:

    - (void)viewWillLayoutSubviews {
        [super viewWillLayoutSubviews];
    
        if (!CGSizeEqualToSize([collectionView_ frame].size, CGSizeZero)) {
    
            [collectionView_ scrollToItemAtIndexPath:_selectedRowItem_ inSection:0]
                                    atScrollPosition:UICollectionViewScrollPositionLeft
                                            animated:NO];
        }
    }
    

    就这样.希望能帮助到你!

    2023-02-13 10:43 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有