原因
-
当
UICollectionViewCell
的size不为整数时,UICollectionViewFlowLayout
在布局计算时,可能会调整Cell的frame.origin,使Cell按照最小物理像素(渲染像素)对齐,导致出现缝隙。 -
假设当前Cell的frame.origin.y=100.8(逻辑像素),转化成渲染像素(参考备注)是201.6(iPhone 8)或302.4(iPhone 8 Plus)。为了按渲染像素对齐,
UICollectionViewFlowLayout
应该会四舍五入取整,取整后为202(iPhone 8)或302(iPhone 8 Plus),转成逻辑像素101(iPhone 8)或100.667(iPhone 8 Plus),导致在iphone8上就会出现0.2像素的缝隙。 -
分辨率相关的,可以百度下。
简单解决办法:
- 主动把Cell的size取整,不丢给
UICollectionViewFlowLayout
处理。
- (CGSize)fixedCollectionCellSize:(CGSize)size {
CGFloat scale = [UIScreen mainScreen].scale;
return CGSizeMake(round(scale * size.width) / scale, round(scale * size.height) / scale);
}
Demo实验
- UITableView,Cell高度设置成100.12,没有强制被按渲染像素对齐,如
99.62
1802.16
1902.28
(lldb) po [0x7fb85b83b800 recursiveDescription]
<UITableView: 0x7fb85b83b800; frame = (0 0; 375 667); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x6000004451f0>; layer = <CALayer: 0x60000022dc40>; contentOffset: {0, 1272.5}; contentSize: {375, 2002.4000549316406}; adjustedContentInset: {20, 0, 0, 0}>
| <UITableViewCell: 0x7fb85c862a00; frame = (0 1902.28; 375 100.12); autoresize = W; layer = <CALayer: 0x6040004265a0>>
| | <UITableViewCellContentView: 0x7fb85b70fea0; frame = (0 0; 375 99.62); gestureRecognizers = <NSArray: 0x6040002426a0>; layer = <CALayer: 0x604000425e80>>
| | | <UIImageView: 0x7fb85b41a330; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x6000008215c0>>
| | <_UITableViewCellSeparatorView: 0x7fb85b710820; frame = (15 99.62; 360 0.5); layer = <CALayer: 0x604000427640>>
| <UITableViewCell: 0x7fb85c862400; frame = (0 1802.16; 375 100.12); autoresize = W; layer = <CALayer: 0x6040002212e0>>
- iPhone Plus 8,UICollectionView,Cell高度设置成100.12,强制被按渲染像素对齐了,frame.origin.y被调整后的值,如
200.333
500.667
600.667
| <UICollectionViewCell: 0x7fdd9f71f010; frame = (0 200.333; 414 100.12); hidden = YES; layer = <CALayer: 0x60000023d800>>
| <UICollectionViewCell: 0x7fdd9f71f470; frame = (0 300.333; 414 100.12); layer = <CALayer: 0x60000023e380>>
| <UICollectionViewCell: 0x7fdd9f72aa30; frame = (0 400.333; 414 100.12); layer = <CALayer: 0x60000023f4e0>>
| <UICollectionViewCell: 0x7fdd9f72ae90; frame = (0 500.667; 414 100.12); layer = <CALayer: 0x60000023f9a0>>
| <UICollectionViewCell: 0x7fdd9f72b510; frame = (0 600.667; 414 100.12); layer = <CALayer: 0x60000023fbc0>>
| <UICollectionViewCell: 0x7fdd9f72d1a0; frame = (0 701; 414 100.12); layer = <CALayer: 0x60000023fdc0>>
- iPhone Plus,UICollectionView,Cell高度设置成100.12,强制被按渲染像素对齐了,frame.origin.y被调整后的值,如
300.5
400.5
500.5
| <UICollectionViewCell: 0x7f85b441b6c0; frame = (0 0; 375 100.12); hidden = YES; layer = <CALayer: 0x600000035ec0>>
| <UICollectionViewCell: 0x7f85b4502e10; frame = (0 100; 375 100.12); hidden = YES; layer = <CALayer: 0x600000035c20>>
| <UICollectionViewCell: 0x7f85b4505c10; frame = (0 200; 375 100.12); layer = <CALayer: 0x600000036300>>
| <UICollectionViewCell: 0x7f85b4506400; frame = (0 300.5; 375 100.12); layer = <CALayer: 0x600000036be0>>
| <UICollectionViewCell: 0x7f85b4506d70; frame = (0 400.5; 375 100.12); layer = <CALayer: 0x600000227ac0>>
| <UICollectionViewCell: 0x7f85b4507560; frame = (0 500.5; 375 100.12); layer = <CALayer: 0x6000002277c0>>
备注
Points(逻辑像素)<--->Rendered Pixels(渲染像素)<--->Physical Pixels(物理像素)
iOS不同机型尺寸.png
网友评论