UICollectionView - 水平滚动,水平布局?

问题描述 投票:54回答:11

我有一个UIScrollView,列出一个图标网格。如果你想象一下iOS Springboard的布局,你就会非常接近正确。它有一个水平的分页滚动(就像Springboard一样)。但是,看起来布局并不完全正确。好像是从上到下布置物品。因此,由于要显示的项目数,我的最后一列只有2行。我宁愿让最后一页上的最后一行有2个项目,就像你在Springboard中看到的那样。

如何通过q​​azxswpoi及其相关课程来实现这一目标?我必须写一个自定义UICollectionView

ios layout uicollectionview uicollectionviewlayout
11个回答
67
投票

第一种方法

怎么样使用UICollectionViewFlowLayout和一系列UIPageViewController?你必须在每个UICollectionViewControllers中获取适当数量的项目,但这应该不难。你会得到与Springboard完全相同的外观。

第二种方法

我考虑过这个,在我看来你必须设置:

UICollectionViewController

并通过继承self.collectionView.pagingEnabled = YES; 创建自己的集合视图布局。从自定义布局对象中,您可以访问UICollectionViewLayout,因此您将知道集合视图的大小self.collectionViewframenumberOfSections的大小。有了这些信息,你就可以计算出细胞的numberOfItemsInSection:(在frames中)和prepareLayout。这里有一些关于创建自定义布局的文章:

3rd approach

您可以在不创建自定义布局的情况下执行此操作(或其近似值)。在空白视图中添加http://www.objc.io/issue-3/collection-view-layouts.html,在其中启用分页。在滚动视图中添加集合视图。然后添加宽度约束,检入代码中有多少项,并将其UIScrollView设置为正确的值,例如constant。这是它的外观(细胞上的数字显示(self.view.frame.size.width * numOfScreens)):indexPath.row如果你对细胞的排序方式不满意,那么我担心你必须选择1.或2。


6
投票

来自@Erik Hunter,我发布了make horizo​​ntal enter image description here的完整代码

UICollectionView

在斯威夫特

