iOS 13 适配 ING…

作者 : 开心源码 本文共39812个字,预计阅读时间需要100分钟 发布时间: 2022-05-13 共194人阅读

内容公告

赤裸裸的使用本文内容去做所谓原创的,麻烦要点脸。

Xcode11 缺失库文件导入位置变更

libstdc-6.0.9 文件下载

Xcode11下 这个目录不存在了

/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/【变更为】/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/

—-以下位置不需要改变

/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib//Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib//Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/lib/

友盟相关 更新最新版本SDK

注册新浪平台 崩溃【验证:仅在模拟器上出现】

这个应该是需要微博官方进行适配了,尝试模拟了 getUniqueStrByUUID 中的相关写法。

屏幕快照2019-06-05下午1.47.08.png

  • 暂时的处理方案:
//修复iOS13下 崩溃问题 验证为:模拟器下出现#if TARGET_IPHONE_SIMULATOR/// 交换方法实现    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        if(@available(iOS 13.0, *)){            Method origin = class_getClassMethod([UIDevice class], NSSelectorFromString(@"getUniqueStrByUUID"));            //    IMP originImp = method_getImplementation(origin);                        Method swizz = class_getClassMethod([self class], @selector(swizz_getUniqueStrByUUID));            //交换方法实现            method_exchangeImplementations(origin, swizz);        }    });#pragma mark - 获取唯一标识 新浪+ (NSString *)swizz_getUniqueStrByUUID{    CFUUIDRef  uuidObj = CFUUIDCreate(nil);//create a new UUID    //get the string representation of the UUID    NSString    *uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(nil, uuidObj);    CFRelease(uuidObj);    return uuidString ;}#endif
+[_LSDefaults sharedInstance] 崩溃问题

针对的友盟版本:
移动统计:6.0.5
消息推送:3.2.4
社会化分享:6.9.6

  • 暂时的处理方案:
