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. 法国总统放大招,用“分身术”竞选总统 全息3d 网

    编辑:大熊 [摘要]法国总统采用全息技术实现"分身"演讲,可谓是一次演讲,全面覆盖! 全息3d网讯:众所周知,欧美国家的总统是通过公开竞选得到的,所以能更直接.更广泛的近距离接触民 ...

  2. [译] AR SDK的种类比你想得要多!这里介绍七个棒棒哒

    作者:Eddie Offermann 原文:There are dozens more Augmented Reality SDKs than you think! Here are seven gr ...

  3. 响应者链-----iOS

    正文 以触摸事件为例,说一下响应者链 当发生触摸事件后,Runloop监听到事件,会将其事件打包成一个UIEvent事件,并放入当前活动UIApplication的事件队列中,再会传给UIWindow ...

  4. Java String类练习题

    题目:1. 给定一个字符串,判断该字符串中是否包含某个子串.如果包含,求出子串的所有出现位置.如:"abcbcbabcb34bcbd"中,"bcb"子串的出现位 ...

  5. strpos、 strstr、 substr三个函数的对比讲解

    mixed strpos ( string $haystack , mixed $needle [, int $offset = 0 ] ) 返回 needle 在 haystack 中首次出现的数字 ...

  6. android学习3——长宽的单位问题dp,px,dpi

    android设备的单位px,pt,dp,sp 分辨率 先通俗说下分辨率的概念.可以把屏幕想想成一个个正方形格子组成的.如果横向有1280个格子,竖向有720个格子.那么分辨率就是1280*720.这 ...

  7. IOS高级开发~开机启动&无限后台运行&监听进程

    一般来说, IOS很少给App后台运行的权限. 仅有的方式就是 VoIP. IOS少有的为VoIP应用提供了后台socket连接,定期唤醒并且随开机启动的权限.而这些就是IOS上实现VoIP App的 ...

  8. hibernate动态切换数据源

    起因: 公司的当前产品,主要是两个项目集成的,一个是java项目,还有一个是php项目,两个项目用的是不同的数据源,但都是mysql数据库,因为java这边的开发工作已经基本完成了,而php那边任务还 ...

  9. JavaWeb从0开始学(一)-----搭建第一个Web应用程序与JSP工作原理

    以往学习的时候大多是看完书或者看完视频,动手实践一下就OK了.然而过了一段时间我发现东西都忘差不多了,需要复习才能重新掌握.现在开始学习JavaWeb了,我将在这里记录自己的学习的一点一滴,不仅便于自 ...

  10. iOS性能检测之Instrunments - 几种常用工具简单介绍

    Instrunments:  没错,就是这货,很多人平时开发可能不一定会用到这个,但我要说的是,学会使用它,会让你加分不少哦 先来一张全家福: 1.打开方式 或者 两种方式都行. 2.今天主要介绍一下 ...