UICollectionView 适配 iPhone 7 Plus

需求:在屏幕上水平放置 5 张正方形图片,每张图片的宽度相等,无缝隙排列铺满一个屏幕宽度。

看似很简单的需求。用 UICollectionView 实现的话,把 UICollectionView 的宽度设置为屏幕宽度;屏幕宽度除以 5 即为 UICollectionViewCell 的边长,边长也是 UICollectionView 的高度。以下是简单的示例,UICollectionViewCell 不加图片,直接显示背景色。

import UIKit

class ViewController: UIViewController, UICollectionViewDataSource {

	// cell 的个数
private static let itemCountOfRow: Int = 5 // collection view 的宽度
private static let collectionViewWidth: CGFloat = UIScreen.main.bounds.width // cell 的边长
private static let itemWidth: CGFloat = collectionViewWidth / CGFloat(itemCountOfRow) override func viewDidLoad() {
super.viewDidLoad() let flowLayout = UICollectionViewFlowLayout()
// cell 的间距为 0
flowLayout.minimumInteritemSpacing = 0
flowLayout.minimumLineSpacing = 0
// cell 的边长为 itemWidth
let itemWidth = ViewController.itemWidth
flowLayout.itemSize = CGSize(width: itemWidth, height: itemWidth) // collectionView 的宽度为 collectionViewWidth
let collectionView = UICollectionView(frame: CGRect(x: 0,
y: 100,
width: ViewController.collectionViewWidth,
height: itemWidth),
collectionViewLayout: flowLayout)
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
collectionView.backgroundColor = .clear
collectionView.dataSource = self
view.addSubview(collectionView)
} // MARK: - Collection view data source func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
} func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return ViewController.itemCountOfRow
} private let cellColors: [UIColor] = [.red, .blue] func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
cell.backgroundColor = cellColors[indexPath.item % 2]
return cell
} }

在 iPhone 5s、7 的屏幕上显示正常,例如 5s 的效果

然而,7 Plus 设备就有问题,cell 之间会出现缝隙(下图的白边)

先看一下各种设备的屏幕分辨率

屏幕分辨率的单位是 pixel,代码里写的代表屏幕距离的数字,单位是 point。目前(不用考虑非 Retina 屏幕的设备),两者的关系是

// 比 Plus 屏幕小的设备
1 point = 2 pixel // Plus 设备
1 point = 1080 / 414 pixel = 2.6087 pixel

iPhone SE (与 5s相同)、6s 的屏幕宽度分别为 320、375 point,可以被 5 整除。Plus 设备的屏幕宽度为 414 point,除以 5 为 82.8。如果直接 print 这个相除的结果,得到 82.8,看似没问题。但是,用断点可以看到问题所在

UICollectionViewCell 的宽度 itemWidth 为 82.7999…,小于 82.8。也就是说,在 Plus 设备上,cell 的边长比期望的边长小,不能铺满整个屏幕,所以会有缝隙(白边)。

可以有不同的解决方法。比如,可以更换 UICollectionView 的背景色,使缝隙看不出来。这里介绍一种方法:如果屏幕宽度不能被 5 整除,则使 UICollectionView 的宽度稍大于屏幕宽度并且能被 5 整除,这样最后一个 cell 会有一点超出屏幕但又几乎看不出来。Plus 设备的屏幕宽度为 414 point,增加 1 point 即为 415 point,可以被 5 整除;最后一个 cell 超出屏幕 1 point,约为 2.6 pixel,几乎看不出来。具体的代码实现,改变 collectionViewWidth 的值即可。可以判断当前设备是否为 Plus,可以判断屏幕宽度是否为 414,但感觉这些写法不优美。可以按以下修改,兼容所有设备。

private static var collectionViewWidth: CGFloat {
let cellWidth = UIScreen.main.bounds.width / CGFloat(itemCountOfRow)
let remaider = cellWidth.truncatingRemainder(dividingBy: 1)
if remaider > 0 {
// cell width 不为整数,取大于 cell width 的最小整数作为 cell width
// 整数 cell width 乘以 cell 的数量为 collection view 的宽度
return (CGFloat(Int(cellWidth)) + 1) * CGFloat(itemCountOfRow)
}
// cell width 为整数,可以用屏幕宽度作为 collection view 的宽度
return UIScreen.main.bounds.width
}

修改后,7 Plus 的效果

转载请注明出处:http://www.cnblogs.com/silence-cnblogs/p/6617066.html

