本文主要介紹POLYV iOS多場景Demo在進(jìn)行iPad適配的相關(guān)知識和工作內(nèi)容,包括屏幕適配爬立、分屏適配以及處理因iPad系統(tǒng)版本引起的新問題乍构。旨在讓不同崗位的同學(xué)可以了解iPad適配過程。
一肛跌、屏幕適配
屏幕適配指定義一套適配規(guī)則讓同一畫面在iPhone以及iPad不同尺寸上按照UI設(shè)計稿呈現(xiàn),也包括旋轉(zhuǎn)屏幕時畫面的適配瑞信。
1.1顷帖、基本原理
1.1.1 如何描述view在視圖中的大小和位置:CGPoint逆航、CGSize鼎文、CGRect渔肩、 frame 與 bounds
iOS坐標(biāo)系:iOS以左上角為坐標(biāo)原點(0,0)因俐,以原點向右側(cè)為X軸正方向,原點下側(cè)為Y軸正方向
CGPoint:iOS采用CGPoint來表示點在坐標(biāo)系上X周偎、Y位置抹剩。我們可以通過CGPointMake(x,y)來創(chuàng)建一個坐標(biāo)點:CGPoint point = CGPointMake(80,40)
CGSize:同時,iOS采用CGSize來表示視圖的寬度和高度蓉坎,即視圖的大小澳眷。我們可以通過CGSizeMake(width,height)來創(chuàng)建一個矩形的大小,如CGSize size = CGSizeMake(144,72)將創(chuàng)建一個寬度為144蛉艾,高度為72的矩形大小钳踊。
CGRect:則是結(jié)合了CGPoint和CGSize,用來表示矩形的位置和大小勿侯。它的origin表示矩形左上角所在位置(CGPoint)拓瞪,size表示矩形的大小(CGSize)。
frame:描述當(dāng)前視圖在其父視圖中的位置和大小助琐,參照點為父視圖的坐標(biāo)
bounds:描述的是當(dāng)前視圖在本身坐標(biāo)系統(tǒng)中的位置和大小祭埂,參照點為本身坐標(biāo)系統(tǒng)。
1.1.2 如何布局
POLYV iOS多場景Demo屏幕適配主要layoutSubview對子視圖重新布局(手動布局)兵钮,也開發(fā)其他項目也會少量依靠Masonry第三方框架(自動布局)蛆橡。兩者的本質(zhì)是一樣的 都是計算坐標(biāo)和寬高來實現(xiàn)視圖的定位。
簡單的對比下兩者掘譬,自動布局的方法主要是通過創(chuàng)建約束泰演、刪除約束、重置約束來實現(xiàn)適配葱轩,只專注約束粥血,依靠算法自動布局柏锄。
而使用手動布局則是通過直接設(shè)置view的frame來實現(xiàn)布局。layoutSubviews作為主要的實現(xiàn)手段是對subviews重新布局复亏。比如趾娃,我們想更新子視圖的位置的時候,可以通過調(diào)用layoutSubviews方法缔御,即可以實現(xiàn)對子視圖重新布局抬闷。觸發(fā)時機(jī)有如下幾種:
①init 不會導(dǎo)致layoutSubviews被調(diào)用
②addSuview 導(dǎo)致layoutsubview被調(diào)用在被添加視圖,被添加的視圖和目標(biāo)的子視圖(不一定是所有)
③view setFrame智能地調(diào)用視圖上的layoutSubviews耕突,只有當(dāng)幀的大小參數(shù)不同時才設(shè)置幀
④滾動一個UIScrollView導(dǎo)致layoutSubviews被調(diào)用在scrollView和它的父視圖
⑤旋轉(zhuǎn)設(shè)備只調(diào)用父視圖上的layoutSubview(響應(yīng)的viewControllers主視圖)
⑥調(diào)整視圖的大小將在其父視圖上調(diào)用layoutSubviews(重要:具有內(nèi)在內(nèi)容大小的視圖將在內(nèi)容決定其大小的變化時調(diào)整大小;例如笤成,更新UILabel上的文本將導(dǎo)致內(nèi)在內(nèi)容大小被更新,從而調(diào)用其父視圖上的layoutSubviews)
通過利用觸發(fā)時機(jī)調(diào)用更新UI的方法以達(dá)到適配眷茁,比如下圖中POLYV iOS多場景 Demo在旋轉(zhuǎn)屏幕觸發(fā)layoutSubview后炕泳,通過updateUI來實現(xiàn)布局的更新。
1.2上祈、iPad屏幕適配實戰(zhàn)
1.2.1 區(qū)分是否是iPad設(shè)備
在POLYV iOS多場景Demo主要依靠以下代碼判斷是否為iPad設(shè)備培遵。
BOOL isPad = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad; // iOS多場景項目中常用判斷
// iphone 設(shè)備為 UIUserInterfaceIdiomPhone
#define IS_PAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) // 宏定義的方式,多場景暫時沒有考慮使用
1.2.2 iPad屏幕適配實例
POLYV iOS多場景Demo設(shè)計方案iphone和iPad布局一致登刺,因此使用同一套代碼籽腕,在滿足屏幕適配 基本規(guī)則時增加對iPad判斷調(diào)整相應(yīng)的數(shù)值即可,主要有以下幾種情況:
①彈層比例不同
②頁面間距不同
③控件大小不同
④顯示位置不同纸俭,如iPad上居中顯示
⑤列表每行展示數(shù)量不同
⑥根據(jù)設(shè)備隱藏控件
⑦占位圖顯示不同
二皇耗、分屏適配
分屏適配指iPad在分屏的情況下按照設(shè)計稿呈現(xiàn),處理分屏旋轉(zhuǎn)時引起的布局錯誤揍很。
2.1 iPad分屏初了解
OS9開始郎楼,iPad開始支持split view分屏功能。
If you transition an older project to iOS 9, make your app eligible for Slide Over and Split View by ensuring your Xcode project is configured as follows:Set the Base SDK to “Latest iOS,” as described in Setting the Base SDK in App Distribution Guide.Provide a LaunchScreen.storyboard file (instead of a .png image file as you did in iOS 7 and earlier), as described in Creating a Launch Screen File in App Distribution Guide.In your project’s Info.plist file, in the “Supported interface orientations (iPad)” array, declare support for all four device orientations, as shown here:
NOTEIf you must opt out of Slide Over and Split View, do so explicitly by adding the UIRequiresFullScreen key to your Xcode project’s Info.plist file and apply the Boolean value YES. You can do this in the property list editor or in the General > Deployment Info area in the target editor.TIPA user can disable Slide Over and Split View in Settings > General > Multitasking. If you think you’ve set up everything correctly and find that these features still don’t work, check this setting.
根據(jù)官方說明可以看出如果支持分屏窒悔,需要info.plist中的“Supported interface orientations (iPad)”屬性對應(yīng)的值包含了四個方向呜袁,同時UIRequiresFullScreen對應(yīng)的值為****NO,且需要使用LaunchScreen作為啟動頁蛉迹。
2.2 POLYV iOS多場景Demo分屏適配實戰(zhàn)
2.2.1 如何判斷是否是分屏
在POLYV iOS多場景Demo中傅寡,主要依靠下面的方法判斷是否處于分屏狀態(tài)。
// 判斷是否小屏
BOOL isPad = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad;
Boolean isSmallScreen = viewWidth <= PLVScreenWidth / 3 ? YES : NO;
if (isPad && isSmallScreen) {}
// 判斷是否是分屏
if (isPad && viewWidth == PLVScreenWidth) {}
2.2.2 POLYV iOS多場景Demo中如何體驗分屏
目前云課堂觀看場景支持分屏適配功能北救,其余場景暫時未支持荐操。POLYV iOS多場景Demo目前默認(rèn)關(guān)閉了分屏功能,也就是配置了UIRequiresFullScreen對應(yīng)的值為YES珍策,如果想體驗分屏是可以配置UIRequiresFullScreen對應(yīng)的值為NO托启。
2.2.3 云課堂分屏適配案例
在POLYV iOS多場景Demo云課堂場景中分屏?xí)r布局保持一致,在實際過程中主要是處理 控件的顯示隱藏 以及分屏?xí)r控件布局的刷新攘宙。主要有以下幾種情況:
①控件是否顯示
②控件尺寸不同
③控制按鈕的可用以及提示信息
④在編寫代碼時要考慮如果分屏?xí)r屯耸,需要更新哪些布局
2.2.4 iPad開啟分屏引發(fā)的問題案例
2.2.4.1 開啟分屏后出現(xiàn)打包錯誤
"Invalid Bundle. Your app supports Multitasking on iPad, so you must include the UILaunchStoryboardName key in your bundle, 'com.XXXXX.xxxx. Learn more
網(wǎng)上大部分給的解決方案是Targets - General - Deployment info - 勾選 Requires full screen。
然而如果需要你的項目需要開啟分屏疗绣,那么這個解決方案和項目要求背道而馳线召,此時的解決方案應(yīng)如下圖所示,調(diào)整為launchScreen作為啟動頁多矮。
2.2.4.2 開啟分屏后無法限制屏幕旋轉(zhuǎn)方向
開啟分屏后無法限制屏幕旋轉(zhuǎn)方向缓淹,也就是分屏?xí)r
系統(tǒng)將忽略下面兩處代碼:
UIApplicationDelegate中的supportedInterfaceOrientationsForWindow:方法
UIViewController通過supportedInterfaceOrientations方法設(shè)置的自己支持的屏幕方向
以及UIViewController中shouldAutorotate的值。
這可能會導(dǎo)致在旋轉(zhuǎn)時布局出現(xiàn)錯亂塔逃,開發(fā)過程中需要多驗證旋轉(zhuǎn)屏幕的情況讯壶,及時發(fā)現(xiàn)問題處理解決。
2.2.4.3 分屏?xí)r無法獲取到相機(jī)權(quán)限
在POLYV iOS多場景Demo中湾盗,使用AVCaptureDeviceInput調(diào)用相機(jī)伏蚊,而當(dāng)分屏調(diào)用相機(jī)時系統(tǒng)要求應(yīng)用具有com.apple.developer.avfoundation.multitasking-camera-access 才可以訪問相機(jī)權(quán)限。這會導(dǎo)致分屏?xí)r格粪,POLYV iOS多場景Demo使用相機(jī)畫面黑屏躏吊。此時可以考慮使用UIImagePickerController,使用系統(tǒng)相機(jī)可在分屏?xí)r使用相機(jī)功能拍攝匀借。
另外一般視頻采集都使用 AVCaptureDeviceInput颜阐,例如微信視頻通話平窘、保利威的連麥功能吓肋,這都需要增加在分屏?xí)r對視頻采集相關(guān)功能的禁用提醒。
更多可以訪問蘋果官方說明了解:https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_avfoundation_multitasking-camera-access
三 瑰艘、因iPad設(shè)備引發(fā)的問題
3.1 iPadOS 13版本以上WKWebview的UserAgent變動
iPadOS 13版本以上使用WKWebview時是鬼,iPad的UserAgent會變?yōu)槿缦虑闆r
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko)
這是因為在iPadOS 13版本以上新增了如下API,iPad默認(rèn)的WKContentMode為WKContentModeDesktop紫新。
typedef NS_ENUM(NSInteger, WKContentMode) {
WKContentModeRecommended,
WKContentModeMobile,
WKContentModeDesktop
} API_AVAILABLE(ios(13.0));
因此如果需要正確判斷iPad設(shè)備可在configuration中設(shè)置為WKContentModeMobile均蜜。
WKWebViewConfiguration *config = [WKWebViewConfiguration new];
if (@available(iOS 13.0, *)) {
config.defaultWebpagePreferences.preferredContentMode = WKContentModeMobile;
}
_webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];
四 、iPad適配總結(jié)
其實在整個iPad適配過程中芒率,POLYV iOS多場景Demo都秉承著求同存異的理念囤耳。求同存異是指努力去尋求、擴(kuò)大雙方的共同點偶芍,存異就是正視并允許雙方有一定的個性存在充择。而iPad適配也是在找尋和iPhone相同的規(guī)則 ,去判斷是否為iPad適配匪蟀,通過調(diào)整間距大小等方式以完成不同差異配置椎麦。
當(dāng)然在開發(fā)過程中也要注意,在項目支持分屏后 對可能用到相機(jī)模塊材彪、旋轉(zhuǎn)屏幕適配做好观挎,在布局時理清各控件的關(guān)系琴儿,按照主次順序做好布局;使用WKWebview時注意 iPadOS 13版本以上WKWebview的UserAgent變動適配嘁捷。