简体   繁体   English

UICollectionView布局故障

[英]UICollectionView layout malfunction

I'm building a dictionary app, and one of the features is that you can "drill down" into a definition. 我正在构建字典应用程序,其功能之一是您可以“向下钻取”定义。 You look up a word, there's a word in the definition you don't understand, so you tap that word and the app shows you the definition for that word, if available. 您查找一个单词,定义中有一个您不了解的单词,因此您轻按该单词,应用程序会显示该单词的定义(如果有)。 This is pretty standard for iOS dictionary apps on the App Store, if anyone's familiar. 如果有人熟悉,这对于App Store上的iOS词典应用程序来说是非常标准的。

One feature is that I am going to have a bar that shows each word as you drill down, so you get a sort of "chain" of words across this horizontal bar. 一个功能是,我将拥有一个在向下钻取时显示每个单词的条,这样您就可以在此水平条上获得一系列“单词”。 The idea is you can tap on the words in the chain to navigate forwards and backwards through your chain of words. 这个想法是,您可以点击链中的单词来在单词链中前后导航。

To represent this chain I am using a UICollectionView, with a subclassed UICollectionViewController. 为了表示这条链,我使用一个UICollectionView和一个子类UICollectionViewController。 Since it's essentially a "grid" with a single row, this made sense to me. 因为它本质上是一个带有一行的“网格”,所以这对我来说很有意义。 I'm using a storyboard, so I simply embedded my custom controller into the main view, pass events back and forth between the master controller and this custom collection controller. 我正在使用情节提要,因此我只是将自定义控制器嵌入到主视图中,在主控制器和此自定义集合控制器之间来回传递事件。 Pretty simple. 很简单

Now, let's say the user taps many different words, so you get the "chain" of UICollectionViewCells growing across the bar from left to right until you hit the edge. 现在,假设用户轻敲了许多不同的单词,那么您将获得UICollectionViewCells的“链”,该链从左到右在整个条形上逐渐增长,直到达到边缘为止。 Since UICollectionView is based on/has a UIScrollView in it, this shouldn't be a problem. 由于UICollectionView基于/具有UIScrollView,所以这应该不是问题。 My concept is that, if the number of items to be displayed exceeds the width of the view, the CollectionView would expand the contentView and place items off the right edge of the view port, and I could then programmatically scroll the view to show the newly added item. 我的想法是,如果要显示的项目数超过视图的宽度,则CollectionView将展开contentView并将项目放置在视图端口的右边缘之外,然后我可以以编程方式滚动视图以显示新的添加的项目。

Here's the code that I use to do this (edited). 这是我用来执行此操作的代码(已编辑)。 It's a method that I call in my subclassed UICollectionViewController: 我在子类UICollectionViewController中调用了此方法:

- (void)reloadDataWithAnimation
{
    [self.collectionView performBatchUpdates:^{
        [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
    } completion:^(BOOL finished) {
            [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:model.data.count - 1 inSection:0]
                                        atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
        }

    }];
}

This is more or less what I'd normally do with a UITableView: tell it to reload its data after I have changed the model. 这或多或少是我通常使用UITableView所做的事情:告诉我在更改模型后重新加载其数据。 It didn't quite work at first until I found a question on SO that covered the use of performBatchUpdates , and I had trouble doing the scrollToItemAtIndexPath until I realized it needed to go into the completion block. 直到开始我在SO上发现一个问题,涉及到performBatchUpdates的使用,然后才开始工作,直到我意识到需要进入完成块为止,我在做scrollToItemAtIndexPath遇到了麻烦。

Now, here's the funky part: everything works fine before the items fill up the whole view. 现在,这是一个时髦的部分:在项目填满整个视图之前,一切工作正常。 The first time an item would go beyond the boundaries, the CollectionView places the item below the last item in the row. 项第一次超出边界时,CollectionView将该项置于行中最后一项的下方 This looks really strange because the view is only one row tall, so you can kinda half-see the item parked below the last one in the row, mostly obscured. 这看起来真的很奇怪,因为视图只有一排高,所以您可以半看停在该行中最后一个下方的物品,大部分被遮盖了。 No scrolling occurs. 没有滚动发生。

At this point, if you scroll the CollectionView back and forth, the item reconfigures itself and moves into the correct position. 此时,如果来回滚动CollectionView,则该项将重新配置并移动到正确的位置。 Or, if you add another item, they align correctly and the view scrolls as intended. 或者,如果您添加另一个项目,它们将正确对齐,并且视图将按预期滚动。 Successive additions work just fine. 连续添加就可以了。 However, if you scroll back to the left and then add another item, it briefly appears underneath the last currently visible item in the viewport, then the view scrolls off to the far right and as it scrolls the misplaced item jumps up into its proper position. 但是,如果向后滚动到左侧然后添加另一个项目,则该项目会短暂出现在视口中当前当前可见的项目下方,然后视图滚动到最右侧,并且在滚动时,放错位置的项目会跳至正确位置。

Although I began posting this question as I could find nothing on Stack Overflow, in the course of writing my question, the Similar Question sidebar updated and I found similar questions, and eventually an answer. 尽管我开始发布此问题是因为我在Stack Overflow上找不到任何内容,但是在编写问题的过程中,“相似问题”侧边栏已更新,并且我发现了相似的问题,最终得到了答案。

Similar question: UICollectionView cell layout is out of the collection view's bounds 类似的问题: UICollectionView单元格布局超出了集合视图的范围

Apparently this issue is known to Apple. 显然,此问题为Apple所知。

Here is the solution linked to in the above question: https://stackoverflow.com/a/13389461/700471 这是上述问题中链接的解决方案: https : //stackoverflow.com/a/13389461/700471

The code that Nick Snyder posted solved the problem for me perfectly. Nick Snyder发布的代码完全为我解决了这个问题。

Edit: Additionally, in the end I subclassed UICollectionViewLayout, bypassing FlowLayout, and made my own layout with this tutorial . 编辑:此外,最后,我绕过FlowLayout继承了UICollectionViewLayout的子类,并通过本教程制作了自己的布局。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM