xcode13环境下iOS15兼容问题汇总

一、调用canOpenURL的差异

通过xcode13运行的APP,在iOS15系统上会限制info.plist的scheme白名单个数,前50个scheme有效,如果超出50个,调用canOpenURL会一直返回NO,无论你的手机是否安装该URL Scheme的应用。

苹果官网对canOpenURL方法的调整做了说明,希望APP内减少对scheme的依赖,通过Universal Link的方式去实现应用跳转。

/// 手机安装了美团APP,如果imeituan添加在列表的第49个,isInstall为YES
BOOL isInstall = [[UIApplication sharedApplication] canOpenURL:@"imeituan://"];

/// 手机安装了美团APP,如果imeituan添加在列表的第51个,isInstall为NO
BOOL isInstall = [[UIApplication sharedApplication] canOpenURL:@"imeituan://"];

xcode13环境下iOS15兼容问题汇总_第1张图片

二、UITableView / UICollectionView的属性差异

在iOS15系统中,在使用UITableViewStylePlain初始化tableView的时候,会发现section header多出了一截,默认顶部边距为22px。可设置sectionHeaderTopPadding属性修改其默认值。

/// 局部设置
if (@available(iOS 15.0, *)) {
    _tableView.sectionHeaderTopPadding = 0;
}

/// 全局设置
if (@available(iOS 15.0, *)) {
    [UITableView appearance].sectionHeaderTopPadding = 0;
}

iOS15之后UITableView / UICollectionView新增了prefetchingEnabled属性-预取开关,默认是开启状态。在没有使用该功能的前提下,需要手动将其关闭,否则列表在滑动时会出现部分空白的情况。 预取API使用示例:Prefetching Collection View Data 

/// 局部设置
if (@available(iOS 15.0, *)) {
    _tableView.prefetchingEnabled = NO;
}

/// 全局设置
if (@available(iOS 15.0, *)) {
    [UITableView appearance].prefetchingEnabled = NO;
}

三、UINavigationBar样式设置的差异 

xcode13环境下iOS15兼容问题汇总_第2张图片

iOS13后新增standardAppearancescrollEdgeAppearance属性,可以用来设置NavigationBar两种状态的样式,常规、页面滚动到Bar边缘(contentOffset.y<=Bar.height & >=0)两种状态。

1、在iOS15之前,scrollEdgeAppearance可以默认不设置,NavigaitonBar样式不会受到页面滚动的影响;而在iOS15之后,scrollEdgeAppearance没有设置则为透明样式,页面滚动到Bar边缘会出现standardAppearance样式与scrollEdgeAppearance样式的过渡效果。如果想统一样式可以设置为同一个UINavigationBarAppearance对象。

2、如果没有设置scrollEdgeAppearance,通过xcode13运行后的APP,在iOS15系统上,导航页面手势滑出时,会出现导航栏变黑的情况,如下方图片所示。

xcode13环境下iOS15兼容问题汇总_第3张图片

具体代码实现:

/// NavigationController中
if (@available(iOS 13.0, *)) {
    UINavigationBarAppearance *navigationBarAppearance = [[UINavigationBarAppearance alloc] init];
    navigationBarAppearance.backgroundColor = [UIColor grayColor];
    navigationBarAppearance.titleTextAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:19]};
    self.navigationBar.standardAppearance = navigationBarAppearance;
    self.navigationBar.scrollEdgeAppearance = navigationBarAppearance;
} else {
    self.navigationBar.barTintColor = [UIColor grayColor];
    self.navigationBar.titleTextAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:19]};
}

/// 全局设置
if (@available(iOS 13.0, *)) {
    UINavigationBarAppearance *navigationBarAppearance = [[UINavigationBarAppearance alloc] init];
    navigationBarAppearance.backgroundColor = [UIColor grayColor];
    navigationBarAppearance.titleTextAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:19]};
    [UINavigationBar appearance].standardAppearance = navigationBarAppearance;
    [UINavigationBar appearance].scrollEdgeAppearance = navigationBarAppearance;
} else {
    [UINavigationBar appearance].barTintColor = [UIColor grayColor];
    [UINavigationBar appearance].titleTextAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:19]};
}

四、UITabBar主题设置的差异

与UINavigationBar类似,不过UITabBar的scrollEdgeAppearance属性是在iOS15之后才有的。

/// TabBarController中
if (@available(iOS 13.0, *)) {
    UITabBarAppearance *tabBarAppearance = [[UITabBarAppearance alloc] init];
    tabBarAppearance.backgroundColor = [UIColor grayColor];
    self.tabBar.standardAppearance = tabBarAppearance;
    /// iOS15没有设置滚动边缘样式会出现过渡效果
    if (@available(iOS 15.0, *)) {
        self.tabBar.scrollEdgeAppearance = tabBarAppearance;
    }
} else {
    self.tabBar.barTintColor = [UIColor grayColor];
}

五、UITabBar添加view控件的crash容错 

 在UITabBar中,遍历出来的subView默认为UITabBarItem,xcode13编译环境下,如果UITabBar中添加自定义的view控件,个别机型(不限于iOS15)会出现调用不到UITabBarItem属性及方法,而导致crash,所以该view控件需要包含以下属性以及方法实现。

/// MKTabBarItem为UITabbar的subView
@interface MKTabBarItem : UIView

/* 模拟UITabBarItem属性,兼容UITabbar遍历subViews使用UITabBarItem的属性,导致的crash */
@property (nonatomic, copy)   NSString *title;
@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) UIImage *selectedImage;
@property (nonatomic, strong) UIImage *unselectedImage;

/* 兼容UITabbar遍历subViews使用UITabBarItem的方法,导致的crash */
- (BOOL)isSystemItem;

@end


@implementation MKTabBarItem

- (BOOL)isSystemItem {
    return NO;
}

@end

你可能感兴趣的:(Objective-C,xcode13,iOS15,系统兼容,汇总)