手把手带你撸一个网易云音乐首页 | 适配篇

16,373 阅读5分钟

「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!」

前言

Hello, 大家好,今天是和大家分享如何用 Swift 开发网易云音乐首页的第四篇文章,在前几篇文章中我分别和大家分享了如何使用 MVVM 模式来构建应用,以下是文章的直通车:

手把手带你撸一个网易云音乐首页(一)

手把手带你撸一个网易云音乐首页(二)

手把手带你撸一个网易云音乐首页(三)

完成以上教程后,我们的应用就差不多已经完成 70% 了,接下来,就让我们进一步的去优化它吧!

首先要做的,就是要对其进行适配。

布局适配

现在的 iOS 设备屏幕尺寸越来越丰富,那么该采用怎样的策略来适配这么多设备的屏幕呢!先来看下有哪些屏幕尺寸吧!

image

image

比例系数

在这个工程中,我采用了的策略是选择一种设备的屏幕尺寸来作为开发的标准,例如我这里采用的是 5.5寸的 iPhone6 plus 屏幕的尺寸,来设置一个比例系数,

func scaleW() -> CGFloat {
        return (screenWidth / 414 * CGFloat(self))
    }
    
    func scaleH() -> CGFloat {
        return (screenHeight / 667 * CGFloat(self))
    }

这样,在布局的时候,就可以考虑使用上面的这个系数,来设置高度和宽度:

/// 根据模型计算 View frame
    class func caculateFrame() -> CGRect {
        let height: CGFloat = sectionC_height * CGFloat(scaleW)
        let width: CGFloat = CGFloat(kScreenWidth)
        return CGRect(x: 0, y: 0, width: width, height: height)
    }

为了方便,在工程中可以通过增加 extension 扩展的方式,将需要用到的比例系数实现出来:

import UIKit

let kScreenWidth = UIScreen.main.bounds.width // max(UIScreen.main.bounds.height, UIScreen.main.bounds.width)
let kSreenHeight = UIScreen.main.bounds.height // min(UIScreen.main.bounds.height, UIScreen.main.bounds.width)
let kSreenBounds = UIScreen.main.bounds

let kLeftMargin: CGFloat = 20.0
let kTopMargin: CGFloat = 20.0

let sectionA_height: CGFloat = 200 + 40

let sectionB_height: CGFloat = 140 + 40

let sectionC_height: CGFloat = 100

let sectionD_height: CGFloat = 180

let sectionE_height: CGFloat = 250 + 40

/// 布局 A Cell 的宽度
let itemA_width: CGFloat = 120

/// headview 高
let HEADVIEW_H: CGFloat = 40


extension CGFloat {
        
    func scaleW() -> CGFloat {
        return (screenWidth / 414 * CGFloat(self))
    }

    func scaleH() -> CGFloat {
        return (screenHeight / 667 * CGFloat(self))
    }
}

常见屏幕适配方式

屏幕适配的方式有很多,大家可以选择原生或者第三方开源的屏幕适配方式,例如:

深色模式/浅色模式

Apple 在 iOS13 上推出了 DarkMode 的新特性。那如何去适配此新特性呢!我们需要从俩个方面来适配,一个是颜色,另一个就是图片,接下来让我们一起来看看具体是怎么操作的吧!

颜色

iOS 13 在 UIColor 中 增加了一个初始化方法,我们可以用这个初始化方法来创建动态颜色。

@available(iOS 13.0, *)
public init(dynamicProvider: @escaping (UITraitCollection) -> UIColor)

当系统从 LightMode 和 DarkMode 之间切换的时候就会触发这个回调。

于是,我们可以通过为 UIColor 增加 extension 扩展的方式,来为 App 的背景色和字体颜色做适配,代码如下:

import UIKit

extension UIColor {
    
    // UIView 背景颜色
    public class var darkModeViewColor:UIColor {
        if #available(iOS 13.0, *) {
            return UIColor{(trainCollection) -> UIColor in
                if trainCollection.userInterfaceStyle == .dark {
                    return .systemBackground
                } else {
                    return UIColor(red: 248/255, green: 248/255, blue: 248/255, alpha: 1)
                }
            }
        } else {
            return .systemBackground
        }
    }
    
    // Cell 背景颜色
    public class var homeCellColor:UIColor {
        if #available(iOS 13.0, *) {
            return UIColor{(trainCollection) -> UIColor in
                if trainCollection.userInterfaceStyle == .dark {
                    return UIColor(red: 23/255, green: 23/255, blue: 23/255, alpha: 1)
                } else {
                    return .white
                }
            }
        } else {
            return .white
        }
    }
    
    
    // 文字颜色
    public class var darkModeTextColor: UIColor {
       if #available(iOS 13.0, *) {
           return UIColor{(trainCollection) -> UIColor in
               if trainCollection.userInterfaceStyle == .dark {
                   return .white
               } else {
                   return .black
               }
           }
       } else {
           return .black
       }
    }
    
    // 设置Placeholder文字颜色
    public class var placeholderColor: UIColor {
        if #available(iOS 13.0, *) {
            return UIColor{(trainCollection) -> UIColor in
                if trainCollection.userInterfaceStyle == .dark {
                    return UIColor(red: 255, green: 255, blue: 255, alpha: 0.25)
                } else {
                    return UIColor(red: 0, green: 0, blue: 0, alpha: 0.25)
                }
            }
        } else {
            return UIColor(red: 0, green: 0, blue: 0, alpha: 0.25)
        }
    }

    .......
 }

图片

在 iOS 中,我们的图片素材都是放在 Assets.xcassets 里面的,所以关于图片的适配,我们也需要在这里进行,图片的适配相对来说比较简单,我们只需要提供正确的尺寸格式即可。

首先,打开 Assets.xcassets,随后将我们的图片资源一一的拖动到里面去,图片资源的格式想必大家都很清楚,Apple 要求的是需要提供三套:@1x, @2x, @3x,要想生成此类格式的图片,可以借助外部的工具来制作,例如 Sketch,Figma 等。

由于需要适配不同模式, 所以需要两套不同的图片资源,并且在右边设置 Appearances 时选择 Any, Dark。设置完后,我们就可以将另一套的图片资源挨个拖入对应的位置中,如图:

image

在 Assets.xcassets 中配置好图片,使用时只需要调用如下方法,适配工作就会自动完成。

@available(iOS 13.0, *)
public /*not inherited*/ init?(named name: String)

最后

好了,学完本篇后,我想大家对 iOS 的适配整体已经有个概念了,关于更多的适配详情,请点击此链接,本篇文章的所有代码都已 push 到我的 Github 上,欢迎 star ✨, 我们下篇文章见。

往期文章:

请你喝杯 ☕️ 点赞 + 关注哦~

  1. 阅读完记得给我点个赞哦,有👍 有动力

  2. 关注公众号--- HelloWorld杰少,第一时间推送新姿势

最后,创作不易,如果对大家有所帮助,希望大家点赞支持,有什么问题也可以在评论区里讨论😄~