zoukankan      html  css  js  c++  java
  • UICollectionView 适配 iPhone 7 Plus

    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( itemWidth, height: itemWidth)
            
            // collectionView 的宽度为 collectionViewWidth
            let collectionView = UICollectionView(frame: CGRect(x: 0,
                                                                y: 100,
                                                                 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

  • 相关阅读:
    可视化理解卷积神经网络
    方差 标准差区别
    SSIS中出现数据流数据源假死状态的解决办法
    IIS中ASP.NET虚拟目录不继承主站点web.config设置的办法(转载)
    SSAS 度量值中的distinct count局聚合方式会数为null的值
    SSAS中CUBE的多对多关系既可以出现在中间事实表上也可以出现在中间维度表上
    SSAS中事实表中的数据如果因为一对多或多对多关系复制了多份,在维度上聚合的时候还是只算一份
    获取当前正在执行的Javascript脚本文件的路径
    C#中try catch中throw ex和throw方式抛出异常有何不同
    SqlServer 一个查询语句导致tempdb增大55G(转载)
  • 原文地址:https://www.cnblogs.com/silence-cnblogs/p/6617066.html
Copyright © 2011-2022 走看看