iOS 13.4 & Xcode 11.4 采坑小记(重写系统get)

最近更新了新系统,发现Modal样式设置的UIModalPresentationFullScreen失效了。

相信大家在适配iOS13 系统的时候,为了适配Modal默认样式发生变化( iOS13之前默认为UIModalPresentationFullScreen 13之后变为UIModalPresentationAutomatic)很多人是通过分类方法实现的。

即:为UIViewController扩展该方法(本质是重写modalPresentationStyle属性的get方法),这样所有地方就直接生效了,不用一处一处修改,当然私有pod库中的还是要自己修改。

/*
 Defines the presentation style that will be used for this view controller when it is presented modally. Set this property on the view controller to be presented, not the presenter.
 If this property has been set to UIModalPresentationAutomatic, reading it will always return a concrete presentation style. By default UIViewController resolves UIModalPresentationAutomatic to UIModalPresentationPageSheet, but system-provided subclasses may resolve UIModalPresentationAutomatic to other concrete presentation styles. Participation in the resolution of UIModalPresentationAutomatic is reserved for system-provided view controllers.
 Defaults to UIModalPresentationAutomatic on iOS starting in iOS 13.0, and UIModalPresentationFullScreen on previous versions. Defaults to UIModalPresentationFullScreen on all other platforms.
 */
@property(nonatomic,assign) UIModalPresentationStyle modalPresentationStyle API_AVAILABLE(ios(3.2));
// 适配iOS13
- (UIModalPresentationStyle)modalPresentationStyle {
   //    适配iOS13系统下 RN弹窗内容被遮挡
    if ([self isKindOfClass:NSClassFromString(@"RCTModalHostViewController")]) {
        return UIModalPresentationOverCurrentContext;
    } else {
        return UIModalPresentationFullScreen;
    }
}

然后问题来了,分类中的 - (UIModalPresentationStyle)modalPresentationStyle 这个方法在Xcode 11.4 & iOS 13.4 环境下 不再执行了。

至此找到问题根本原因是 Xcode 11.4 & iOS 13.4 环境下 分类重写系统级属性的get方法会失效。正常的系统级方法(如:- (void)viewWillAppear:(BOOL)animated;重写)还是会调用。

解决办法:

1、使用低版本Xcode打包

2、使用运行时方法替换(系统还是会调用这个方法,只不过不再调用我们重写的get方法,所以替换方法实现)

+ (void)swizzleInstanceSelector:(SEL)originalSelector withSelector:(SEL)swizzledSelector
{
    Class class = [self class];

    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

    BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
    if (success)
    {
        class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    }
    else
    {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

+ (void)load
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

         [self swizzleInstanceSelector:@selector(modalPresentationStyle) withSelector:@selector(uiviewController_modalPresentationStyle)];
    });
}

- (UIModalPresentationStyle)uiviewController_modalPresentationStyle
{
   //    适配iOS13系统下 RN弹窗内容被遮挡
    if ([self isKindOfClass:NSClassFromString(@"RCTModalHostViewController")]) {
        return UIModalPresentationOverCurrentContext;
    } else {
        return UIModalPresentationFullScreen;
    }
}

拓展:

系统属性的get方法重写可能都会受到影响

原文地址:https://www.cnblogs.com/lijianyi/p/12607377.html

时间: 2024-10-12 11:44:42

iOS 13.4 & Xcode 11.4 采坑小记(重写系统get)的相关文章

总结iOS 8和Xcode 6的各种坑

总结iOS 8和Xcode 6的各种坑 项目路径坑 模拟器的路径从之前的 ~/Library/Application Support/iPhone Simulator 移动到了 ~/Library/Developer/CoreSimulator/Devices/ 这相当的坑爹,之前运行用哪个模拟器直接选择这个模拟器文件夹进去就能找到项目 现在可好,Devices目录下没有标明模拟器的版本,图片上选中的对应的可能是iPhone 5s 7.1的 然后图片上的文件夹对应的应该是 iPhone 4s 7

(转)总结iOS 8和Xcode 6的各种坑

