在使用UICollectionView
開發(fā)無(wú)縫隙或者間隙為1px的頁(yè)面的時(shí)候應(yīng)該會(huì)遇到這樣的問(wèn)題(iPhone 5s 沒(méi)有問(wèn)題),明明是把屏幕四等分了,但為什么會(huì)有下圖的空白間隙呢?
再檢查一下代碼:
UICollectionViewFlowLayout * flowLayout = [[UICollectionViewFlowLayout alloc] init];
flowLayout.itemSize = CGSizeMake(Wi/4.0, 60);//算出來(lái)的寬度是93.75
flowLayout.minimumLineSpacing = 0;
flowLayout.minimumInteritemSpacing = 0;
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, Wi, He) collectionViewLayout:flowLayout];
發(fā)現(xiàn)代碼也是沒(méi)有問(wèn)題啊,可為什么會(huì)有這樣呢?(之前開發(fā)遇過(guò)這個(gè)問(wèn)題,但是被自己用"畫線填充"的方式取巧搞定了,沒(méi)想到這次有同事問(wèn)我這個(gè)問(wèn)題,為了能有一個(gè)通用的方法,還是要去找出原因)纫版。果然還是從簡(jiǎn)書找到解決方法UICollectionView 縫隙修復(fù),這里我結(jié)合我的理解做進(jìn)一步解釋。有哪位看官對(duì)此有更好的闡述希望不吝指導(dǎo)
- 首先應(yīng)該了解一下
[[UIScreen mainScrenn] scale]
iPhone 4 之前的設(shè)備為1.0
iPhone 4 ~ iPhone 6s (除plus外) 的為2.0
iPhone 6 plus 和 iPhone 6s plus 的為3.0
對(duì)于iPhone 6 Plus之前的手機(jī)痹雅,pt和px的比例是1:2,而iPhone 6 Plus出來(lái)之后,這一比例達(dá)到了1:3朴沿,
還是不太明白的話可以谷歌一下,這里有篇擴(kuò)展閱讀: 「像素」「渲染像素」以及「物理像素」是什么東西魏铅?它們有什么聯(lián)系?
造成縫隙的原因
iPhone6的屏幕像素(point,也叫邏輯像素)是375*667
,物理像素為750*1334
,等分4份的話每一個(gè)item的寬度是375/4=93.75
,這里是沒(méi)有問(wèn)題的,問(wèn)題是屏幕能分的最小物理像素是1,而iPhone6的[[UIScreen mainScrenn] scale]
是2.0,也就是說(shuō)1個(gè)屏幕像素(邏輯像素)對(duì)應(yīng)有2個(gè)物理像素,即0.5個(gè)屏幕像素對(duì)應(yīng)1個(gè)物理像素,而iPhone6四等分的寬度是93.75
,根據(jù)前面的分析有0.25
是不可再分的,這就是造成縫隙的原因千贯。
同理iPhone6 Plus的[[UIScreen mainScrenn] scale]
是3.0,也就是說(shuō)1個(gè)屏幕像素(邏輯像素)對(duì)應(yīng)有3個(gè)物理像素,即0.333333個(gè)屏幕像素對(duì)應(yīng)1個(gè)物理像素,四等分之后是414/4=103.5
,有0.16
是不可再分的,也會(huì)有縫隙敦第。
解決辦法
思路:只要itemSize的width的小數(shù)點(diǎn)后的值等于1 / [UIScreen mainScreen].scale
的值即可峰弹。
- (CGFloat)fixSlitWith:(CGRect)rect colCount:(CGFloat)colCount space:(CGFloat)space {
CGFloat totalSpace = (colCount - 1) * space;//總共留出的距離
CGFloat itemWidth = (rect.size.width - totalSpace) / colCount;// 按照真實(shí)屏幕算出的cell寬度 (iPhone6 375*667)93.75
CGFloat fixValue = 1 / [UIScreen mainScreen].scale; //(1px=0.5pt,6Plus為3px=1pt)
CGFloat realItemWidth = floor(itemWidth) + fixValue;//取整加fixValue floor:如果參數(shù)是小數(shù),則求最大的整數(shù)但不大于本身.
if (realItemWidth < itemWidth) {// 有可能原cell寬度小數(shù)點(diǎn)后一位大于0.5
realItemWidth += fixValue;
}
CGFloat realWidth = colCount * realItemWidth + totalSpace;//算出屏幕等分后滿足1px=([UIScreen mainScreen].scale)pt實(shí)際的寬度,可能會(huì)超出屏幕,需要調(diào)整一下frame
CGFloat pointX = (realWidth - rect.size.width) / 2; //偏移距離
rect.origin.x = -pointX;//向左偏移
rect.size.width = realWidth;
_rect = rect;
return realItemWidth; //每個(gè)cell的真實(shí)寬度
}