UICollectionView 縫隙修復
在開發中有時可能你的 UICollectionView 需要一行 無縫 放置4個cell。在5s上是完美的,6或者6p上應該是這樣的:

你的第一反應肯定是去檢查 layout 的 minimumInteritemSpacing 。
然而

就是設置為0的,怎么會這樣?
也有可能你需要一行放置3個cell,間隔為1px。可能會是這樣的:

你的第一反應肯定還是去檢查 layout 的 minimumInteritemSpacing 。
然而

原因
罪魁禍首就是像素,手機屏幕最小的單位是像素也就是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
}
}
修復之后
無縫

1px縫隙\

思路
根據上面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真實寬度
}
來自:http://www.jianshu.com/p/4db0be2f4803
本文由用戶 orgq5556 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!