我有一个UIScrollView
,它列出了一个图标网格。如果你想象一下iOS Springboard的布局,你就会非常接近正确。它有一个水平的分页滚动(就像Springboard一样)。但是,看起来布局并不完全正确。好像是从上到下布置物品。因此,由于要显示的项目数,我的最后一列只有2行。我宁愿让最后一页上的最后一行有2个项目,就像你在Springboard中看到的那样。
如何使用UICollectionView
及其相关类来完成此操作?我是否必须编写自定义UICollectionViewFlowLayout
?
答案 0 :(得分:91)
您是否尝试将UICollectionViewFlowLayout的滚动方向设置为水平?
[yourFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
如果你希望它像跳板那样页面,你需要在你的集合视图上启用分页,如下所示:
[yourCollectionView setPagingEnabled:YES];
答案 1 :(得分:65)
如何将UIPageViewController
与UICollectionViewControllers
数组一起使用呢?您必须在每个UICollectionViewController
中获取适当数量的项目,但这应该不难。你会得到与Springboard完全相同的外观。
我已经考虑过这一点,在我看来你必须设置:
self.collectionView.pagingEnabled = YES;
并通过继承UICollectionViewLayout
创建自己的集合视图布局。从自定义布局对象中,您可以访问self.collectionView
,这样您就可以知道集合视图{@ 1}},frame
和numberOfSections
的大小。根据该信息,您可以计算单元格numberOfItemsInSection:
(frames
)和prepareLayout
。这里有一些关于创建自定义布局的文章:
您可以在不创建自定义布局的情况下执行此操作(或其近似值)。在空白视图中添加collectionViewContentSize
,在其中启用分页。在滚动视图中添加集合视图。然后为其添加宽度约束,检入代码中包含的项目数量,并将其UIScrollView
设置为正确的值,例如constant
。以下是它的外观(单元格上的数字显示(self.view.frame.size.width * numOfScreens)
):https://www.dropbox.com/s/ss4jdbvr511azxz/collection_view.mov如果您对单元格的排序方式不满意,那么我担心您必须使用1.或者2。
答案 2 :(得分:29)
您需要将UICollectionView
的高度降低到其单元格/项高度,然后从“Horizontal
”中选择“Scroll Direction
”,如下面的屏幕截图所示。然后它将根据您在其数据源实现中返回的numberOfItems
水平滚动。
答案 3 :(得分:11)
如果您在代码中定义UICollectionViewFlowLayout
,它将覆盖Interface Builder配置。因此,您需要再次重新定义scrollDirection
。
let layout = UICollectionViewFlowLayout()
...
layout.scrollDirection = .Horizontal
self.awesomeCollectionView.collectionViewLayout = layout
答案 4 :(得分:8)
只是为了好玩,另一种方法是离开分页和水平滚动设置,添加一个方法来改变数组项的顺序,从“从上到下,从左到右”转换为 visual < / strong>'从左到右,从上到下'并用空的隐藏单元格填充中间单元格以使间距正确。如果网格中的7个项目为9,则可能如下所示:
[1][4][7]
[2][5][ ]
[3][6][ ]
应该成为
[1][2][3]
[4][5][6]
[7][ ][ ]
所以1 = 1,2 = 4,3 = 7等,6 =空。您可以通过计算行和列的总数来重新排序它们,然后计算每个单元格的行和列编号,更改列的行,反之亦然,然后您有新的索引。当单元格没有与图像对应的值时,您可以返回一个空单元格并将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
方法,则必须使用cellForItemAtIndexPath
中使用的相同转化来获取相应的项目。如果您有单元格边距,则需要将它们添加到行和列计算中,因为这些必须正确才能使其正常工作。
答案 5 :(得分:7)
此代码适用于 Swift 3.1 和 Xcode 8.3.2
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 :(得分:6)
我正在使用Xcode 6.2,而对于水平滚动,我在属性检查器中更改了滚动方向。
点击collectionView-&gt;属性检查器 - &gt;滚动方向 - >更改为水平
我希望它有所帮助。
答案 7 :(得分:6)
我们可以使用UICollectionView执行相同的Springboard行为,为此我们需要为自定义布局编写代码。
我使用&#34; SMCollectionViewFillLayout&#34;
的自定义布局类实现实现了它代码存储库:
https://github.com/smindia1988/SMCollectionViewFillLayout
输出如下:
<强> 1.png 强>
<强> 2_Code_H-Scroll_V-Fill.png 强>
<强> 3_Output_H-Scroll_V-Fill.png 强>
答案 8 :(得分:6)
答案 9 :(得分:5)
来自@Erik Hunter,我发布了make horizontal UICollectionView
UICollectionViewFlowLayout *collectionViewFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[collectionViewFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
self.myCollectionView.collectionViewLayout = collectionViewFlowLayout;
在Swift中
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .Horizontal
self.myCollectionView.collectionViewLayout = layout
在Swift 3.0中
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
self.myCollectionView.collectionViewLayout = layout
希望这个帮助
答案 10 :(得分:1)
您可以编写自定义pymysql.err.InternalError: (1366, "Incorrect string value: '\\xF0\\x9F\\x87\\xBA\\xF0\\x9F...' for column 'Message' at row 1")
布局来实现此目的,这是我的实现的演示图像:
此处的代码存储库:KSTCollectionViewPageHorizontalLayout
@iPhoneDev(这也许对你有帮助)
答案 11 :(得分:0)
如果需要设置UICollectionView滚动“方向水平”,并且需要将单元格的宽度和高度设置为静态。 请将收藏视图的估算大小自动设置为无。