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. Ubuntu16.04+Theano环境

    安装Anaconda: 官网下载Anaconda 切换到下载目录 cd ~/下载/ 用bash运行下载好的.sh文件 bash Anaconda2--Linux-x86_64.sh 进入欢迎界面 We ...

  2. 完成OSS.Http底层HttpClient重构封装 支持标准库

    OSS.Http项目对于.Net Standard标准库的支持已经迁移完毕,OSS开源系列两个最底层的类库已经具备跨运行时支持的能力.由于OSS.Http类库是几年前我参照RestSharp的思路,完 ...

  3. 做一个360度看车的效果玩玩(web)

    前几天在 Lexus 官网看到有这样的一个效果:http://www.lexus.com.cn/models/es/360 于是顺手打开控制台看了下他们是怎么做的,发现使用的技术还是比较简单的,通过背 ...

  4. 学生管理系统(C语言)

    #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 3 #define LEN ...

  5. [翻译]现代java开发指南 第二部分

    现代java开发指南 第二部分 第二部分:部署.监控 & 管理,性能分析和基准测试 第一部分,第二部分 =================== 欢迎来到现代 Java 开发指南第二部分.在第一 ...

  6. Mysql动态sql语句,用当前时间做表名

    在mysql备份操作中, 我们可能要使用表名和当前时间来做为备份表的名称,但是MySQL在存储过程中不支持使用变量名来做表名或者列名. 例如:有一个表"user",我需要备份一份, ...

  7. fiddler介绍

    先看fiddler 的使用界面和各模块的功能介绍 1请求列表:请求列表中包含了许多信息,从左至右依次为,#(序列号),Result(结果状态码),Prottocol(请求的协议),Host(请求的主机 ...

  8. HttpWebRequest 模拟网站登录获取数据

    此文档仅仅是一个BaseCode,已做后续查阅 项目使用IBM Platform Symphony分布式平台,所有业务处理都在这个分布式平台上计算,需求是获取这些计算机机群的运行状态,和每一个服务的的 ...

  9. Spring AOP的解读

    一.为什么会有AOP 在日常的开发中经常会有这样一种场景,支付相关的业务中经常需要记录日志,而记录的日志大体相同:这样就会造成支付组件和日志组件强关联,耦合在一起了.而AOP的出现就是为了解决这种问题 ...

  10. .NET中利用反射来实现自动映射两个对象中的数据成员

    在以前的项目开发之中,经常会遇到这样一个问题:比如在外面项目的架构设计之中,我们采用MVC和EntityFramework来构建一个Web应用程序.比如我们采用常用的多层架构,例如有Presentat ...