解決UICollectionView間隔設(shè)置為0時(shí)仍有空隙的問題
明明把間距設(shè)置為0了為什么還有空隙呢 ?接著往下看有兩個解決辦法等著你欢瞪。
例子:(我的代碼)
#pragma mark - <UICollectionViewDelegateFlowLayout>
//定義每個UICollectionView 的邊距
- ( UIEdgeInsets )collectionView:( UICollectionView *)collectionView layout:( UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:( NSInteger )section {
return UIEdgeInsetsMake(0, 0, 0, 0);;
}
#pragma mark - X間距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 0;
}
#pragma mark - Y間距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 0;
}
- 首先應(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
對于iPhone 6 Plus之前的手機(jī)挂捻,pt和px的比例是1:2碉纺,而iPhone 6 Plus出來之后,這一比例達(dá)到了1:3,
還是不太明白的話可以谷歌一下,這里有篇擴(kuò)展閱讀: 「像素」「渲染像素」以及「物理像素」是什么東西骨田?它們有什么聯(lián)系耿导?
造成縫隙的原因
iPhone6的屏幕像素(point,也叫邏輯像素)是
375*667
,物理像素為750*1334
,等分4份的話每一個item的寬度是375/4=93.75
,這里是沒有問題的,問題是屏幕能分的最小物理像素是1,而iPhone6的[[UIScreen mainScrenn] scale]
是2.0,也就是說1個屏幕像素(邏輯像素)對應(yīng)有2個物理像素,即0.5個屏幕像素對應(yīng)1個物理像素,而iPhone6四等分的寬度是93.75
,根據(jù)前面的分析有0.25
是不可再分的,這就是造成縫隙的原因。 同理iPhone6 Plus的[[UIScreen mainScrenn] scale]
是3.0,也就是說1個屏幕像素(邏輯像素)對應(yīng)有3個物理像素,即0.333333個屏幕像素對應(yīng)1個物理像素,四等分之后是414/4=103.5
,有0.16
是不可再分的,也會有縫隙态贤。 ###解決辦法 思路:只要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í)際的寬度,可能會超出屏幕,需要調(diào)整一下frame
CGFloat pointX = (realWidth - rect.size.width) / 2; //偏移距離
rect.origin.x = -pointX;//向左偏移
rect.size.width = realWidth;
_rect = rect;
return realItemWidth; //每個cell的真實(shí)寬度
}
- 解決方法 二
重寫layoutAttributesForElementsInRect方法即可
//
// GSCollectionViewFlowLayout.m
// SuperSearch
//
// Created by 鞏小鵬 on 2018/4/17.
// Copyright ? 2018年 鞏小鵬. All rights reserved.
//
#import "GSCollectionViewFlowLayout.h"
@interface GSCollectionViewFlowLayout()
@end
@implementation GSCollectionViewFlowLayout
#pragma mark - 初始化layout的結(jié)構(gòu)和初始需要的參數(shù)
- (void)prepareLayout
{
[super prepareLayout];
}
//#pragma mark - cell的左右間距
- (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {
NSMutableArray * answer = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
/* 處理左右間距 */
for(int i = 1; i < [answer count]; ++i) {
UICollectionViewLayoutAttributes *currentLayoutAttributes = answer[i];
UICollectionViewLayoutAttributes *prevLayoutAttributes = answer[i - 1];
//注意:currentLayoutAttributes.indexPath.section 這里是單獨(dú)處理某個section的空隙悠汽,如果不需要可把if判斷刪除即可
if (currentLayoutAttributes.indexPath.section == 0) {
NSInteger maximumSpacing = 0;
NSInteger origin = CGRectGetMaxX(prevLayoutAttributes.frame);
if(origin + maximumSpacing + currentLayoutAttributes.frame.size.width < self.collectionViewContentSize.width) {
CGRect frame = currentLayoutAttributes.frame;
frame.origin.x = origin + maximumSpacing;
currentLayoutAttributes.frame = frame;
}
}
}
return answer;
}
@end