-->

UICollectionViewFlowLayout不是方向变更权无效(UICollectionVi

2019-09-01 18:21发布

我有一个UICollectionViewFlowLayout一个UICollectionView。 我也实现了UICollectionViewDelegateFlowLayout协议。

在我的数据源,我有一大堆的其中一个自定义的协议作出回应,所以我可以要求他们的规模和一些其他的东西UIViewControllers的。

在当它要求sizeForItemAtIndexPath中的FlowLayout代表:,我回报的项目大小,我从我的协议获得。 其中执行我的协议ViewControllers返回不同的项目大小取决于方向。

现在,如果我设备的方向改变,从纵向到横向世界上没有问题(项目在景观大),但如果我改回来,我得到这样的警告:

    the item width must be less that the width of the UICollectionView minus the section insets left and right values.
    Please check the values return by the delegate.

它仍然工作,但我不喜欢它得到警告,所以也许你能告诉我什么,我做错了。 此外还有另一个问题。 如果我不告诉我collectionViews collectionViewLayout在willAnimateRotationToInterfaceOrientation无效:在sizeForItemAtIndexPath:永远不会被调用。

希望你明白我的意思。 如果您需要更多的信息让我知道:)

Answer 1:

一个解决方案是使用志愿,并听取了变化给上海华盈的框架为您集合视图。 调用-reloadData会工作,并摆脱了警告。 这里有一个潜在的计时问题...

// -loadView
[self.view addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];

// -dealloc
[self.view removeObserver:self forKeyPath:@"frame"];

// KVO Method
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    [collectionView_ reloadData];
}


Answer 2:

这个答案是晚了,但接受的答案并没有为我工作。 我与OP同情想要一个发射后不管UICollectionViewFlowLayout。 我建议,在无效的视图控制器的布局,其实是最好的解决方案。

我想要细胞的单个水平滚动路线,在视图的中心,在纵向和横向。

我子类UICollectionViewFlowLayout。

我推翻prepareLayout重新计算插图,然后调用[超级prepareLayout。

我推翻了getter方法collectionViewContentSize做出一定含量的大小是正确的。

布局并没有对自己无效,即使界限,用调整方向变化。

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    // does the superclass do anything at this point?
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

    // do whatever else you need before rotating toInterfaceOrientation

    // tell the layout to recalculate
    [self.collectionViewLayout invalidateLayout];
}

该UICollectionViewFlowLayout保持方位之间的滚动位置。 同一小区将居中只有当它是方形的。



Answer 3:

我这里使用的两个答案的组合做什么,我们都在努力做的确实是做一个集合视图看起来像一个表视图,但不使用的UITableView并在单柱获得的物品(最有可能)

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

    [self.collectionView.collectionViewLayout invalidateLayout];
}


Answer 4:

对@ meelawsh的答案的变化,但是在斯威夫特,并没有self.sizeForCollectionView属性:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {

    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)

    guard let collectionView = self.collectionView else {
        return
    }

    if size.width > collectionView.frame.width {
        // bigger

        let animation: (UIViewControllerTransitionCoordinatorContext)->(Void) = {
            context in
            collectionView.collectionViewLayout.invalidateLayout()
        }

        coordinator.animateAlongsideTransition(animation, completion: nil)
    } else {
        // smaller
        collectionView.collectionViewLayout.invalidateLayout()
    }
}


Answer 5:

我不知道这是否可以帮助的人,而是因为我使用了一些没有最后答案的帮我UIViewsUIScrollView

我以编程方式打开UIViews依赖于某些事件。 所以我不能用- (void) willRotateToInterfaceOrientation:invalidateLayoutreloadData因为:
1.的invalidateLayout“下一个视图布局更新周期期间发生。”
2. reloadData“为了提高效率,收集视图仅显示那些细胞和可见补充意见”。

什么工作对我来说是使用的CollectionView的父(一的UIView)的宽度:

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
int currentWidth = self.frame.size.width;

UIEdgeInsets sectionInset = [(UICollectionViewFlowLayout *)collectionView.collectionViewLayout sectionInset];
int fixedWidth = currentWidth - (sectionInset.left + sectionInset.right);


出于某种原因,的CollectionView框架有肖像的宽度的时候调用这个函数...使用int currentWidth = self.frame.width帮我解决这个问题。



Answer 6:

iOS8上:我可以沉默警告的唯一方法是调用旋转到一个更小的尺寸时,旋转到更大的尺寸和转型之前,当在过渡期间无效。

    self.sizeForCollectionView = size; //used to determine collectionview size in sizeForItem
    if (size.width <= size.height) {
        [self.collectionView.collectionViewLayout invalidateLayout];
    }

    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        if (size.width > size.height) {
            [self.collectionView.collectionViewLayout invalidateLayout];
        }
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
    }];


Answer 7:

该@ 0mahc0的回答为我工作,但只有部分。

我没有旋转的问题,因为我强迫我的应用程序只在人像模式,但我的解决方案可以帮助其他有同样的问题。

警告显示每次出现的查看时间。 该警告的原因很清楚,我们已经定义了部分插图左和UICollectionView的权利。 检查界面生成器,你会在这些指标值来定义见。

该@ 0mahc0的解决方案工作,但我想伸展细胞最大宽度,所以我删除部分的插图,否则我将有一个“缘”左,右。

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
    return UIEdgeInsetsZero;
}

相反,实施委托方法你可以去建设者和变化值接口到左,右插图零。



文章来源: UICollectionViewFlowLayout not invalidating right on orientation change