UICollectionView 适配 iPhone 7 Plus的更多相关文章

  1. App适配iPhone 6/ Plus和iOS 8:10条小秘诀

    App适配iPhone 6/ Plus和iOS 8:10条小秘诀   iPhone 6iOS 8适配   (原文:raywenderlich 作者:Jack Wu 译者:@TurtleFromMars ...

  2. iOS:界面适配--iPhone不同机型适配 6/6plus

    iOS:界面适配--iPhone不同机型适配 6/6plus        机型变化 坐标:表示屏幕物理尺寸大小,坐标变大了,表示机器屏幕尺寸变大了: 像素:表示屏幕图片的大小,跟坐标之间有个对应关系 ...

  3. ios开发之--使用xib适配iPhone X

    最近在修改一个老项目,里面有很多xib文件,需要适配iPhone X,但是又不想重写页面用代码适配,分享个小方法,也算是个笨办法吧, 适配iPhone X底部,iPhone X底部有34px的操作区域 ...

  4. iOS版微信6.5.21发布 适配iPhone X

    昨日,iOS版微信迎来v6.5.21正式版发布,本次升级主要适配iPhone X,在聊天中查找聊天内容时,可以查找交易消息.可以给聊天中的消息设置日期提醒.上一个正式版v6.5.16发布于9月13日, ...

  5. 适配IPhone X的技巧

    #define TabbarHeight ([[UIApplication sharedApplication] statusBarFrame].size.height>20?83:49) // ...

  6. [转]在cocos2d-x中让一个项目适配iphone、iphone retina、ipad、ipad retina四种分辨率

    http://cankeyyin.blog.163.com/blog/static/12336178320124149391202/ 原理:将iphone的hd图片给ipad用,即: 使用原iphon ...

  7. h5页面适配iPhone X的方法

    一.原生适配iphoneX 原生适配很简单,查看机型图:   只要用 #define KIsiPhoneX ([UIScreen mainScreen].bounds.size.height>8 ...

  8. iOS - iPhone屏幕适配/启动图适配/APP图标适配(iPhone最全尺寸包含iPhoneX/XR/XS/XS Max等)

    趁iPhone新品还没有发布,先整理一下屏幕适配.启动图适配.APP图标适配的笔记,方便以后查阅: 注:部分图片来源于网络 违删; (一)iPhone屏幕适配: (1)屏幕分辨率: ①设计尺寸规范(表 ...

  9. 适配iphone X

    首先需要为meta标签加上viewport-fit=cover,默认viewport-fit=contain,跟background-size类似.当值设置为cover既可让安全区域铺满全屏,就跟适配 ...

随机推荐

  1. 使用cordova开发app

    前言 公司之前用的app就是一个套壳挂个链接就能用的app,后来需要添加微信分享方便传播,没办法只好做成混合式的app了, 因为之前做.net用vs可以创建cordova项目也试着玩过,就决定用cor ...

  2. Webappbuilder自定义widget模板

    Webappbuilder自定义widget模板 by 李远祥 到\\widgets\samplewidgets目录下拷贝 CustomWidgetTemplate 文件并重命名为MyWidget 设 ...

  3. 性能优化之数据存储&DOM编程

    多读书多看报 数据存储 ·在javascript中,数据存储的位置会对代码整体性能产生重大的影响. ·数据存储共有4种方式:字面量.变量.数组.对象成员.   ·要理解变量的访问速度,就要理解作用域. ...

  4. [Linux] PHP程序员玩转Linux系列-lnmp环境的搭建

    1.PHP程序员玩转Linux系列-怎么安装使用CentOS 在平常的工作中,我作为PHP程序员经常要搭建一下环境,这个环境就是Linux系统下安装nginx,php,mysql这三个软件,对软件进行 ...

  5. [Spark] - HashPartitioner & RangePartitioner 区别

    Spark RDD的宽依赖中存在Shuffle过程,Spark的Shuffle过程同MapReduce,也依赖于Partitioner数据分区器,Partitioner类的代码依赖结构主要如下所示: ...

  6. ES6__异步开发优化

    一:JS事件循环 1:同步调用 同步调用是一种阻塞式调用,调用要等待双方执行完毕才返回,他是一种单向调用. 2:回调 回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口. 3: ...

  7. 2017-3-2 C#链接数据库实现登陆

    只是链接一个数据库就有好多的知识:) 实际操作下来,主要是两种登陆方式: 1.Windows的身份验证: 2.Sql Sever的身份验证: 两种的方法不同,但是主要是通过复制创建数据库的字符串来链接 ...

  8. centOS7 mini配置linux服务器(三) 配置防火墙以及IPtables切换

    一.firewall介绍 CentOS 7中防火墙是一个非常的强大的功能,在CentOS 6.5中在iptables防火墙中进行了升级了. 1.官方介绍 The dynamic firewall da ...

  9. 赵本山 教你如何在实战项目中使用WCF

    我们都知道调用WCF直接在Service References中引用可以远程调用的WCF Url就行了. 但是我们想过没,在Development环境中可以这样做,但是QA.UAT.Productio ...

  10. linux中添加环境变量(python为例)

    最近想用Django搭建个人博客,之前学了些python基础语法,准备边学习Django边实战操作.自己有一个阿里云服务器,用的centOS,自带的是python2.7版本,我直接安装了python3 ...