美文网首页ios开发之路iOS15iOS大咖说
iOS 15 适配踩坑:NavigationBar、UITabB

iOS 15 适配踩坑:NavigationBar、UITabB

作者: 阳光下的叶子呵 | 来源:发表于2021-09-23 10:13 被阅读0次

    苹果前两天推出了iOS 15。秋天都等不及~~

    相关链接:ios 15.0 适配问题:NavigationBar和UITabBar失效问题

    Xcode 13 beta版,iOS 15 beta 3的系统。
    除了客户提出的问题,自己还发现了两处UI异常,不过说不定苹果能良心发现,在正式版中给修复一下。

    一、企业签名的 App 无法使用

    客户反馈说 App 不能正常打开,并且提示下面的这种信息:

    “xxx”Needs to Be Updated : The developer of this app needs to update it to work with this version of iOS.

    “xxx”需要更新 :App开发者需要更新此App以在此iOS版本上正常工作。

    <center style="box-sizing: border-box; color: rgb(201, 202, 204); font-family: Menlo, "Meslo LG", monospace; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(29, 31, 33); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">

    猜测是需要重签名或者使用最新的 Xcode 打包。

    我看苹果论坛上有人说必须使用新的 Xcode 以适配 iOS 15,但我用旧版的 Xcode 重新打了一个包,也可以解决这个问题。所以,不方便更新 Xcode 的话,可以尝试重签名试试。

    睡了一觉之究极补充: 签名问题与 Xcode 版本无关,而是 Mac 系统导致的,将 macOS 升级到 11.* Big Sur 以上再进行重新签名,可以解决 App 无法使用的问题。

    二、 NavigationBar 颜色及背景失效

    1. 问题描述

    项目中往往会自定义一个导航控制器,方便全局指定导航条的背景色、标题颜色等等。以设置背景色和标题颜色为例:

    //背景色
    self.navigationBar.barTintColor = RGB(42, 109, 240);
    //Title 颜色
    NSDictionary *titleTextAttributes = @{NSFontAttributeName:[UIFont fontWithName:@"" size:18], NSForegroundColorAttributeName:RGB(255, 255, 255)};
    [self.navigationBar setTitleTextAttributes:titleTextAttributes];
    

    但在 iOS 15上发现,指定的背景色失效了,但滚动控制器的视图时,导航条的背景又出现了。看了一眼 UINavigationBar 的 API,15中并没有新增的。倒是有几个 iOS 13新增的 API 我没用过……哈哈哈,写到这里觉得自己以前的功课落下太多了,13的更新还没学习呢😂😂😂😂😂

    2. iOS 13新增 API

    • standardAppearance : 描述导航栏以标准高度显示时要使用的外观属性。
    @property (nonatomic, readwrite, copy) UINavigationBarAppearance *standardAppearance;
    
    • compactAppearance : 描述导航栏在紧凑高度时使用的外观属性。如果未设置,则将使用标准外观。
    @property (nonatomic, readwrite, copy, nullable) UINavigationBarAppearance *compactAppearance;
    
    • scrollEdgeAppearance : 描述当关联的 UIScrollView 向上滚动时要使用的导航栏的外观属性。如果未设置,将改用修改后的standardAppearance。
    @property (nonatomic, readwrite, copy, nullable) UINavigationBarAppearance *scrollEdgeAppearance;
    
    • compactScrollEdgeAppearance : 描述当导航栏以紧凑的高度显示时,以及关联的 UIScrollView 往上滚动时,要使用的导航栏的外观属性。如果未设置,则首先尝试 scrollEdgeAppearance,如果为nil,则尝试 compactAppearance,然后尝试修改 standardAppearance。
    @property(nonatomic,readwrite, copy, nullable) UINavigationBarAppearance *compactScrollEdgeAppearance;
    

    3. 解决办法

    根据我们的问题现象,猜测是 standardAppearancescrollEdgeAppearance 需要调整,如果正常状态和滚动状态颜色一样,可以修改如下:

    NSDictionary *titleTextAttributes = @{NSFontAttributeName:[UIFont fontWithName:MAIN_FONT_FAMILY size:18], NSForegroundColorAttributeName:RGB(255, 255, 255)};
    if (@available(iOS 13.0, *)) {
     UINavigationBarAppearance *appearance = [UINavigationBarAppearance new];
     appearance.backgroundColor = RGB(42, 109, 240);
     appearance.titleTextAttributes = titleTextAttributes; 
     self.navigationBar.standardAppearance = appearance;
     self.navigationBar.scrollEdgeAppearance = appearance;
    } else {
     // Fallback on earlier versions
     self.navigationBar.barTintColor = RGB(42, 109, 240);
     [self.navigationBar setTitleTextAttributes:titleTextAttributes];
    }
    

    Bingo!颜色显示正常啦

    所以这是什么意思?强买强卖吗?必须设置 Appearance 才可以?

    4. 遗留问题

    在 Xcode 13-beta 中,必须同时指定 standardAppearancescrollEdgeAppearance 才可以。但根据苹果的注释,如果 scrollEdgeAppearance 为nil,会默认使用 standardAppearance 啊。燃鹅并不行。不知道是苹果的 bug 还是怎么的……朋友昨天叫我一起转行了,因为他觉得苹果的系统做的一年不如一年~ 😂

    三、UITabBar 背景图失效

    这个问题有点类似上一个,UITabBar 之前设置的背景图片,老版本可以,iOS 15上表现为空白。参考问题二的思路,找到了下面的 API,做个兼容就可以了。当然,遗留问题同上,必须同时指定 standardAppearancescrollEdgeAppearance 才可以……🙄……而且,如果在初始化以后,某个时机单独修改了 standardAppearance,也必须要同步指定一下 scrollEdgeAppearance ……🙄

    • API
    @property (nonatomic, readwrite, copy) UITabBarAppearance *standardAppearance;//ios 13.0.
    @property (nonatomic, readwrite, copy, nullable) UITabBarAppearance *scrollEdgeAppearance;//ios 15.0.
    
    • 老方式
    [self.tabBar setBackgroundImage:[img imageWithRenderingMode:(UIImageRenderingModeAlwaysOriginal)]];
    
    • 兼容新的API
    UIImage *img = [UIImage imageNamed:@"ahaaaaa"];
    if (@available(iOS 13.0, *)) {
     UITabBarAppearance *appearance = [[UITabBarAppearance alloc] init];
     appearance.backgroundImage = img;
     appearance.backgroundImageContentMode = UIViewContentModeScaleToFill;
     self.tabBar.standardAppearance = appearance;
     if (@available(iOS 15.0, *)) {
     self.tabBar.scrollEdgeAppearance = appearance;
     } else {
     // Fallback on earlier versions
     }
    } else {
     // Fallback on earlier versions
     [self.tabBar setBackgroundImage:[img imageWithRenderingMode:(UIImageRenderingModeAlwaysOriginal)]];
    }
    

    |

    四、UITabBarItem 文字颜色失效

    ……还是同上,新版本中 UITabBarItem 文字颜色的修改不起作用。同样是在 iOS 13 中新增的 UITabBarItemAppearance 来修改 Item 的不同状态下的不同表现。遗留问题同上。

    • 相关的类型如下,其他的API就不贴了:

    UITabBarItemAppearanceUITabBarItemStateAppearance

    /// The appearance when the tab bar item is in the normal state
    @property (nonatomic, readonly, strong) UITabBarItemStateAppearance *normal;
    
    /// The appearance when the tab bar item is in the selected state
    @property (nonatomic, readonly, strong) UITabBarItemStateAppearance *selected;
    
    /// The appearance when the tab bar item is in the disabled state
    @property (nonatomic, readonly, strong) UITabBarItemStateAppearance *disabled;
    
    /// The appearance when the tab bar item is in the focused state
    @property (nonatomic, readonly, strong) UITabBarItemStateAppearance *focused;
    
    • 兼容新的API
    //Set tabBar style.
    UIColor *normalTitleColor = RGBA(80, 80, 81, 1);
    UIColor *selectedTitleColor = RGBA(42, 109, 240, 1);
    if (@available(iOS 13.0, *)) {
     UITabBarItemAppearance *itemAppearance = [[UITabBarItemAppearance alloc] init];
     itemAppearance.normal.titleTextAttributes = @{NSForegroundColorAttributeName : normalTitleColor};
     itemAppearance.selected.titleTextAttributes = @{NSForegroundColorAttributeName : selectedTitleColor};
     UITabBarAppearance *appearance = [[UITabBarAppearance alloc] init];
     appearance.stackedLayoutAppearance = itemAppearance;
     self.tabBar.standardAppearance = appearance;
     if (@available(iOS 15.0, *)) {
     self.tabBar.scrollEdgeAppearance = appearance;
     } else {
     // Fallback on earlier versions
     }
    }else if (@available(iOS 10.0, *)) {
     self.tabBar.tintColor = normalTitleColor;
     self.tabBar.unselectedItemTintColor = selectedTitleColor;
    }else {
     // Fallback on earlier versions
    }
    

    五、 UITableView Header 高度失效

    通常 TableView 第一个分组如果不需要 Header 的话,我们会给个0.01的高度,看上去就是顶部没有空白的效果。

    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
     return 0.01;
    }
    

    但在 iOS 15上视图的顶部默认会下沉几个像素,我以为磨人的 automaticallyAdjustsScrollIndicatorInsets 这类小妖精又出现了,尝试了一下好像不是这类问题。😂

    看了一眼官网的 API 变动,发现了一个小秘密:

    The amount of padding above each section header.

    每个分组Header上方的填充量。

    @property(nonatomic) CGFloat sectionHeaderTopPadding;
    

    所以我就这样:

    if (@available(iOS 15.0, *)) {
     self.tableView.sectionHeaderTopPadding = 0;
    }
    

    试着改了一下,毕竟试试又不会怀孕。好了……有那么一瞬间我仿佛能理解苹果为什么加这个属性,貌似真的有场景会用到这个间距。冷静了一下,我发现我还是太菜了,理解不了~~~~~

    六、UITextField 的 clearButton 向右偏移

    _UITextFieldClearButton 向右偏移了一点儿点儿…有点压到边框,倒是不影响使用,然后我也不知道怎么改,谁知道告诉我一下。阿里嘎多~


    目前就发现了这几个问题。希望秋天到来的时候,开发者们不用花太多时间在 UI 适配上。

    相关文章

      网友评论

        本文标题:iOS 15 适配踩坑:NavigationBar、UITabB

        本文链接:https://www.haomeiwen.com/subject/cskggltx.html