UICollectionViewFlowLayout *collectionViewFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[collectionViewFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
self.myCollectionView.collectionViewLayout = collectionViewFlowLayout;

在Swift 3.0中

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .Horizontal
self.myCollectionView.collectionViewLayout = layout

希望这有帮助


1
投票

您可以编写自定义let layout = UICollectionViewFlowLayout() layout.scrollDirection = .horizontal self.myCollectionView.collectionViewLayout = layout 布局来实现此目的,这是我的实现的演示图像:

这是代码库:UICollectionView

@iPhoneDev(这也许对你有帮助)


91
投票

您是否尝试将UICollectionViewFlowLayout的滚动方向设置为水平?

https://www.dropbox.com/s/ss4jdbvr511azxz/collection_view.mov

如果你希望它像跳板那样页面,你需要在你的集合视图上启用分页,如下所示:

[yourFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];

34
投票

您需要将[yourCollectionView setPagingEnabled:YES]; 的高度降低到其单元格/项目高度,并从“UICollectionView”中选择“Horizontal”,如下面的屏幕截图所示。然后它将根据您在其数据源实现中返回的Scroll Direction水平滚动。


12
投票

如果您在代码中定义numberOfItems,它将覆盖Interface Builder配置。因此,您需要再次重新定义UICollectionViewFlowLayout

scrollDirection

8
投票

只是为了好玩,另一种方法是只留下分页和水平滚动设置,添加一个方法,改变数组项的顺序,从“从上到下,从左到右”转换为“从左到右”,从上到下在底部'并用空的隐藏单元填充中间单元格以使间距正确。如果网格中的7个项目为9,则会如下所示:

let layout = UICollectionViewFlowLayout()
...
layout.scrollDirection = .Horizontal
self.awesomeCollectionView.collectionViewLayout = layout

应该成为

[1][4][7]
[2][5][ ]
[3][6][ ]

所以1 = 1,2 = 4,3 = 7等,6 =空。您可以通过计算行和列的总数来重新排序它们,然后计算每个单元格的行和列编号,更改列的行,反之亦然,然后您有新的索引。当单元格没有与图像对应的值时,您可以返回一个空单元格并将[1][2][3] [4][5][6] [7][ ][ ] 设置为它。

它在我构建的音板应用程序中运行良好,所以如果有人想要工作代码,我会添加它。只需要很少的代码就可以使这个技巧发挥作用,听起来比它更难!

更新

我怀疑这是最好的解决方案,但请求这里的工作代码:

cell.hidden = YES;

如果您想使用- (void)viewDidLoad { // Fill an `NSArray` with items in normal order items = [NSMutableArray arrayWithObjects: [NSDictionary dictionaryWithObjectsAndKeys:@"Some label 1", @"label", @"Some value 1", @"value", nil], [NSDictionary dictionaryWithObjectsAndKeys:@"Some label 2", @"label", @"Some value 2", @"value", nil], [NSDictionary dictionaryWithObjectsAndKeys:@"Some label 3", @"label", @"Some value 3", @"value", nil], [NSDictionary dictionaryWithObjectsAndKeys:@"Some label 4", @"label", @"Some value 4", @"value", nil], [NSDictionary dictionaryWithObjectsAndKeys:@"Some label 5", @"label", @"Some value 5", @"value", nil], nil ]; // Calculate number of rows and columns based on width and height of the `UICollectionView` and individual cells (you might have to add margins to the equation based on your setup!) CGFloat w = myCollectionView.frame.size.width; CGFloat h = myCollectionView.frame.size.height; rows = floor(h / cellHeight); columns = floor(w / cellWidth); } // Calculate number of sections - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return ceil((float)items.count / (float)(rows * columns)); } // Every section has to have every cell filled, as we need to add empty cells as well to correct the spacing - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return rows*columns; } // And now the most important one - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier@"myIdentifier" forIndexPath:indexPath]; // Convert rows and columns int row = indexPath.row % rows; int col = floor(indexPath.row / rows); // Calculate the new index in the `NSArray` int newIndex = ((int)indexPath.section * rows * columns) + col + row * columns; // If the newIndex is within the range of the items array we show the cell, if not we hide it if(newIndex < items.count) { NSDictionary *item = [items objectAtIndex:newIndex]; cell.label.text = [item objectForKey:@"label"]; cell.hidden = NO; } else { cell.hidden = YES; } return cell; } 方法,则必须使用didSelectItemAtIndexPath中使用的相同转换来获取相应的项目。如果您有单元格边距,则需要将它们添加到行和列计算中,因为这些必须正确才能使其正常工作。


7
投票

此代码在Swift 3.1和Xcode 8.3.2中运行良好

cellForItemAtIndexPath

6
投票

我正在研究Xcode 6.2和水平滚动我在属性检查器中更改了滚动方向。

单击collectionView->属性检查器 - >滚动方向 - >更改为水平

我希望它对某人有帮助。


6
投票

对于xcode 8我做了这个,它工作:override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() let layout = UICollectionViewFlowLayout() layout.scrollDirection = .horizontal self.collectionView.collectionViewLayout = layout self.collectionView!.contentInset = UIEdgeInsets(top: -10, left: 0, bottom:0, right: 0) if let layout = self.collectionView.collectionViewLayout as? UICollectionViewFlowLayout { layout.minimumInteritemSpacing = 0 layout.minimumLineSpacing = 0 layout.itemSize = CGSize(width: self.view.frame.size.width-40, height: self.collectionView.frame.size.height-10) layout.invalidateLayout() } }


6
投票

我们可以使用UICollectionView执行相同的Springboard行为,为此我们需要编写自定义布局的代码。

我用我的自定义布局类实现“SMCollectionViewFillLayout”实现了它

代码库:

输出如下:

1.png

https://github.com/smindia1988/SMCollectionViewFillLayout

2_Code_H-Scroll_V-Fill.png

First.png

3_Output_H-Scroll_V-Fill.png enter image description here

4_Code_H-Scroll_H-Fill.png enter image description here

5_Output_H-Scroll_H-Fill.png enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.