@implementation NSObject (Extend)+ (void)load{        SEL originalSelector = @selector(doesNotRecognizeSelector:);    SEL swizzledSelector = @selector(sw_doesNotRecognizeSelector:);        Method originalMethod = class_getClassMethod(self, originalSelector);    Method swizzledMethod = class_getClassMethod(self, swizzledSelector);        if(class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))){        class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));    }else{        method_exchangeImplementations(originalMethod, swizzledMethod);    }}+ (void)sw_doesNotRecognizeSelector:(SEL)aSelector{    //解决 _LSDefaults 崩溃问题    if([[self description] isEqualToString:@"_LSDefaults"] && (aSelector == @selector(sharedInstance))){        //冷解决...        return;    }    [self sw_doesNotRecognizeSelector:aSelector];}

DeviceToken获取 友盟声明

#include <arpa/inet.h>- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{    if (![deviceToken isKindOfClass:[NSData class]]) return;    const unsigned *tokenBytes = (const unsigned *)[deviceToken bytes];    NSString *hexToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",                          ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),                          ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),                          ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];    NSLog(@"deviceToken:%@",hexToken);}

UITextField

通过KVC方式修改空白提醒语颜色 崩溃
[UITextField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor”];
  • 处理方案:
attributedPlaceholder
leftView、rightView 设置异常 【疑似iOS13beta4新出现】

在设置leftView 左按钮时,假如使用的是UIImageView即会出现图片无法按照用意显示的问题。

@騲尼罵人獣狂 反馈UITextFieldrightView的子视图假如使用束缚布局, 会导致rightView覆盖整个UITextField

// Confuse in beta4 iOS13UIImageView *imageIcon = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 34, 30)];//search_icon  15*15imageIcon.image = [UIImage imageNamed:@"search_icon"];imageIcon.contentMode = UIViewContentModeCenter;UITextField *txtSearch = [[UITextField alloc] init];txtSearch.leftView = imageIcon;
  • 处理方案:UIImageVIew 包一层UIView再设置给leftView 、设置leftView或者rightView不要使用束缚布局

UISearchBar

验证来源:@騲尼罵人獣狂
searchTextField属性对外暴露了,不用再通过KVC获取了。

    UISearchBar *searchBar = [[UISearchBar alloc]init];    searchBar.searchTextField

控制器相关

模态跳转样式变更

过场动画上下文机制有调整,默认调整为了卡片样式。

/* 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 other system-provided view controllers may resolve UIModalPresentationAutomatic to other concrete presentation styles. 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));[nav setModalPresentationStyle:UIModalPresentationFullScreen];
模态横屏弹出

假如希望模态视图是以横屏状态弹出,需要注意到其会受到跳转样式的影响。
默认的卡片样式,依然会以竖屏弹出。

参考链接

- (BOOL)shouldAutorotate {    return NO;}- (UIInterfaceOrientationMask)supportedInterfaceOrientations {       return UIInterfaceOrientationMaskLandscapeRight;}- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {        return UIInterfaceOrientationLandscapeRight;}

Dark Mode 颜色主题相关

UIColor 适配
 UIColor *dynamicColor =  [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * provider) { //使用 provider 判断,有时会出问题    if(keyWindow.isDark){        return darkColor;    }    return lightColor; }];
YYTextView && YYLabel 适配 完美处理的前提是 UIColor 必需正确适配

针对YY的改造–链接直达

假如你也在做该适配的话,那么很可能遇到以下的问题。
尝试了很屡次,最大的问题竟出在 UIColor
不过出现的问题,疑似和YY内部在Runloop 即将休眠时进行绘制任务具备很大的相关性。
具体起因还不能确定,等以后再深究一下。

系统体现

这里先看下系统UILabel的暗夜适配找寻一下灵感

UILabel DarkMode.png
可以看到,UILabel的绘制是调用 drawTextInRext,而翻看YY能看到其使用的 CTRunDraw()。因为一开始对UIDynamicProviderColor有误会,也尝试过解析其中打包的颜色,来通过查看CTRun的属性集来判断当前能否正确渲染。

….然而,在YYLabel应用上述方案时可能正常,但YYTeView却出现了其它的问题。
….排查中发现,某些时候UITraitCollection.currentTraitCollection解析出的颜色,和对应的状态不符。
….最终发现,colorWithDynamicProvider中回调的状态可能出现和当前系统状态不一致的情况,也就是说这个回调有点不那么可信了… 误我青春

YYLabel 适配

YYLabel.m 增加如下代码

#pragma mark - DarkMode Adapater#ifdef __IPHONE_13_0- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection{    [super traitCollectionDidChange:previousTraitCollection];        if (@available(iOS 13.0, *)) {        if([UITraitCollection.currentTraitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]){            [self.layer setNeedsDisplay];        }    } else {        // Fallback on earlier versions    }}#endif
YYTextView 适配

YYTextView.m 增加如下代码

#pragma mark - Dark mode Adapter#ifdef __IPHONE_13_0- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection{    [super traitCollectionDidChange:previousTraitCollection];        if (@available(iOS 13.0, *)) {        if([UITraitCollection.currentTraitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]){            [self _commitUpdate];        }    } else {        // Fallback on earlier versions    }}#endif

额外要做的事情

  • NSAttributedString+YYText.m 去除部分CGColor 调用
- (void)setColor:(UIColor *)color {    [self setColor:color range:NSMakeRange(0, self.length)];}- (void)setStrokeColor:(UIColor *)strokeColor {    [self setStrokeColor:strokeColor range:NSMakeRange(0, self.length)];}- (void)setStrikethroughColor:(UIColor *)strikethroughColor {    [self setStrikethroughColor:strikethroughColor range:NSMakeRange(0, self.length)];}- (void)setUnderlineColor:(UIColor *)underlineColor {    [self setUnderlineColor:underlineColor range:NSMakeRange(0, self.length)];}

UIImageView

主要发现两个问题:
1.初始化:UIImageView.image 初始化时必需设置,否则不显示 。
2.暗黑适配:图片经过拉伸解决后,会导致暗黑适配失效。

  • @不羁觅觅羊 分享的处理方案:
#pragma mark - 处理Image拉伸问题+ (UITraitCollection *)lightTrait API_AVAILABLE(ios(13.0)) {    static UITraitCollection *trait = nil;    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        trait = [UITraitCollection traitCollectionWithTraitsFromCollections:@[            [UITraitCollection traitCollectionWithDisplayScale:UIScreen.mainScreen.scale],            [UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]        ]];    });    return trait;}+ (UITraitCollection *)darkTrait API_AVAILABLE(ios(13.0)) {    static UITraitCollection *trait = nil;    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        trait = [UITraitCollection traitCollectionWithTraitsFromCollections:@[            [UITraitCollection traitCollectionWithDisplayScale:UIScreen.mainScreen.scale],            [UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark]        ]];    });    return trait;}+ (void)fixResizableImage API_AVAILABLE(ios(13.0)) {        Class klass = UIImage.class;    SEL selector = @selector(resizableImageWithCapInsets:resizingMode:);    Method method = class_getInstanceMethod(klass, selector);    if (method == NULL) {        return;    }        IMP originalImp = class_getMethodImplementation(klass, selector);    if (!originalImp) {        return;    }        IMP dynamicColorCompatibleImp = imp_implementationWithBlock(^UIImage *(UIImage *_self, UIEdgeInsets insets, UIImageResizingMode resizingMode) {            // 理论上可以判断UIColor 能否是 UIDynamicCatalogColor.class, 假如不是, 直接返回原实现; 但没必要.            UITraitCollection *lightTrait = [self lightTrait];            UITraitCollection *darkTrait = [self darkTrait];            UIImage *resizable = ((UIImage * (*)(UIImage *, SEL, UIEdgeInsets, UIImageResizingMode))                                      originalImp)(_self, selector, insets, resizingMode);            UIImage *resizableInLight = [_self.imageAsset imageWithTraitCollection:lightTrait];            UIImage *resizableInDark = [_self.imageAsset imageWithTraitCollection:darkTrait];                    if (resizableInLight) {                [resizable.imageAsset registerImage:((UIImage * (*)(UIImage *, SEL, UIEdgeInsets, UIImageResizingMode))                                                         originalImp)(resizableInLight, selector, insets, resizingMode)                                withTraitCollection:lightTrait];            }            if (resizableInDark) {                [resizable.imageAsset registerImage:((UIImage * (*)(UIImage *, SEL, UIEdgeInsets, UIImageResizingMode))                                                         originalImp)(resizableInDark, selector, insets, resizingMode)                                withTraitCollection:darkTrait];            }            return resizable;        });    class_replaceMethod(klass, selector, dynamicColorCompatibleImp, method_getTypeEncoding(method));}

绘制异常 【暂未确定能否为iOS13新发】

UIImageView绘制

应用场景:自己设置控件生成图片,绘制API会受到UIImage的拉伸方式UIImageResizingModeTile干扰。
影响:所得并不是所见

/// 常见的绘制代码UIGraphicsBeginImageContextWithOptions(contentSize,YES,[[UIScreen mainScreen] scale]);问题API:/// CGContextRef ctx = UIGraphicsGetCurrentContext();/// [self.viewContent.layer renderInContext:ctx];建议使用如下API:[self.viewContent drawViewHierarchyInRect:CGRectMake(0, 0, contentSize.width, contentSize.height) afterScreenUpdates:YES];//生成图片UIImage *image = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();
截长图

有朋友反馈 iOS13上截长图,只能截取到当前屏幕。
起因:束缚和绝对布局混用导致,截图代码和布局代码的UI设定环境调整为一致就好。

  • 随处可见的,截长图代码,原理就是设置UIView.size为实际内容size
    UIImage* shotImage = nil;    UITableView *scrollView = self.tableBase;    //临时数据    CGPoint fltOriginOffset = scrollView.contentOffset;    CGRect rectOrigin = scrollView.frame;    scrollView.contentOffset = CGPointZero;    scrollView.frame = CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height);    UIGraphicsBeginImageContextWithOptions(CGSizeMake(scrollView.contentSize.width, scrollView.contentSize.height), scrollView.opaque, 0.0);    [scrollView.layer renderInContext:UIGraphicsGetCurrentContext()];    shotImage = UIGraphicsGetImageFromCurrentImageContext();    UIGraphicsEndImageContext();        //状态还原    scrollView.contentOffset = fltOriginOffset;    scrollView.frame = rectOrigin;

UIWindow 变更

在iOS13版本下,App 任意处生成YYTextView均会导致全局的scrollsToTop 回顶功能失效。
尽管最终追查至YYTextEffectWindow中,但整个排查过程还是发现了很多新内容的。

这是正常的回顶功能调用逻辑,基于此一条条的覆写了系统相关的私有函数来判别问题出自何处。

-[UICollectionView scrollViewShouldScrollToTop:] -[UIScrollView _scrollToTopIfPossible:] ()-[UIScrollView _scrollToTopFromTouchAtScreenLocation:resultHandler:] ()-[UIWindow _scrollToTopViewsUnderScreenPointIfNecessary:resultHandler:]_block_invoke.796 ()-[UIWindow _handleScrollToTopAtXPosition:resultHandler:] ()//此处能看到有个新鲜的 UIStatusBarManager 是iOS13新添加的类,可以看到状态栏的点击事件已经被其接管了。//经过实践,出问题的时候该方法也能被正常调用故此排上以上调用栈方法。-[UIStatusBarManager _handleScrollToTopAtXPosition:] ()-[UIStatusBarManager handleTapAction:] ()

开始以为是多个UIScrollView共存时scrollsToTop的设置问题,还有UIScrollViewContentInsetAdjustmentNever的设置问题。结果都不是…
最终沿着UIScrollView 子类一直查找,找到了YYTextView 其中用到的 YYTextEffectWindow也进入了视野…

    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        if (![UIApplication isAppExtension]) {            one = [self new];            one.frame = (CGRect){.size = kScreenSize};            one.userInteractionEnabled = NO;            //此处能看到 窗口等级是高于状态栏的,但屡次尝试等级调整均无果。            one.windowLevel = UIWindowLevelStatusBar + 1;                       //元凶在这里           //所以,即便关闭了客户交互 但是它竟能够阻挡状态栏的事件,但却对常规Window的事件无任何影响...            if (@available(iOS 13.0, *)) {                //费解的结果...                one.hidden = YES;            }else{                one.hidden = NO;            }                        // for iOS 9:            one.opaque = NO;            one.backgroundColor = [UIColor clearColor];            one.layer.backgroundColor = [UIColor clearColor].CGColor;        }    });    return one;

在UIWindow 上使用addSubview增加子视图,需要注意 暗黑模式切换,并不会向子视图下发状态变更。

  • 处理方案:
获取系统暗黑切换通知(自行实现),而后重写增加到 UIWindow 的子视图 overrideUserInterfaceStyle 为正确的状态。

UIScrollView 滚动条异常偏移

屏幕旋转可能会触发系统对滚动条的自动修正
假如没有修改需求,关闭该特性就可

#ifdef __IPHONE_13_0   if (@available(iOS 13.0, *)) {       self.automaticallyAdjustsScrollIndicatorInsets = NO;   }#endif

UICollectionView 异常API

该API 在iOS13下会强制将cell置中,导致上部留白。
推测,底部应该也会有留白的情况。

#pragma mark - 修复iOS13 下滚动异常API#ifdef __IPHONE_13_0- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated{        [super scrollToItemAtIndexPath:indexPath atScrollPosition:scrollPosition animated:animated];    //修复13下 Cell滚动位置异常   if (@available(iOS 13.0, *)) {      //顶部      if(self.contentOffset.y < 0){          [self setContentOffset:CGPointZero];          return;      }          //底部      if(self.contentOffset.y > self.contentSize.height){          [self setContentOffset:CGPointMake(0, self.contentSize.height)];      }  }}#endif

UITableViewCell 异常 【疑似iOS13beta4新出现】

[self addSubView: viewObjA]
[self.contentView addSubview:viewObjB]
上面两种方式,在遇到折叠需求时。设置self.clipsToBounds=YES 可能会有布局异常

//有其余朋友反馈,遇到的情况正好相反。保险的做法 [增加如下两句] self.clipsToBounds = YES;  【无效】//此处很费解self.layer.masksTobounds = YES;  【有效】

疑似布局引擎机制有调整 【有待确定】

在调试中发现,假如代码流是这样一种状态 可能会造成 【束缚失效】
假如遇到诡异问题 需要排查下能否存在束缚和绝对布局混用的情况

[viewMain addSubView:viewA];[viewMain addSubView:viewB];// 升级 viewA 的束缚 [self.imageBackground mas_updateConstraints:^(MASConstraintMaker *make) {       make.top.mas_equalTo(50); }]; //立即升级束缚 [viewA.superview setNeedsUpdateConstraints]; [viewA.superview updateConstraintsIfNeeded]; [viewA.superview layoutIfNeeded];//升级容器束缚[viewMain mas_updateConstraints:^(MASConstraintMaker *make) {       make.... }];....其它解决逻辑....// 升级 viewA 的束缚 【代码不会生效】 [self.imageBackground mas_updateConstraints:^(MASConstraintMaker *make) {       make.top.mas_equalTo(100); }];

WKWebView

暗黑适配

要点:

  1. 模式参数通过 UA 传递
  2. 联调中出现加载闪白问题
webView.opaque = false;
WebJavascriptBridge失效
待验证

手势影响

iOS13下,假如在UITextView上附加如拖动手势,会发现假如触点落在UITextView之上极易触发第一响应者。
实际效果,可比照iOS12之前版本的体现。

!!!注意这两项即便开启也不会有改善效果!!!gesture.cancelsTouchesInView = YES;gesture.delaysTouchesBegan = YES;
  • 先看一下相关调用栈

    单击UITextView.png

iOS12下拖动UITextView.pngiOS13下拖动UITextView.png

  • 处理方案:为UITextView内部手势增加外部依赖
///UITextView override#ifdef __IPHONE_13_0//用于处理 iOS13下,可拖动UITextView场景中放大镜手势引起的异常激活编辑状态问题。-(void)addInteraction:(id<UIInteraction>)interaction{    [super addInteraction:interaction];    if(!self.otherGestureRecognizer || self.otherGestureRecognizer.count == 0){        return;    }    if([interaction isKindOfClass:NSClassFromString(@"UITextLoupeInteraction")]){        UIGestureRecognizer *delayLoupeGesture = [self.gestureRecognizers objectWithBlock:^BOOL(UIGestureRecognizer *obj) {            return [obj isKindOfClass:NSClassFromString(@"UIVariableDelayLoupeGesture")];        }];        if(delayLoupeGesture){                        [self.otherGestureRecognizer forEach:^(UIGestureRecognizer *obj) {                [delayLoupeGesture requireGestureRecognizerToFail:obj];            }];        }    }}#endif

iOS13 下文本框 — 针对YYTextView

双光标问题

注意:之前使用 __IPHONE_13_0 宏错误,应使用 @available(iOS 13.0, *)

具体方法: _updateSelectionView {......}

针对YYTextView所做的过往修改 链接直达

问题产生起因:

  1. 机制更改
  2. 之前所做的处理搜狗输入法、系统键盘单词中断问题所做的修改存在问题。
  • 机制更改
    在真机上尝试了很屡次,确认如下:
    iOS13下,只需遵循了UITextInput相关协议,在进行文本选择操作时系统会自动派生出UITextSelectionView系列组件,显然和YY自有的YYTextSelectionView冲突了。(此处隐藏一颗彩蛋)

  • 之前对YYTextView所做的代码变更,武断的注释掉了如下方法:

if (notify) [_inputDelegate selectionWillChange:self];if (notify) [_inputDelegate selectionDidChange:self];

会造成内部对文本选择相关的数据错乱,当然这种影响目前只在iOS13下能够看到体现。

  • 处理方案 :隐藏系统派生出来的UITextSelectionView相关组件
/// YYTextView.m /// 添加标记位struct {       .....       unsigned int trackingDeleteBackward : 1;  ///< track deleteBackward operation       unsigned int trackingTouchBegan : 1;  /// < track touchesBegan event} _state;/// 方法重写#pragma mark - override- (void)addSubview:(UIView *)view{        //处理蓝点问题    Class Cls_selectionGrabberDot = NSClassFromString(@"UISelectionGrabberDot");    if ([view isKindOfClass:[Cls_selectionGrabberDot class]]) {        view.backgroundColor = [UIColor clearColor];        view.tintColor = [UIColor clearColor];        view.size = CGSizeZero;    }        //获取UITextSelectionView    //处理双光标问题    Class Cls_selectionView = NSClassFromString(@"UITextSelectionView");    if ([view isKindOfClass:[Cls_selectionView class]]) {        view.backgroundColor = [UIColor clearColor];        view.tintColor = [UIColor clearColor];        view.hidden = YES;    }        [super addSubview:view];    }/// 方法修改/// Replace the range with the text, and change the `_selectTextRange`./// The caller should make sure the `range` and `text` are valid before call this method.- (void)_replaceRange:(YYTextRange *)range withText:(NSString *)text notifyToDelegate:(BOOL)notify{    if (_isExcludeNeed) {        notify = NO;    }    if (NSEqualRanges(range.asRange, _selectedTextRange.asRange)) {        //这里的代理商方法需要注释掉 【废止】        //if (notify) [_inputDelegate selectionWillChange:self];        /// iOS13 下,双光标问题 便是由此而生。        if (_state.trackingDeleteBackward)[_inputDelegate selectionWillChange:self];        NSRange newRange = NSMakeRange(0, 0);        newRange.location = _selectedTextRange.start.offset + text.length;        _selectedTextRange = [YYTextRange rangeWithRange:newRange];        //if (notify) [_inputDelegate selectionDidChange:self];        /// iOS13 下,双光标问题 便是由此而生。        if (_state.trackingDeleteBackward) [_inputDelegate selectionDidChange:self];        ///恢复标记        _state.trackingDeleteBackward = NO;    } else {    .....    .....}- (void)deleteBackward {    //标识出删除动作:用于处理双光标相关问题    _state.trackingDeleteBackward = YES;        [self _updateIfNeeded];    .....    .....}- (void)_updateSelectionView {    _selectionView.frame = _containerView.frame;    _selectionView.caretBlinks = NO;    _selectionView.caretVisible = NO;    _selectionView.selectionRects = nil;  .....  .....        if (@available(iOS 13.0, *)) {        if (_state.trackingTouchBegan) [_inputDelegate selectionWillChange:self];        [[YYTextEffectWindow sharedWindow] showSelectionDot:_selectionView];        if (_state.trackingTouchBegan) [_inputDelegate selectionDidChange:self];    }else{         [[YYTextEffectWindow sharedWindow] showSelectionDot:_selectionView];    }    if (containsDot) {        [self _startSelectionDotFixTimer];    } else {        [self _endSelectionDotFixTimer];  .....  .....}
iOS13 新添加编辑手势 —暂时禁用

编辑手势 形容借鉴
复制:三指捏合
剪切:两次三指捏合
粘贴:三指松开
撤销:三指向左划动(或者三指双击)
重做:三指向右划动
快捷菜单:三指单击

#ifdef __IPHONE_13_0- (UIEditingInteractionConfiguration)editingInteractionConfiguration{    return UIEditingInteractionConfigurationNone;}#endif

UITabbar

UITabbar 层次发生改变,无法通过设置shadowImage去掉上面的线。
@还是老徐ooo 反馈

  • 处理方案:stackoverflow 自行转化为OC哦
if #available(iOS 13, *) {  let appearance = self.tabBar.standardAppearance.copy()  appearance.backgroundImage = UIImage()  appearance.shadowImage = UIImage()  appearance.shadowColor = .clear  self.tabBar.standardAppearance = appearance} else {  self.tabBar.shadowImage = UIImage()  self.tabBar.backgroundImage = UIImage()}
UITabBar frame 设置失效
待验证

layoutSubviews 相关

//容错性更高 //具体待补充

一断毒代码 注:仅在iOS13以上版本可见

*********神奇体现*********
前提:系统旋转开关处于锁定状态
DEV 调试无任何疑问 — No Problem
Adhoc 和 Release,只需客户手动操作一次前后端切换下面的方法即死翘翘。 — Die
此问题为多种综合因素造成,各位并不肯定遇到。

#pragma mark - 旋转屏幕+(void)changeOrientation:(UIInterfaceOrientation)toOrientation{   if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {        SEL selector = NSSelectorFromString(@"setOrientation:");        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDeviceinstanceMethodSignatureForSelector:selector]];        [invocation setSelector:selector];        [invocation setTarget:[UIDevice currentDevice]];        int val = UIInterfaceOrientationLandscapeRight;        [invocation setArgument:&val atIndex:2];        [invocation invoke];    }}
  • 处理方案: 疑似函数内部栈指针错乱
要处理看起来很简单,只要要在方法函数头部增加几句不会被编译器优化掉的代码就可。#pragma mark - 旋转屏幕+(void)changeOrientation:(UIInterfaceOrientation)toOrientation{    [self uploadLog:@"旋转屏幕"];  if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {        SEL selector = NSSelectorFromString(@"setOrientation:");        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDeviceinstanceMethodSignatureForSelector:selector]];        [invocation setSelector:selector];        [invocation setTarget:[UIDevice currentDevice]];        int val = UIInterfaceOrientationLandscapeRight;        [invocation setArgument:&val atIndex:2];        [invocation invoke];    }}

状态栏相关

状态栏的显示与隐藏

【方案一】

尽管下面的方法被列为DEPRECATED,在iOS13上依然见效。

- (void)setStatusBarHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation API_DEPRECATED("Use -[UIViewController prefersStatusBarHidden]", ios(3.2, 9.0)) API_UNAVAILABLE(tvos);

【方案二】

奇淫技巧:通过复写私有方法,其实可以做到全局状态栏不显示,但并不推荐。

!!!还是不要尝试的好!!!
获取状态栏 注意本质为新创立一个状态栏,和当前系统状态栏可能不一致
        if (@available(iOS 13.0, *)) {            UIView *_localStatusBar = [[UIApplication sharedApplication].keyWindow.windowScene.statusBarManager performSelector:@selector(createLocalStatusBar)];            UIView * statusBar = [_localStatusBar performSelector:@selector(statusBar)];            // 注意此代码不生效 用于绘制           // [statusBar drawViewHierarchyInRect:statusBar.bounds afterScreenUpdates:NO];            [statusBar.layer renderInContext:context];        } else {            // Fallback on earlier versions        }
横屏时状态栏显示且在左侧或者右侧

常见于视频播放页需求
起因1:视频播放器所属的 UIViewController 未能正确旋转所致。
起因2:iOS13下API失效
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];

  • 处理方案:
允许控制器旋转,iOS13横屏时会自动隐藏状态栏。
  • 状态栏设置背景色

因为iOS13下当前状态栏实际上被系统强制接管了,是拿不到的。?? 或者者是有我没找到的API

  • 处理方案:
    UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;    UIView *viewStatusColorBlend = [[UIView alloc]initWithFrame:keyWindow.windowScene.statusBarManager.statusBarFrame];    viewStatusColorBlend.backgroundColor = Color;    [keyWindow addSubview:viewStatusColorBlend];
横屏时显示状态栏

【方案一】

针对iOS13 需要明确如下:

  1. iOS13 设施支持情况,不同设施有着不同的体现。
  2. 该方案不能保证肯定通过苹果审核,请慎重对待!!! 请慎重对待!!! 请慎重对待!!!
  3. 创立了本地状态栏后,是会对系统的状态栏造成不确定影响的,所以下面的方法谨慎的使用了 addSubViewremoveFromSuperview
  • 不支持的设施 图片来源

iOS13不支持的设施.jpg

  • 状态栏在不同设施的体现

A: iPhone X ~ iPhone … Max (刘海屏):状态栏显示时,分左、右两段,其中左上角为时间、右上角为??等信息,且在iOS13 下横屏不显示

B: iPhone7 ~ iPhone 8P (矩形屏):状态栏显示时,分左、中、右三段,其中时间居中显示,且在iOS13 下横屏不显示

C: iPAD (糊脸屏):状态栏显示时,分左、右两段,其中左上角为时间,右上角为??等信息,且在iOS13 (纠正:iPad OS13)下默认显示

总结: A 、B 两种情况需要特殊解决

  • 效果预览

Simulator Screen Shot – iPhone X? – 2019-09-27 at 16.51.25.pngSimulator Screen Shot – iPhone 8 – 2019-09-27 at 16.54.08.png

  • 处理方案: 参考上面的获取状态栏方法
/** 状态栏--iOS13 */@property (nonatomic, strong) UIView  *viewStatusBar API_AVAILABLE(ios(13.0));- (UIView *)viewStatusBar{    if (!_viewStatusBar) {#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wundeclared-selector"        _viewStatusBar = [[UIApplication sharedApplication].keyWindow.windowScene.statusBarManager performSelector:@selector(createLocalStatusBar)];        _viewStatusBar.backgroundColor = [UIColor clearColor];        _viewStatusBar.hidden = YES;        _viewStatusBar.tag = 784321;        _viewStatusBar.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;                //手动设置状态栏为白色样式        UIView *statusBar = [[_viewStatusBar valueForKey:@"_statusBar"]valueForKey:@"_statusBar"];        [statusBar performSelector:@selector(setForegroundColor:) withObject:[UIColor whiteColor]];#pragma clang diagnostic pop    }    return _viewStatusBar;}#param mark - 横屏方法- (void)setOrientationLandscapeConstraint { //状态栏解决    if (@available(iOS 13.0, *)) {        if(![self viewWithTag:784321] && !DP_IS_IPAD){            self.viewStatusBar.hidden = NO;            [self addSubview:self.viewStatusBar];            //我这里是为了避开 其它控件,具体的按各自的需求来            CGFloat fltLeftMargin = DP_IS_IPHONEX ? (-24) : 0;            CGFloat fltTopMargin = DP_IS_IPHONEX ? (-12) : 0;            UIView *leftView = DP_IS_IPHONEX ? self.lblTitle : self;                        [self.viewStatusBar mas_makeConstraints:^(MASConstraintMaker *make) {                 make.left.mas_equalTo(leftView.mas_left).offset(fltLeftMargin);                 make.top.mas_equalTo(fltTopMargin);                 make.right.mas_equalTo(0);            }];        }    }}#param mark - 竖屏方法- (void)setOrientationPortraitConstraint {     //状态栏解决    if (@available(iOS 13.0, *)) {        if (!DP_IS_IPAD) {            self.viewStatusBar.hidden = YES;            if ([self viewWithTag:784321]) {                [self.viewStatusBar removeFromSuperview];            }        }    }}
  • 原本希望是达到和爱奇艺一样的效果,但上面的方式假如顺利过审的话已经满足需求了。
    当然 假如哪位大佬知道怎样实现的,还望不吝赐教。

爱奇艺 XS Max 截取

【方案二】重点:显示系统状态栏

该方案使用原生状态栏,而非通过私有API创立。
额外注意的是:尽管能够正常显示,但对状态栏Frame修改的尝试均失败。

@implementation UIStatusBarManager (Extend)/// 更改默认配置- (CGFloat)defaultStatusBarHeightInOrientation:(UIInterfaceOrientation)orientation {    if (orientation ==  UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight ) {    /// 主要就是这里        return 20;    }    /// 此处仅做示例,实际使用需要针对不同设施进行适配。    return 44;}@end

【方案三】
印证辅助:Alook浏览器内置的视频播放器和爱奇艺的效果基本一致,作者明确了横屏状态栏是自实现,而非系统。

分析爱奇艺的实现,个人鄙见:主要讲实现方案

  1. 视频最终页构成:仅支持竖屏的控制器 + 自己设置承载视频播放器的UIWindow
  2. 横竖屏逻辑:通过弹出一个模态控制器,来控制真是的旋转方向,但其内容肯定是透明的。(具体大概意思就是 视频最终页(竖屏) —> 透明的模态控制器(横屏))
  3. 视频播放器UIWindow转场效果
  • 注意:该API已经失效,这也是很多人一直在找横竖屏替代方案的起因。
 [[UIApplication sharedApplication] setStatusBarOrientation:currentOrientation animated:NO];
  • 调试时发现的一个私有方法:猜测是用来代替上面方法的,但实际调用无效果。
setStatusBarOrientation:fromOrientation:windowScene:animationParameters:updateBlock:
小结:关于横竖屏以及状态栏的问题,总结至此。

代码规范问题相关 NSDate

命名

@frankfan1990 反馈应用切换到后端时Crash,全局断点捕获不到并且直接断进了main函数。

问题起因:
自行实现的NSDatecategory,里面有一个方法叫 +(NSInterger)now的方法。该方法在iOS13 中已有实现,具体崩溃起因待验证。

处理方案: 改写系统提供类的方法或者者新添加方法,注意避免冲突。最好将命名带有前后缀,对于属性也一样适用。

奇淫巧技请注意

三目运算符
result = x?x:y; ==> result = x?:y;

可能是因为Xcode11 编译器或者者语法器的调整,上面的技巧可能不会得到你想要的结果了。

VOIP 相关

@2742810c4ba1 反馈到后端收不到推送,并且有报错闪退。

处理方案: @叫点什么好呢 提到push 推送的data数据结构发生变更,需要升级SDK。

3D Touch && Haptic Touch

支持判断

注意:使用该判断,并且直接return的话  可能你同时也就错过了 Haptic Touch。traitCollection.forceTouchCapability == UIForceTouchCapabilityUnavailable可能是因为苹果的疏忽,Haptic Touch的能力并未和3D Touch统一。我能想到的唯一判断方式,是通过系统版本。//能否支持触摸力度检测if(self.window.traitCollection.forceTouchCapability == UIForceTouchCapabilityUnavailable){    //不支持触摸力度检测时,检测能否支持 haptic touch。    //haptic touch,判断依据 仅iOS 13.0 以上版本。    if(@available(iOS 13.0, *)) {          }else{            return;     }} 

补充

状态栏调试补充

在调试过程中,挖了少量相关数据。
下面会贴出来,目前对于状态栏问题的处理并不是很满意。
所以希望有兴趣的朋友,能够一起找寻下最佳方案。

配置及结构
  • 为什么iOS13 横屏会不显示状态栏?

    默认配置.png

  • 状态栏层级结构

    状态栏层级结构.png

私有方法挖掘
  • UIStatusBarManager
.cxx_destructsetWindowScene:_settingsDiffActionsForScene:initWithScene:_scene_setScene:windowSceneisStatusBarHiddendefaultStatusBarHeightInOrientation:statusBarStylestatusBarHeightupdateStatusBarAppearanceupdateLocalStatusBarsstatusBarHiddenstatusBarAlphasetupForSingleLocalStatusBarstatusBarFrameForStatusBarHeight:updateStatusBarAppearanceWithAnimationParameters:_updateStatusBarAppearanceWithClientSettings:transitionContext:animationParameters:_updateVisibilityForWindow:targetOrientation:animationParameters:_updateStyleForWindow:animationParameters:_updateAlpha_visibilityChangedWithOriginalOrientation:targetOrientation:animationParameters:activateLocalStatusBar:_updateLocalStatusBar:statusBarFrame_handleScrollToTopAtXPosition:_adjustedLocationForXPosition:updateStatusBarAppearanceWithClientSettings:transitionContext:deactivateLocalStatusBar:createLocalStatusBarhandleTapAction:localStatusBarssetLocalStatusBars:statusBarPartStylesisInStatusBarFadeAnimationdebugMenuHandlersetDebugMenuHandler:
  • UIStatusBar_Modern
.cxx_destruct layoutSubviews intrinsicContentSize setMode: setOrientation: currentStyle forceUpdate: statusBar setStatusBar: forceUpdateData: setEnabledPartIdentifiers: setAvoidanceFrame: frameForPartWithIdentifier: alphaForPartWithIdentifier: setAlpha:forPartWithIdentifier: setOffset:forPartWithIdentifier: jiggleLockIcon setForegroundColor:animationParameters: setStyleRequest:animationParameters: enabledPartIdentifiers setAction:forPartWithIdentifier: statusBarServer:didReceiveStatusBarData:withActions: statusBarServer:didReceiveStyleOverrides: statusBarServer:didReceiveDoubleHeightStatusString:forStyle: statusBarStateProvider:didPostStatusBarData:withActions: defaultDoubleHeight setForegroundAlpha:animationParameters: _effectiveStyleFromStyle: actionForPartWithIdentifier: offsetForPartWithIdentifier: _initWithFrame:showForegroundView:wantsServer:inProcessStateProvider: setLegibilityStyle:animationParameters: _requestStyle:partStyles:animationParameters:forced: _implicitStyleOverrideForStyle: _effectiveDataFromData:activeOverride:canUpdateBackgroundActivity: _updateWithData:force: _requestStyle:partStyles:legibilityStyle:foregroundColor:animationParameters: _updateSemanticContentAttributeFromLegacyData: _dataFromLegacyData:
  • _UIStatusBarLocalView
.cxx_destructinitWithFrame:willMoveToWindow:statusBarsetStatusBar:
  • _UIStatusBar
description.cxx_destructsetAction:actionlayoutSubviewsintrinsicContentSizemodeinitWithStyle:setMode:itemsstyleorientationsetOrientation:foregroundColorcontainerView_updateDisplayedItemsWithData:styleAttribupdateConstraintssetStyle:gestureRecognizerShouldBegin:currentDatatraitCollectionDidChange:setItems:setForegroundColor:areAnimationsEnabledsetSemanticContentAttribute:updateWithData:setStyleAttributes:styleAttributesitemWithIdentifier:regions_traitCollectionForChildEnvironment:_accessibilityHUDGestureManager:HUDItemFo_accessibilityHUDGestureManager:gestureLi_accessibilityHUDGestureManager:shouldRec_accessibilityHUDGestureManager:shouldTer_accessibilityHUDGestureManager:showHUDIt_dismissAccessibilityHUDForGestureManagerforegroundViewactionGestureRecognizeravoidanceFramesetEnabledPartIdentifiers:setAvoidanceFrame:frameForPartWithIdentifier:alphaForPartWithIdentifier:setAlpha:forPartWithIdentifier:setOffset:forPartWithIdentifier:enabledPartIdentifierssetOverlayData:setAction:forPartWithIdentifier:setStyle:forPartWithIdentifier:overlayDataupdateCompletionHandlersetUpdateCompletionHandler:setForegroundView:visualProvider_forceLayoutEngineSolutionInRationalEdgesresizeSubviewsWithOldSize:currentAggregatedDataupdateWithAnimations:styleAttributesForStyle:displayItemIdentifiersInRegionsWithIdentiframeForDisplayItemWithIdentifier:frameForPartWithIdentifier:includeInternadataAggregatordisplayItemWithIdentifier:regionWithIdentifier:stateForDisplayItemWithIdentifier:setDisplayItemStates:_updateWithAggregatedData:statusBarGesture:_setVisualProviderClass:_visualProviderClass_prepareVisualProviderIfNeeded_effectiveTargetScreen_updateStyleAttributes_performWithInheritedAnimation:_effectiveStyleFromStyle:_updateWithData:completionHandler:_prepareAnimations:_performAnimations:_fixupDisplayItemAttributes_delayUpdatesWithKeys:fromAnimation:_updateRegionItems_rearrangeOverflowedItems_frameForActionable:actionInsets:_gestureRecognizer:touchInsideActionable:_gestureRecognizer:pressInsideActionable:_frameForActionable:_pressFrameForActionable:_gestureRecognizer:isInsideActionable:_regionsForPartWithIdentifier:includeInte_actionablesForPartWithIdentifier:include_itemWithIdentifier:createIfNeeded:_statusBarWindowForAccessibilityHUD_setVisualProviderClassName:_visualProviderClassNameresetVisualProvideractionForPartWithIdentifier:offsetForPartWithIdentifier:styleForPartWithIdentifier:dependentDataEntryKeysanimationContextIditemsDependingOnKeys:itemIdentifiersInRegionsWithIdentifiers:dataEntryKeysForItemsWithIdentifiers:targetScreensetTargetScreen:displayItemStatestargetActionablesetTargetActionable:accessibilityHUDGestureManagersetAccessibilityHUDGestureManager:
相关数据 看了这些就了解了别人是怎样挖到信息的
(lldb) po [statusBar performSelector:@selector(currentData)]<_UIStatusBarData: 0x7fee29fdada0: mainBatteryEntry=<_UIStatusBarDataBatteryEntry: 0x600001713c90: isEnabled=1, capacity=100, state=2, saverModeActive=0, prominentlyShowsDetailString=0, detailString=100%>, secondaryCellularEntry=<_UIStatusBarDataCellularEntry: 0x600003c4d9e0: isEnabled=1, rawValue=0, displayValue=0, displayRawValue=0, status=0, lowDataModeActive=0, type=5, wifiCallingEnabled=0, callForwardingEnabled=0, showsSOSWhenDisabled=0>, backNavigationEntry=<_UIStatusBarDataStringEntry: 0x60000191e540: isEnabled=0>, vpnEntry=<_UIStatusBarDataEntry: 0x600001aae360: isEnabled=0>,radarEntry=<_UIStatusBarDataBoolEntry: 0x600001aae280: isEnabled=0, boolValue=0>, rotationLockEntry=<_UIStatusBarDataEntry: 0x600001aadf20: isEnabled=0>, dateEntry=<_UIStatusBarDataStringEntry: 0x60000191e560: isEnabled=1, stringValue=Thu Sep 26>, quietModeEntry=<_UIStatusBarDataBoolEntry: 0x600001aae250: isEnabled=0, boolValue=0>, timeEntry=<_UIStatusBarDataStringEntry: 0x60000191e580: isEnabled=1, stringValue=5:15 PM>, personNameEntry=<_UIStatusBarDataStringEntry: 0x60000191e5a0: isEnabled=0>, cellularEntry=<_UIStatusBarDataCellularEntry: 0x600003c4da40: isEnabled=1, rawValue=0, displayValue=0, displayRawValue=0, status=1, lowDataModeActive=0, type=5, string=Carrier, wifiCallingEnabled=0, callForwardingEnabled=0, showsSOSWhenDisabled=0>, assistantEntry=<_UIStatusBarDataEntry: 0x600001aae210: isEnabled=0>, bluetoothEntry=<_UIStatusBarDataBluetoothEntry: 0x60000191e5c0: isEnabled=0, state=0>, ttyEntry=<_UIStatusBarDataEntry: 0x600001aacbc0: isEnabled=0>, voiceControlEntry=<_UIStatusBarDataVoiceControlEntry: 0x60000191e5e0: isEnabled=0, type=0>, carPlayEntry=<_UIStatusBarDataEntry: 0x600001aacc00: isEnabled=0>, wifiEntry=<_UIStatusBarDataWifiEntry: 0x6000003b2880: isEnabled=1, rawValue=0, displayValue=3, displayRawValue=0, status=5, lowDataModeActive=0, type=0>, liquidDetectionEntry=<_UIStatusBarDataEntry: 0x600001aae160: isEnabled=0>, shortTimeEntry=<_UIStatusBarDataStringEntry: 0x60000191e600: isEnabled=1, stringValue=5:15>, studentEntry=<_UIStatusBarDataEntry: 0x600001aaeac0: isEnabled=0>, tetheringEntry=<_UIStatusBarDataTetheringEntry: 0x60000191e620: isEnabled=0, connectionCount=0>, alarmEntry=<_UIStatusBarDataEntry: 0x600001aae0e0: isEnabled=0>, activityEntry=<_UIStatusBarDataActivityEntry: 0x60000191e640: isEnabled=0, type=0, displayId=com.driver.feng>, locationEntry=<_UIStatusBarDataLocationEntry: 0x60000191e660: isEnabled=0, type=1>, airPlayEntry=<_UIStatusBarDataEntry: 0x600001aadfc0: isEnabled=0>, deviceNameEntry=<_UIStatusBarDataStringEntry: 0x60000191e680: isEnabled=0>, lockEntry=<_UIStatusBarDataLockEntry: 0x60000191e6a0: isEnabled=0, unlockFailureCount=0>, electronicTollCollectionEntry=<_UIStatusBarDataBoolEntry: 0x600001aae030: isEnabled=0, boolValue=0>, thermalEntry=<_UIStatusBarDataThermalEntry: 0x60000191e6c0: isEnabled=0, color=0, sunlightMode=0>, backgroundActivityEntry=<_UIStatusBarDataBackgroundActivityEntry: 0x600001713ed0: isEnabled=0, type=0>, forwardNavigationEntry=<_UIStatusBarDataStringEntry: 0x60000191e700: isEnabled=0>, airplaneModeEntry=<_UIStatusBarDataEntry: 0x600001aadfa0: isEnabled=0>>
(lldb) po [statusBar performSelector:@selector(items)]{    "<_UIStatusBarIdentifier: 0x600001907300: object=_UIStatusBarIndicatorTTYItem>" = "<_UIStatusBarIndicatorTTYItem: 0x6000003b1d40: identifier=<_UIStatusBarIdentifier: 0x600001907300: object=_UIStatusBarIndicatorTTYItem>>";    "<_UIStatusBarIdentifier: 0x600001903a00: object=_UIStatusBarTimeItem>" = "<_UIStatusBarTimeItem: 0x600003b7f610: identifier=<_UIStatusBarIdentifier: 0x600001903a00: object=_UIStatusBarTimeItem>>";    "<_UIStatusBarIdentifier: 0x600001907380: object=_UIStatusBarIndicatorAlarmItem>" = "<_UIStatusBarIndicatorAlarmItem: 0x6000003b1e00: identifier=<_UIStatusBarIdentifier: 0x600001907380: object=_UIStatusBarIndicatorAlarmItem>>";    "<_UIStatusBarIdentifier: 0x600001906f80: object=_UIStatusBarSpacerItem>" = "<_UIStatusBarSpacerItem: 0x60000177ea00: identifier=<_UIStatusBarIdentifier: 0x600001906f80: object=_UIStatusBarSpacerItem>>";    "<_UIStatusBarIdentifier: 0x600001903d60: object=_UIStatusBarActivityItem_Split>" = "<_UIStatusBarActivityItem_Split: 0x6000003b2000: identifier=<_UIStatusBarIdentifier: 0x600001903d60: object=_UIStatusBarActivityItem_Split>>";    "<_UIStatusBarIdentifier: 0x600001903960: object=_UIStatusBarCellularCondensedItem>" = "<_UIStatusBarCellularCondensedItem: 0x600002aa8ea0: identifier=<_UIStatusBarIdentifier: 0x600001903960: object=_UIStatusBarCellularCondensedItem>>";    "<_UIStatusBarIdentifier: 0x600001903a80: object=_UIStatusBarVoiceControlPillItem>" = "<_UIStatusBarVoiceControlPillItem: 0x600003b7f980: identifier=<_UIStatusBarIdentifier: 0x600001903a80: object=_UIStatusBarVoiceControlPillItem>>";    "<_UIStatusBarIdentifier: 0x600001907400: object=_UIStatusBarIndicatorRotationLockItem>" = "<_UIStatusBarIndicatorRotationLockItem: 0x6000003b1e40: identifier=<_UIStatusBarIdentifier: 0x600001907400: object=_UIStatusBarIndicatorRotationLockItem>>";    "<_UIStatusBarIdentifier: 0x600001907000: object=_UIStatusBarBluetoothItem>" = "<_UIStatusBarBluetoothItem: 0x6000003b1f00: identifier=<_UIStatusBarIdentifier: 0x600001907000: object=_UIStatusBarBluetoothItem>>";    "<_UIStatusBarIdentifier: 0x600001906ee0: object=_UIStatusBarIndicatorAirplaneModeItem>" = "<_UIStatusBarIndicatorAirplaneModeItem: 0x6000003b2080: identifier=<_UIStatusBarIdentifier: 0x600001906ee0: object=_UIStatusBarIndicatorAirplaneModeItem>>";    "<_UIStatusBarIdentifier: 0x600001907760: object=_UIStatusBarBuildVersionItem>" = "<_UIStatusBarBuildVersionItem: 0x60000177e310: identifier=<_UIStatusBarIdentifier: 0x600001907760: object=_UIStatusBarBuildVersionItem>>";    "<_UIStatusBarIdentifier: 0x600001906d20: object=_UIStatusBarIndicatorVPNItem>" = "<_UIStatusBarIndicatorVPNItem: 0x6000003b1fc0: identifier=<_UIStatusBarIdentifier: 0x600001906d20: object=_UIStatusBarIndicatorVPNItem>>";    "<_UIStatusBarIdentifier: 0x600001907480: object=_UIStatusBarIndicatorQuietModeItem>" = "<_UIStatusBarIndicatorQuietModeItem: 0x6000003b1e80: identifier=<_UIStatusBarIdentifier: 0x600001907480: object=_UIStatusBarIndicatorQuietModeItem>>";    "<_UIStatusBarIdentifier: 0x6000019075a0: object=_UIStatusBarActivityItem_SyncOnly>" = "<_UIStatusBarActivityItem_SyncOnly: 0x60000177dad0: identifier=<_UIStatusBarIdentifier: 0x6000019075a0: object=_UIStatusBarActivityItem_SyncOnly>>";    "<_UIStatusBarIdentifier: 0x6000019076c0: object=_UIStatusBarIndicatorLiquidDetectionItem>" = "<_UIStatusBarIndicatorLiquidDetectionItem: 0x6000003b1f40: identifier=<_UIStatusBarIdentifier: 0x6000019076c0: object=_UIStatusBarIndicatorLiquidDetectionItem>>";    "<_UIStatusBarIdentifier: 0x600001907080: object=_UIStatusBarThermalItem>" = "<_UIStatusBarThermalItem: 0x6000003b1c80: identifier=<_UIStatusBarIdentifier: 0x600001907080: object=_UIStatusBarThermalItem>>";    "<_UIStatusBarIdentifier: 0x600001906dc0: object=_UIStatusBarSecondaryCellularExpandedItem>" = "<_UIStatusBarSecondaryCellularExpandedItem: 0x60000366c380: identifier=<_UIStatusBarIdentifier: 0x600001906dc0: object=_UIStatusBarSecondaryCellularExpandedItem>>";    "<_UIStatusBarIdentifier: 0x600001907500: object=_UIStatusBarIndicatorLocationItem>" = "<_UIStatusBarIndicatorLocationItem: 0x6000003b1ec0: identifier=<_UIStatusBarIdentifier: 0x600001907500: object=_UIStatusBarIndicatorLocationItem>>";    "<_UIStatusBarIdentifier: 0x600001907100: object=_UIStatusBarIndicatorAssistantItem>" = "<_UIStatusBarIndicatorAssistantItem: 0x6000003b1cc0: identifier=<_UIStatusBarIdentifier: 0x600001907100: object=_UIStatusBarIndicatorAssistantItem>>";    "<_UIStatusBarIdentifier: 0x600001907620: object=_UIStatusBarBatteryItem>" = "<_UIStatusBarBatteryItem: 0x600003b7f4d0: identifier=<_UIStatusBarIdentifier: 0x600001907620: object=_UIStatusBarBatteryItem>>";    "<_UIStatusBarIdentifier: 0x600001903de0: object=_UIStatusBarNavigationItem>" = "<_UIStatusBarNavigationItem: 0x60000177fc90: identifier=<_UIStatusBarIdentifier: 0x600001903de0: object=_UIStatusBarNavigationItem>>";    "<_UIStatusBarIdentifier: 0x600001907180: object=_UIStatusBarIndicatorAirPlayItem>" = "<_UIStatusBarIndicatorAirPlayItem: 0x6000003b1d00: identifier=<_UIStatusBarIdentifier: 0x600001907180: object=_UIStatusBarIndicatorAirPlayItem>>";    "<_UIStatusBarIdentifier: 0x600001906c60: object=_UIStatusBarWifiItem>" = "<_UIStatusBarWifiItem: 0x6000003b2480: identifier=<_UIStatusBarIdentifier: 0x600001906c60: object=_UIStatusBarWifiItem>>";    "<_UIStatusBarIdentifier: 0x600001903b60: object=_UIStatusBarVoiceControlItem>" = "<_UIStatusBarVoiceControlItem: 0x6000003b1f80: identifier=<_UIStatusBarIdentifier: 0x600001903b60: object=_UIStatusBarVoiceControlItem>>";    "<_UIStatusBarIdentifier: 0x600001907200: object=_UIStatusBarIndicatorCarPlayItem>" = "<_UIStatusBarIndicatorCarPlayItem: 0x6000003b1d80: identifier=<_UIStatusBarIdentifier: 0x600001907200: object=_UIStatusBarIndicatorCarPlayItem>>";    "<_UIStatusBarIdentifier: 0x600001903be0: object=_UIStatusBarPillBackgroundActivityItem>" = "<_UIStatusBarPillBackgroundActivityItem: 0x600003c4d560: identifier=<_UIStatusBarIdentifier: 0x600001903be0: object=_UIStatusBarPillBackgroundActivityItem>>";    "<_UIStatusBarIdentifier: 0x600001906b20: object=_UIStatusBarCellularExpandedItem>" = "<_UIStatusBarCellularExpandedItem: 0x60000366c280: identifier=<_UIStatusBarIdentifier: 0x600001906b20: object=_UIStatusBarCellularExpandedItem>>";    "<_UIStatusBarIdentifier: 0x600001907280: object=_UIStatusBarIndicatorStudentItem>" = "<_UIStatusBarIndicatorStudentItem: 0x6000003b1dc0: identifier=<_UIStatusBarIdentifier: 0x600001907280: object=_UIStatusBarIndicatorStudentItem>>";}
(lldb) po [statusBar performSelector:@selector(containerView)]<_UIStatusBarForegroundView: 0x7fee31804f30; frame = (0 0; 375 44); layer = <CALayer: 0x600001907720>>
(lldb) po [statusBar performSelector:@selector(setForegroundColor:) withObject:[UIColor whiteColor]]UICachedDeviceWhiteColor
(lldb) po [statusBar performSelector:@selector(styleAttributes)]<_UIStatusBarStyleAttributes: 0x60000332fd40: style=-6485417468062910266, mode=-6485417468062910314, traitCollection=<UITraitCollection: 0x600002db61c0; UserInterfaceIdiom = Phone, DisplayScale = 2, DisplayGamut = P3, HorizontalSizeClass = Compact, VerticalSizeClass = Compact, UserInterfaceStyle = Light, UserInterfaceLayoutDirection = LTR, ForceTouchCapability = Unavailable, PreferredContentSizeCategory = L, AccessibilityContrast = Normal, UserInterfaceLevel = Base>, effectiveLayoutDirection=0, iconScale=1, symbolScale=1, textColor=UIExtendedGrayColorSpace 1 1, imageTintColor=UIExtendedGrayColorSpace 1 1, imageDimmedTintColor=UIExtendedGrayColorSpace 1 0.2, imageNamePrefixes=(    "Split_",    "Black_",    "Item_")>

留言的朋友,把问题形容清楚了再po出来呗!

假如本文对您有用,点个?? 我就满足了~

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » iOS 13 适配 ING…

发表回复