项目路径坑 模拟器的路径从之前的 ~/Library/Application Support/iPhone Simulator 移动到了 ~/Library/Developer/CoreSimulator/Devices/ 这相当的坑爹,之前运行用哪个模拟器直接选择这个模拟器文件夹进去就能找到项目 现在可好,Devices目录下没有标明模拟器的版本,图片上选中的对应的可能是iPhone 5s 7.1的 然后图片上的文件夹对应的应该是 iPhone 4s 7.1 iPhone 4s 8.0 iPh

iOS 8和Xcode 6的各种坑

1项目路径坑 模拟器的路径从之前的 ~/Library/Application Support/iPhone Simulator 移动到了 ~/Library/Developer/CoreSimulator/Devices/ 这相当的坑爹,之前运行用哪个模拟器直接选择这个模拟器文件夹进去就能找到项目 现在可好,Devices目录下没有标明模拟器的版本,图片上选中的对应的可能是iPhone 5s 7.1的 然后图片上的文件夹对应的应该是 iPhone 4s 7.1 iPhone 4s 8.0 iP

iOS - (instancetype)initWithCoder:(NSCoder *)aDecoder采坑小记

一般我们封装控件时 既要支持xib 又要支持手码 一般我们会在以下两个方法里执行我们的自定义操作.然后关于initWithCoder的小坑来了. /// 手码 - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // 自定义操作 [self initData]; [self initUI]; } return self; } /// xib - (instanc

文顶顶 iOS开发UI篇—IOS开发中Xcode的一些使用技巧

iOS开发UI篇—IOS开发中Xcode的一些使用技巧 一.快捷键的使用 经常用到的快捷键如下: 新建 shift + cmd + n     新建项目 cmd + n             新建文件 视图 option + cmd + 回车 打开助理编辑器 cmd + 回车           显示主窗口 cmd + 0             导航窗口 option + cmd + 0    工具窗口 在.m & .h之间切换           control + cmd + 上/下 按

iOS开发UI基础—IOS开发中Xcode的一些使用技巧

iOS开发UI基础-IOS开发中Xcode的一些使用技巧 一.快捷键的使用 经常用到的快捷键如下: 新建 shift + cmd + n     新建项目 cmd + n             新建文件 视图 option + cmd + 回车 打开助理编辑器 cmd + 回车           显示主窗口 cmd + 0             导航窗口 option + cmd + 0    工具窗口 在.m & .h之间切换           control + cmd + 上/下

记一次虚拟机共享文件夹的采坑之旅

1.官网下载VMware,安装~~ 2.找一个linux镜像,创建虚拟机~~ 3.进入系统,安装gcc 报错 could not retrieve mirrorlist...... 解决:sudo vim /etc/sysconfig/network-scripts/ifcfg-ens33 将ONBOOT改为yes,wq!保存退出     重新启动网络  service network restart 4.虚拟机设置->选项->共享文件夹->开启并添加一个共享文件夹 5.貌似一切都很顺利

iOS开发高级分享 - iOS 13 中的新框架 — MetriKit

MetriKit是iOS 13中用于收集和处理电池和性能指标的新框架.这是在WWDC今年与XCTestMetrics和Xcode Metrics组织者一起,作为一项协调一致的努力的一部分,为开发人员带来关于他们的应用程序在该领域的表现的新见解. 苹果会自动从AppStore上安装的应用程序中收集度量指标.您可以在Xcode 11中通过打开组织者(? ? ? o)并选择新的Metrics选项卡. MetriKit是Xcode组织者度量的补充,它提供了一种编程方式来接收有关应用程序在该领域中的表现的

Xcode 11.4 发布新特性

Xcode 11.4 发布新特性 Xcode 11.4 包含适用于 iOS 13.4,iPadOS 13.4,tvOS 13.4,watchOS 6.2 和 macOS Catalina 10.15.4 的SDK.Xcode 11.4 版本支持在 iOS 8+,tvOS 9+ 以及 watchOS 2+ 的设备上调试,同时需要运行 macOS Catalina 10.15.2+ 版本的 Mac. 通用 • Xcode 11.4 可以构建和分发支持 通用购买 的 macOS 应用.要将 macOS