?? 2019-10-16
在現(xiàn)在的許多 APP 中可以看到在啟動頁上加載廣告,實際上這里是由兩部分組成,一張與啟動頁完全相同的圖片以及廣告視圖。

在 iOS13 以前我們可以通過啟動頁加載完成之后讀取 LaunchImage 資源里所對應(yīng)的不同尺寸的啟動圖來達到這一目的,但是在 iOS 13 之后蘋果不再推薦使用 LaunchImage 來設(shè)置啟動圖,而是應(yīng)該通過 LaunchScreen.StoryBoard 來設(shè)置,所以之前所使用的方法就失效了。
最初我想可以通過讀取 LaunchScreen.StoryBoard 里的視圖,再將其轉(zhuǎn)為一張圖片就可以達到目的了,然而事實是如果去除了安全區(qū)域那么讀取出來的視圖的尺寸是不全的。
默認創(chuàng)建的 LaunchScreen.StoryBoard 的大小是 iPhone11 的大小,也就是 414 * 896 , 如果你采取直接讀取 LaunchScreen.StoryBoard 里 Controller 對應(yīng)的 View 的方式運行在一個 iPhoneX 的設(shè)備上,那么這里的視圖將以 414 * 896 切成 375 * 812 后得到的視圖顯示在屏幕上??吹降男Ч缦滤荆?/p>
let controller = UIStoryboard(name: "LaunchScreen", bundle: nil).instantiateInitialViewController()!


從示圖中可以明顯看到相比正常的啟動圖快照,有問題的少了 Copyright 部分以及 logo 發(fā)生了偏移。
下面部分我們就來解決這個問題
- 在
LaunchScreen.StoryBoard里設(shè)置 Copyright 對應(yīng)的文本底部約束的 identifier, 這是為了后面調(diào)整在iPhoneX等設(shè)備上這段文本距離底部的距離偏差問題

2.創(chuàng)建一個 Controller,其中的代碼圖所示。這里我們將加載出來的 LaunchScreen.Storyboard 里的 Controller 作為當前控制器的子控制器,同時設(shè)置了對應(yīng) View 的尺寸,注意正是由于這一層的包裝才使得最后取得的快照是正確的。

- 在前面我們設(shè)置了
Copyright文本底部約束所對應(yīng)的 identifier,這是為了處理iPhoneX等設(shè)備上 34 像素的間距問題,你可以注釋掉下面的代碼查看效果。處理代碼如下:
/// 針對 iPhoneX 設(shè)備處理安全區(qū)域34間距問題
if #available(iOS 11.0, *) {
let isPhoneX = (UIApplication.shared.delegate as! AppDelegate).window!.safeAreaInsets.bottom > 0.0
if isPhoneX {
for constraint in controller.view.constraints {
if constraint.identifier == "bottomConstraint" {
constraint.constant += 34.0
}
}
}
}
- 在
UIImage+LaunchScreen.swift中創(chuàng)建獲取啟動圖快照的方法,這里將LaunchScreenViewController的view做成了一張快照,最終這里得到的快照與啟動圖一模一樣。
extension UIImage {
static func launchImage() -> UIImage? {
let controller = LaunchScreenViewController()
// 打開下面的注釋就可以看到有問題的快照
// let controller = UIStoryboard(name: "LaunchScreen", bundle: nil).instantiateInitialViewController()!
let launchImage = UIImage.snapshot(from: controller.view)
return launchImage
}
static func snapshot(from view: UIView) -> UIImage? {
let size = view.bounds.size
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(size, true, scale)
view.layer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
- 最后我們可在
AdViewController里加載啟動圖快照與廣告視圖
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let launchImage = UIImage.launchImage()
let imageView = UIImageView(frame: view.bounds)
imageView.image = launchImage
view.addSubview(imageView)
}
AppDelegate.swift 看到演示的加載代碼如下:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let adVC = AdViewController()
let mainVC = ViewController()
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = adVC;
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 4.0) {
self.window?.rootViewController = mainVC
}
return true
}