close
当前位置: 物联网在线 > 技术文库 > ios >

UICollectionView 缝隙修复

在开发中有时可能你的 UICollectionView 需要一行 无缝 放置4个cell。在5s上是完美的,6或者6p上应该是这样的:

UICollectionView 缝隙修复

你的第一反应肯定是去检查 layout 的 minimumInteritemSpacing 。

然而

UICollectionView 缝隙修复

就是设置为0的,怎么会这样?

也有可能你需要一行放置3个cell,间隔为1px。可能会是这样的:

UICollectionView 缝隙修复

你的第一反应肯定还是去检查 layout 的 minimumInteritemSpacing 。

然而

UICollectionView 缝隙修复

原因

罪魁祸首就是像素,手机屏幕最小的单位是像素也就是1px,当小于1px时,像素是不可再分的,就造成了上面的现象。(1px = 0.5pt)

在上面设置 itemSize 宽度时就是因为像素不够分了375 / 4 = 93.75,根据上面的关系可知,小数点后只有1位且最小为5。

第二种情况同理 374 / 3 = 124.66666666666667

我在网上查了一下,主要的解决办法主要是重写 UICollectionViewFlowLayout ,还有设置 sectionInset ,似乎都有点麻烦,也没能最终解决问题。这篇 文章 的思路才是我们想要的,不过只处理了无缝情况。

debug代码

先贴出代码

Swift2.3

/// 修正collection布局有缝隙 func fixSlit(inout rect: CGRect, colCount: CGFloat, space: CGFloat = 0) -> CGFloat { let totalSpace = (colCount - 1) * space let itemWidth = (rect.width - totalSpace) / colCount var realItemWidth = floor(itemWidth) + 0.5 if realItemWidth < itemWidth { realItemWidth += 0.5 } let realWdth = colCount * realItemWidth + totalSpace let pointX = (realWdth - rect.width) / 2 rect.origin.x = -pointX rect.size.width = realWdth return (rect.width - totalSpace) / colCount }

Swift3

extension UICollectionViewFlowLayout { /// 修正collection布局有缝隙 func fixSlit(rect: inout CGRect, colCount: CGFloat, space: CGFloat = 0) -> CGFloat { let totalSpace = (colCount - 1) * space let itemWidth = (rect.width - totalSpace) / colCount var realItemWidth = floor(itemWidth) + 0.5 if realItemWidth < itemWidth { realItemWidth += 0.5 } let realWdth = colCount * realItemWidth + totalSpace let pointX = (realWdth - rect.width) / 2 rect.origin.x = -pointX rect.size.width = realWdth return (rect.width - totalSpace) / colCount } } 修复之后

无缝

UICollectionView 缝隙修复

1px缝隙\

UICollectionView 缝隙修复

思路

根据上面bug出现的原因,我们知道只要 itemSize 的 width 的小数点后只有1位且最小为5也就是满足 1px=0.5pt 这个等式。

func fixSlit(inout rect: CGRect, colCount: CGFloat, space: CGFloat = 0) -> CGFloat { let totalSpace = (colCount - 1) * space // 总共留出的距离 let itemWidth = (rect.width - totalSpace) / colCount // 按照真实屏幕算出的cell宽度 var realItemWidth = floor(itemWidth) + 0.5 // 取整加0.5(1px=0.5pt) if realItemWidth < itemWidth { // 有可能原cell宽度小数点后一位大于0.5 realItemWidth += 0.5 } let realWidth = colCount * realItemWidth + totalSpace // 算出屏幕等分后满足`1px=0.5pt`实际的宽度 let pointX = (realWidth - rect.width) / 2 // 偏移距离 rect.origin.x = -pointX // 向左偏移 rect.size.width = realWidth return (rect.width - totalSpace) / colCount // 每个cell真实宽度 }

来自:


(责任编辑:ioter)

用户喜欢...

自定义UICollectionViewLayout实现瀑布流布局

最近项目中需要用到瀑布流的效果,但是用UICollectionViewFlowLayout又达不到效果,自己动手写了一个瀑布流的layout,下面是我的心路路程 先先上效果图 因为是用UICollectionView来实现瀑布流的,决...