iOS 13碰到的crash

人家一步一个脚印,咱是一步一个坑

此次更新Xcode11之后,有需要适配iOS 13的点却没有做的话,出包之后在iOS 13的设备上会crash。Xcode10不用担心,不更新就没问题嘛。

1. UIStatusBarManager

iOS 13 的暗黑模式系统最大限度的接管了状态栏的权限。应用中有获取或修改 UIStatusBar 的操作,在iOS 13都必须重新适配 ,否则都会有这个报错。
'App called -statusBar or -statusBarWindow on UIApplication: this code must be changed as there's no longer a status bar or status bar window. Use the statusBarManager object on the window scene instead.'

UIStatusBarManager.h 文件
#if (defined(USE_UIKIT_PUBLIC_HEADERS) && USE_UIKIT_PUBLIC_HEADERS) || !__has_include(<UIKitCore/UIStatusBarManager.h>)
//
//  UIStatusBarManager.h
//  UIKit
//
//  Copyright © 2018 Apple Inc. All rights reserved.
//

#import <UIKit/UIWindowScene.h>

NS_ASSUME_NONNULL_BEGIN

UIKIT_EXTERN API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos)
@interface UIStatusBarManager : NSObject

- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;

@property (nonatomic, readonly) UIStatusBarStyle statusBarStyle;
@property (nonatomic, readonly, getter=isStatusBarHidden) BOOL statusBarHidden;
@property (nonatomic, readonly) CGRect statusBarFrame; // returns CGRectZero if the status bar is hidden

@end


@interface UIWindowScene (StatusBarManager)

@property (nonatomic, readonly, nullable) UIStatusBarManager *statusBarManager API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos);

@end

NS_ASSUME_NONNULL_END

#else
#import <UIKitCore/UIStatusBarManager.h>
#endif

通过了解之后发现UIWindowScene ,可以通过获取当前window的status去获取状态栏的 statusBarStyle,statusBarHidden,statusBarFrame

就直接贴上代码

获取状态栏高度

CGFloat statusBarHeight;
    if (@available(iOS 13.0, *)) {
        statusBarHeight = [UIApplication sharedApplication].keyWindow.windowScene.statusBarManager.statusBarFrame.size.height;
    } else {
        statusBarHeight = [UIApplication sharedApplication].statusBarFrame.size.height;
    }

2. UITabBarItem

tabBar 新的设置方法, 需要的话直接到文件里查看就行。

UITabBarAppearance.h

具体不多说。

我踩的属于老坑,之前没出现的问题。下面的写法在iOS13之后,tabbar的未选中状态下的title会不显示,之后发现是设置字体颜色引起的问题

[[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:normalColor, NSFontAttributeName:[UIFont systemFontOfSize:10]} forState:UIControlStateNormal];
    [[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:selectedColor, NSFontAttributeName:[UIFont systemFontOfSize:10]} forState:UIControlStateSelected];

实则配置 选中/未选中 的title颜色适配 iOS10 后UITabBar 的一个属性即可unselectedItemTintColor

if (@available(iOS 10, *)) {
		//选中item颜色
        [UITabBar appearance].tintColor = selectedColor;
		//未选中颜色
        [UITabBar appearance].unselectedItemTintColor = normalColor;
    }
    else {
        [[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:normalColor} forState:UIControlStateNormal];
        [[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:selectedColor} forState:UIControlStateSelected];
    }

之后TabBarItem的状态显示才恢复正常。

3. UISearchBar

iOS 13里KVC是禁止了,不能像以前一样愉快的使用类似方法去设置searchBar的私有属性了。

UITextField *searchTextField =  [self valueForKey:@"_searchField"];
[searchField setValue:textColor forKeyPath:@"_placeholderLabel.textColor"];

但是 iOS 13开放了 searchBartextFild
但是 iOS 13开放了 searchBartextFild
但是 iOS 13开放了 searchBartextFild

@interface UISearchBar (UITokenSearch)

@property (nonatomic, readonly) UISearchTextField *searchTextField;

@end

可以放心大胆的使用了。 设置UISearchBar 的 placeholder

if (@available(iOS 13, *)) {
        NSAttributedString *attributPlaceholder = [[NSAttributedString alloc] initWithString:placeholder attributes:@{NSForegroundColorAttributeName : textColor, NSFontAttributeName : [UIFont systemFontOfSize:14]}];
        self.searchTextField.attributedPlaceholder = attributPlaceholder;
    }
    else {
        UITextField *searchField = [self valueForKey:@"searchField"];
        [searchField setValue:textColor forKeyPath:@"_placeholderLabel.textColor"];
    }

最后说一句, 做事要细心,用心,专心。

再次感谢 iOS 13 适配 (填坑…)

以上几个更新都必须适配否则会Crash!!!

以上几个更新都必须适配否则会Crash!!!

以上几个更新都必须适配否则会Crash!!!

下面更一些自己遇到的iOS 13下需要兼容的东西

iOS 13中注册推送的 deviceToken 改变,拿不到对应的字符串,而是拿到一个NSData类型的值

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

做出以下兼容

if (@available(iOS 13, *)) {
        const char *bytes = deviceToken.bytes;
        NSInteger count = deviceToken.length;
        NSMutableString *mutableStr = [NSMutableString string];
        for (int i = 0; i < count; i++) {
            [mutableStr appendFormat:@"%02x", bytes[i]&0x000000FF];
        }
        newDeviceToken = mutableStr.copy;
    }
    else {
        newDeviceToken = deviceToken;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值