UICollectionView 縫隙修復

orgq5556 9年前發布 | 9K 次閱讀 iOS開發 移動開發

在開發中有時可能你的 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 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!