iOS Swift iPhone、iPad屏幕完整適配

導(dǎo)言

移動(dòng)開(kāi)發(fā)中屏幕適配是很重要的。就個(gè)人而言,最從android開(kāi)發(fā)的時(shí)候用過(guò)最原始的屏幕適配方案,以1920*1080為基準(zhǔn)屏幕(設(shè)計(jì)圖比例 ),然后生成以1px開(kāi)始不同的分辨率


圖片來(lái)自簡(jiǎn)書(shū).png
圖片來(lái)自簡(jiǎn)書(shū)2.png

這樣的做法能簡(jiǎn)單的適配屏幕,不過(guò)手機(jī)分辨率過(guò)多,就要增加一種像素比例,無(wú)形中增加了app的體積,也麻煩。

然后就是用過(guò)今日頭條的AndroidAutoSize無(wú)入侵輕量級(jí)的屏幕適配框架,這種方案是不錯(cuò)的,我android同事也在用,重點(diǎn)是無(wú)入侵性輕量級(jí)。

然后回到iOS屏幕適配,masonry和SnapKit都是基于自動(dòng)布局,大的方面還是能適配屏幕的,小的地方還是需要自己手動(dòng)改才行。

最近在學(xué)習(xí)Flutter課程(MJ老師系列

有講到小程序的適配基于rpx,然后我覺(jué)得挺好的 現(xiàn)在就移植到iOS(我一直認(rèn)為前端思想都是大同小異的

實(shí)現(xiàn)

先上代碼

class QSizeFit : NSObject {
    
    static let shared : QSizeFit = {
        let shared = QSizeFit()
        return shared
    }()
    
    let rpx : Double
    
    override init() {
        rpx = Double(1.0 * UIScreen.main.bounds.size.width / 375)
    }
    
    
    func getIRpx(value : Int) -> Int{
        return Int(rpx) * value
    }
    
    func getFRpx(value : Float) -> Float{
        return Float(rpx) * value
    }
    
    func getDRpx(value : Double) -> Double{
        return rpx * value
    }
    
}


 
extension Int {    
    
    var rpx : Int {
        return QSizeFit.shared.getIRpx(value: self)
    }
}

extension Float {
    
    var rpx : Float {
        return QSizeFit.shared.getFRpx(value: self)
    }
    
}

extension Double {
    
    var rpx : Double {
        return QSizeFit.shared.getDRpx(value: self)
    }
}

extension CGFloat {
    
    var rpx : CGFloat {
        return CGFloat(QSizeFit.shared.getFRpx(value: Float(self)))
    }
    
}

375 是設(shè)計(jì)圖比例 也是基準(zhǔn)
使用中注意Double\ Float 轉(zhuǎn)Int 當(dāng)rpx小于1 有時(shí)候會(huì)結(jié)果等于0了

效果圖
Simulator Screen Shot - iPad Pro (11-inch) (1st generation) - 2020-07-06 at 10.25.00.png
Simulator Screen Shot - iPad Pro (12.9-inch) (4th generation) - 2020-07-06 at 10.24.14.png
Simulator Screen Shot - iPhone 6s - 2020-07-06 at 10.22.03.png
Simulator Screen Shot - iPhone Xs Max - 2020-07-06 at 10.23.31.png

其他

如果有什么其他更好的方案也可以留言交流。

后續(xù)

2020.08.11

在項(xiàng)目中使用發(fā)現(xiàn)還是有些問(wèn)題,比如在iPad上比例于iPhone相差較大。會(huì)造成中間部分View重疊。以下是優(yōu)化后的效果

Simulator Screen Shot - iPad Pro (12.9-inch) (4th generation) - 2020-08-11 at 09.44.18.png
Simulator Screen Shot - iPad Pro (12.9-inch) (4th generation) - 2020-08-11 at 09.44.33.png
Simulator Screen Shot - iPad Pro (12.9-inch) (4th generation) - 2020-08-11 at 09.59.01.png

其中圖一二是同一版本,是將UIViewController中的View添加到UIScrollView中,以此達(dá)到完整的展示。不過(guò)對(duì)于用戶體驗(yàn)性不是很好。在此期間使用iPad過(guò)程中發(fā)現(xiàn)百度App首頁(yè)中左右是空白的(當(dāng)然他主題色也是白色,看起來(lái)沒(méi)異樣),內(nèi)容居中的效果。

后面想了下,設(shè)計(jì)圖上有些是最頂級(jí)rootView是UIView(不是UIScrollView)就分開(kāi)適配

/// 所有UIViewController的View的父類,效果圖1、2就是繼承UIScrollView,如果是圖3就應(yīng)該繼承UIView
class QMainView: UIScrollView {

    lazy var viewMain : UIView = {
        let view = UIView()
       
        return view
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
      
        self.addSubview(viewMain)
        
        if UIDevice.current.userInterfaceIdiom == .pad {
            let w = 375 * QScreenHeight / 667
            viewMain.frame = CGRect(x: (QScreenWidth - w) * 0.5, y: 0, width: w, height: QScreenHeight)
        }else {
            viewMain.frame = CGRect(x: 0, y: 0, width: QScreenWidth, height: QScreenHeight)
        }
        
        //contentSize = viewMain.frame.size
        
        self.bounces = false
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func addSubview(_ view: UIView) {
        if  view != viewMain {
            viewMain.addSubview(view)
        }else {
            super.addSubview(view)
        }
    }
    
}

基類QViewController中把UIView替換掉

lazy var vianMainQ : QMainView = {
        let view = QMainView(frame: UIScreen.main.bounds)
        return view
}()
    
override func loadView() {
        if isFullScreen() {
            view = vianMainQ
        }else {
            view = UIView()
        }
}

當(dāng)然rpx也要增加一種
如果是滿屏就是rootView不能滾動(dòng)的就應(yīng)該使用rpx2

let rpx : Double
    
let rpx2 : Double
    
override init() {
        
        rpx = Double(1.0 * UIScreen.main.bounds.size.width / 375)
        
        if UIDevice.current.userInterfaceIdiom == .pad {
            rpx2 = Double(QScreenHeight / 667)
        }else {
            rpx2 = rpx
        }
        
 }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容