iOS項(xiàng)目中runtime實(shí)現(xiàn)支持某個(gè)頁(yè)面橫豎屏切換

前言

在項(xiàng)目中,尤其是帶視頻播放的項(xiàng)目,經(jīng)常需要視頻播放頁(yè)面橫豎屏切換。

常規(guī)實(shí)現(xiàn)方式的弊端

提到支持橫豎屏,大家可能會(huì)想到在xcode項(xiàng)目配置中,勾選landscape兩個(gè)選項(xiàng)。在項(xiàng)目中用代碼控制頁(yè)面的橫豎屏。這種方案有這么幾個(gè)缺點(diǎn):

  • 需要在自定義的tabbarController和navigationController,甚至每個(gè)VC中寫控制代碼
  • plus系列手機(jī)橫屏模式下,啟動(dòng)app時(shí),簡(jiǎn)直是杯具(不信的話,你試試有道四六級(jí)app)。市面上,有很多有觀看課程功能的app都有此類問(wèn)題。
  • ......

思考過(guò)程

前段時(shí)間,我在項(xiàng)目中也遇到這個(gè)問(wèn)題。由于當(dāng)時(shí)項(xiàng)目緊,沒(méi)來(lái)的及記錄?,F(xiàn)將實(shí)現(xiàn)方案記錄下:
1. 既然以上方案存在幾個(gè)問(wèn)題,并且不好解決,那絕不能在xcode中配置橫屏。我們知道屏幕橫豎切換時(shí),會(huì)執(zhí)行AppDelegate的application:supportedInterfaceOrientationsForWindow:,返回支持的屏幕方向。那應(yīng)該在這里做操作。
2.由1又產(chǎn)生了兩條思路:

  • 當(dāng)?shù)叫枰獧M屏的vc時(shí),在keywindow最頂層加個(gè)特殊命名的view。在此方法中,取出keywindow第一個(gè)view。判斷。返回橫屏還是豎屏。
  • 當(dāng)需要橫屏的vc對(duì)象存在時(shí),和銷毀時(shí),在此方法做操作。
    我都試了一遍,還是第二種好點(diǎn)。感興趣的同學(xué)可以試試第一種,有問(wèn)題可以留言討論。

3.將2的思路做優(yōu)化。應(yīng)該寫個(gè)工具類,hook此方法,做操作。

代碼實(shí)現(xiàn)

繼承自NSObject創(chuàng)建WSLandscapeTool工具類。代碼中有注釋,不再做說(shuō)明。

WSLandscapeTool.h

#import <UIKit/UIKit.h>

@interface WSLandscapeTool : NSObject

/**
 *  在需要橫屏的控制器中調(diào)用此方法。
    使用前,請(qǐng)先在AppDelegate.m中實(shí)現(xiàn)application:supportedInterfaceOrientationsForWindow:方法
 *
 *  @param appDelegate     AppDelegate類 e.g.(AppDelegate *)[UIApplication sharedApplication].delegate
 *  @param needLandscapeVC 需要橫屏的控制器
 */
+ (void)allowLandscape:(NSObject *)appDelegate viewController:(UIViewController *)needLandscapeVC;

@end
WSLandscapeTool.m

#import "WSLandscapeTool.h"
#import <objc/message.h>

@implementation WSLandscapeTool

+ (void)allowLandscape:(NSObject *)appDelegate viewController:(UIViewController *)needLandscapeVC {
    //防止循環(huán)引用
    __weak typeof(UIViewController *) weakVC = needLandscapeVC;
    
    //方法原始的實(shí)現(xiàn)
    IMP originalIMP = method_getImplementation(class_getInstanceMethod([appDelegate class], @selector(application:supportedInterfaceOrientationsForWindow:)));
    
    //被替換后的新實(shí)現(xiàn)
    IMP newIMP = imp_implementationWithBlock(^(id obj, UIApplication *application, UIWindow *window){
        if (!weakVC) {
            //VC被釋放后,把原來(lái)的方法替換回去
            class_replaceMethod([appDelegate class], @selector(application:supportedInterfaceOrientationsForWindow:), originalIMP, method_getTypeEncoding(class_getInstanceMethod([appDelegate class], @selector(application:supportedInterfaceOrientationsForWindow:))));
        }
        return weakVC ? UIInterfaceOrientationMaskAllButUpsideDown : UIInterfaceOrientationMaskPortrait;
    });
    
    //將方法替換
    class_replaceMethod([appDelegate class], @selector(application:supportedInterfaceOrientationsForWindow:), newIMP, method_getTypeEncoding(class_getInstanceMethod([appDelegate class], @selector(application:supportedInterfaceOrientationsForWindow:))));
}

@end

注意

方法聲明中也寫了說(shuō)明,重復(fù)下。使用工具時(shí),需要在AppDelegate.m中實(shí)現(xiàn)下supportedInterfaceOrientationsForWindow方法。

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    return UIInterfaceOrientationMaskPortrait;
}

最后

個(gè)人見(jiàn)解,如有不妥或不明之處,請(qǐng)留言討論!謝謝!
這是Demo地址

最后編輯于
?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 關(guān)于橫豎屏適配,有一句說(shuō)一句,坑挺深的。之前做Vision和畢設(shè)的時(shí)候就處理過(guò)橫豎屏問(wèn)題,不過(guò)當(dāng)時(shí)的功力太淺,明顯...
    HarwordLiu閱讀 37,590評(píng)論 26 137
  • 由于項(xiàng)目需求,需要實(shí)現(xiàn)app中的其中一個(gè)頁(yè)面支持橫豎屏,由于之前接觸此方面甚少,著實(shí)花費(fèi)了一些時(shí)間研究~怕自己忘記...
    桃子王閱讀 1,801評(píng)論 2 1
  • 概述 寫代碼就是在不斷填坑的過(guò)程中慢慢成長(zhǎng),程序員哪有不遇坑的呢? 這篇文章來(lái)談?wù)刬OS中橫豎屏切換的一些坑,橫豎...
    jumpingfrog0閱讀 11,486評(píng)論 6 21
  • 【跑步不是一種任務(wù),它是一種當(dāng)代非常少時(shí)間能夠進(jìn)行自我交流的一種形式,這種超越形式交流的溝通,在當(dāng)代的快節(jié)奏的生活...
    賀小桶閱讀 241評(píng)論 0 1
  • 世界上有一個(gè)“一”,就會(huì)有一的對(duì)立面, 任何事物都有他的對(duì)立面了吧, 熱 和 冷, 善 和 惡 , 高興 和 悲傷...
    蘇步閱讀 307評(píng)論 0 1

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