RVN*_*RVN 96 ios uicollectionview
I am currently using UICollectionView
for the user interface grid, and it works fine. However, I'd like to be enable horizontal scrolling. The grid supports 8 items per page and when the total number of items are, say 4, this is how the items should be arranged with horizontal scroll direction enabled:
0 0 x x
0 0 x x
Run Code Online (Sandbox Code Playgroud)
Here 0 -> Collection Item and x -> Empty Cells
有没有办法使它们居中对齐,如:
x 0 0 x
x 0 0 x
Run Code Online (Sandbox Code Playgroud)
这样内容看起来更干净?
以下安排也可能是我期待的解决方案.
0 0 0 0
x x x x
Run Code Online (Sandbox Code Playgroud)
rde*_*mar 79
我认为你可以通过实现这样的方式来实现单行外观:
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(0, 100, 0, 0);
}
Run Code Online (Sandbox Code Playgroud)
您将不得不使用该数字来弄清楚如何将内容强制为一行.第一个0是顶边参数,如果要在屏幕中垂直居中,也可以调整那个参数.
Ale*_*shy 77
对于那些寻找一个解决方案中心对齐,动态宽的CollectionView细胞,因为我是,我最终修改天使的回答为左对齐版本创建一个中心对齐的子类UICollectionViewFlowLayout
.
// NOTE: Doesn't work for horizontal layout!
class CenterAlignedCollectionViewFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
guard let superAttributes = super.layoutAttributesForElements(in: rect) else { return nil }
// Copy each item to prevent "UICollectionViewFlowLayout has cached frame mismatch" warning
guard let attributes = NSArray(array: superAttributes, copyItems: true) as? [UICollectionViewLayoutAttributes] else { return nil }
// Constants
let leftPadding: CGFloat = 8
let interItemSpacing = minimumInteritemSpacing
// Tracking values
var leftMargin: CGFloat = leftPadding // Modified to determine origin.x for each item
var maxY: CGFloat = -1.0 // Modified to determine origin.y for each item
var rowSizes: [[CGFloat]] = [] // Tracks the starting and ending x-values for the first and last item in the row
var currentRow: Int = 0 // Tracks the current row
attributes.forEach { layoutAttribute in
// Each layoutAttribute represents its own item
if layoutAttribute.frame.origin.y >= maxY {
// This layoutAttribute represents the left-most item in the row
leftMargin = leftPadding
// Register its origin.x in rowSizes for use later
if rowSizes.count == 0 {
// Add to first row
rowSizes = [[leftMargin, 0]]
} else {
// Append a new row
rowSizes.append([leftMargin, 0])
currentRow += 1
}
}
layoutAttribute.frame.origin.x = leftMargin
leftMargin += layoutAttribute.frame.width + interItemSpacing
maxY = max(layoutAttribute.frame.maxY, maxY)
// Add right-most x value for last item in the row
rowSizes[currentRow][1] = leftMargin - interItemSpacing
}
// At this point, all cells are left aligned
// Reset tracking values and add extra left padding to center align entire row
leftMargin = leftPadding
maxY = -1.0
currentRow = 0
attributes.forEach { layoutAttribute in
// Each layoutAttribute is its own item
if layoutAttribute.frame.origin.y >= maxY {
// This layoutAttribute represents the left-most item in the row
leftMargin = leftPadding
// Need to bump it up by an appended margin
let rowWidth = rowSizes[currentRow][1] - rowSizes[currentRow][0] // last.x - first.x
let appendedMargin = (collectionView!.frame.width - leftPadding - rowWidth - leftPadding) / 2
leftMargin += appendedMargin
currentRow += 1
}
layoutAttribute.frame.origin.x = leftMargin
leftMargin += layoutAttribute.frame.width + interItemSpacing
maxY = max(layoutAttribute.frame.maxY, maxY)
}
return attributes
}
}
Run Code Online (Sandbox Code Playgroud)
Sie*_*ult 56
这里的顶级解决方案对我来说不起作用,所以我提出了这个应该适用于任何水平滚动集合视图与流布局和只有一个部分:
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
// Add inset to the collection view if there are not enough cells to fill the width.
CGFloat cellSpacing = ((UICollectionViewFlowLayout *) collectionViewLayout).minimumLineSpacing;
CGFloat cellWidth = ((UICollectionViewFlowLayout *) collectionViewLayout).itemSize.width;
NSInteger cellCount = [collectionView numberOfItemsInSection:section];
CGFloat inset = (collectionView.bounds.size.width - (cellCount * cellWidth) - ((cellCount - 1)*cellSpacing)) * 0.5;
inset = MAX(inset, 0.0);
return UIEdgeInsetsMake(0.0, inset, 0.0, 0.0);
}
Run Code Online (Sandbox Code Playgroud)
mie*_*tus 34
动态计算insets很容易,这段代码总是以你的单元为中心:
NSInteger const SMEPGiPadViewControllerCellWidth = 332;
...
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
NSInteger numberOfCells = self.view.frame.size.width / SMEPGiPadViewControllerCellWidth;
NSInteger edgeInsets = (self.view.frame.size.width - (numberOfCells * SMEPGiPadViewControllerCellWidth)) / (numberOfCells + 1);
return UIEdgeInsetsMake(0, edgeInsets, 0, edgeInsets);
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
[self.collectionView.collectionViewLayout invalidateLayout];
}
Run Code Online (Sandbox Code Playgroud)
kga*_*dis 20
与其他答案类似,这是一个动态答案,应该适用于静态大小的单元格.我做的一个修改是我把垫子放在两边.如果我不这样做,我遇到了问题.
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewFlowLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
NSInteger numberOfItems = [collectionView numberOfItemsInSection:section];
CGFloat combinedItemWidth = (numberOfItems * collectionViewLayout.itemSize.width) + ((numberOfItems - 1) * collectionViewLayout.minimumInteritemSpacing);
CGFloat padding = (collectionView.frame.size.width - combinedItemWidth) / 2;
return UIEdgeInsetsMake(0, padding, 0, padding);
}
Run Code Online (Sandbox Code Playgroud)
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
let numberOfItems = CGFloat(collectionView.numberOfItems(inSection: section))
let combinedItemWidth = (numberOfItems * flowLayout.itemSize.width) + ((numberOfItems - 1) * flowLayout.minimumInteritemSpacing)
let padding = (collectionView.frame.width - combinedItemWidth) / 2
return UIEdgeInsets(top: 0, left: padding, bottom: 0, right: padding)
}
Run Code Online (Sandbox Code Playgroud)
另外,如果你仍然遇到问题,请确保您同时设置minimumInteritemSpacing
并minimumLineSpacing
以相同的值,因为这些值似乎是相互关联的.
UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout;
flowLayout.minimumInteritemSpacing = 20.0;
flowLayout.minimumLineSpacing = 20.0;
Run Code Online (Sandbox Code Playgroud)
ber*_*ert 19
把它放到你的集合视图委托中.它考虑了比其他答案更多的基本流程布局设置,因此更通用.
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
NSInteger cellCount = [collectionView.dataSource collectionView:collectionView numberOfItemsInSection:section];
if( cellCount >0 )
{
CGFloat cellWidth = ((UICollectionViewFlowLayout*)collectionViewLayout).itemSize.width+((UICollectionViewFlowLayout*)collectionViewLayout).minimumInteritemSpacing;
CGFloat totalCellWidth = cellWidth*cellCount + spacing*(cellCount-1);
CGFloat contentWidth = collectionView.frame.size.width-collectionView.contentInset.left-collectionView.contentInset.right;
if( totalCellWidth<contentWidth )
{
CGFloat padding = (contentWidth - totalCellWidth) / 2.0;
return UIEdgeInsetsMake(0, padding, 0, padding);
}
}
return UIEdgeInsetsZero;
}
Run Code Online (Sandbox Code Playgroud)
swift版本(感谢g0ld2k):
extension CommunityConnectViewController: UICollectionViewDelegateFlowLayout {
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
// Translated from Objective-C version at: http://stackoverflow.com/a/27656363/309736
let cellCount = CGFloat(viewModel.getNumOfItemsInSection(0))
if cellCount > 0 {
let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
let cellWidth = flowLayout.itemSize.width + flowLayout.minimumInteritemSpacing
let totalCellWidth = cellWidth*cellCount + spacing*(cellCount-1)
let contentWidth = collectionView.frame.size.width - collectionView.contentInset.left - collectionView.contentInset.right
if (totalCellWidth < contentWidth) {
let padding = (contentWidth - totalCellWidth) / 2.0
return UIEdgeInsetsMake(0, padding, 0, padding)
}
}
return UIEdgeInsetsZero
}
}
Run Code Online (Sandbox Code Playgroud)
小智 11
我对静态大小的集合视图单元的解决方案需要在左侧和右侧填充 -
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAtIndex section: Int) -> UIEdgeInsets {
let flowLayout = (collectionViewLayout as! UICollectionViewFlowLayout)
let cellSpacing = flowLayout.minimumInteritemSpacing
let cellWidth = flowLayout.itemSize.width
let cellCount = CGFloat(collectionView.numberOfItemsInSection(section))
let collectionViewWidth = collectionView.bounds.size.width
let totalCellWidth = cellCount * cellWidth
let totalCellSpacing = cellSpacing * (cellCount - 1)
let totalCellsWidth = totalCellWidth + totalCellSpacing
let edgeInsets = (collectionViewWidth - totalCellsWidth) / 2.0
return edgeInsets > 0 ? UIEdgeInsetsMake(0, edgeInsets, 0, edgeInsets) : UIEdgeInsetsMake(0, cellSpacing, 0, cellSpacing)
}
Run Code Online (Sandbox Code Playgroud)
我的应用程序中有一个使用UICollectionView
&的标签栏UICollectionViewFlowLayout
,其中一行单元格居中对齐.
要获得正确的缩进,请从宽度中减去所有单元格的总宽度(包括间距)UICollectionView
,然后除以2.
[........Collection View.........]
[..Cell..][..Cell..]
[____indent___] / 2
=
[_____][..Cell..][..Cell..][_____]
Run Code Online (Sandbox Code Playgroud)
问题是这个功能 -
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
之前被称为......
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
...所以你不能迭代你的单元格来确定总宽度.
相反,你需要再次计算每个单元格的宽度,在我的情况下,我使用,[NSString sizeWithFont: ... ]
因为我的单元格宽度由UILabel本身决定.
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
CGFloat rightEdge = 0;
CGFloat interItemSpacing = [(UICollectionViewFlowLayout*)collectionViewLayout minimumInteritemSpacing];
for(NSString * tag in _tags)
rightEdge += [tag sizeWithFont:[UIFont systemFontOfSize:14]].width+interItemSpacing;
// To center the inter spacing too
rightEdge -= interSpacing/2;
// Calculate the inset
CGFloat inset = collectionView.frame.size.width-rightEdge;
// Only center align if the inset is greater than 0
// That means that the total width of the cells is less than the width of the collection view and need to be aligned to the center.
// Otherwise let them align left with no indent.
if(inset > 0)
return UIEdgeInsetsMake(0, inset/2, 0, 0);
else
return UIEdgeInsetsMake(0, 0, 0, 0);
}
Run Code Online (Sandbox Code Playgroud)
在Swift中,以下内容将通过在每个单元格的两侧应用正确数量的填充来均匀分布单元格.当然,您需要先了解/设置单元格宽度.
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAtIndex section: Int) -> UIEdgeInsets {
var cellWidth : CGFloat = 110;
var numberOfCells = floor(self.view.frame.size.width / cellWidth);
var edgeInsets = (self.view.frame.size.width - (numberOfCells * cellWidth)) / (numberOfCells + 1);
return UIEdgeInsetsMake(0, edgeInsets, 60.0, edgeInsets);
}
Run Code Online (Sandbox Code Playgroud)
小智 8
Swift 2.0对我来说很好用!
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
let edgeInsets = (screenWight - (CGFloat(elements.count) * 50) - (CGFloat(elements.count) * 10)) / 2
return UIEdgeInsetsMake(0, edgeInsets, 0, 0);
}
Run Code Online (Sandbox Code Playgroud)
其中: screenWight:基本上是我的集合的宽度(全屏宽度) - 我做了常量:让screenWight:CGFloat = UIScreen.mainScreen().bounds.width因为self.view.bounds每次显示600 - 来自SizeClasses 元素 -单元格数组 50 - 我的手动单元格宽度10 - 单元格 之间的距离
小智 6
您可以像这样使用https://github.com/keighl/KTCenterFlowLayout:
KTCenterFlowLayout *layout = [[KTCenterFlowLayout alloc] init];
[self.collectionView setCollectionViewLayout:layout];
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
88108 次 |
最近记录: |