iOS开发之iOS13 适配

302 阅读4分钟

UIWebview 将被废止

作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:812157648,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!

UITextField 的私有属性 _placeholderLabel

[self.textField setValue:self.placeholderColor forKeyPath:@"_placeholderLabel.textColor"];

居然崩溃了,错误信息如下

'Access to UITextField's _placeholderLabel ivar is prohibited. This is an application bug' 

解决方法

方案A:
 
UITextField有个attributedPlaceholder的属性,我们可以自定义这个富文本来达到我们需要的结果。
 
NSMutableAttributedString *placeholderString = [[NSMutableAttributedString alloc] initWithString:placeholder attributes:@{NSForegroundColorAttributeName : self.placeholderColor}];
_textField.attributedPlaceholder = placeholderString;
 
 
方案B:
 
#import <objc/runtime.h>
 
 
Ivar ivar =  class_getInstanceVariable([UITextField class], "_placeholderLabel");
UILabel *placeholderLabel = object_getIvar(textField, ivar);
placeholderLabel.textColor = [UIColor whiteColor];

iOS 13 通过 KVC 方式修改私有属性,有 Crash 风险,谨慎使用!并不是所有KVC都会Crash,要尝试!

MPMoviePlayerController 在iOS 13已经不能用了

'MPMoviePlayerController is no longer available. Use AVPlayerViewController in AVKit.' 

解决方案:

既然不能再用了,那只能换掉了。替代方案就是AVKit里面的那套播放器。

iOS 13 DeviceToken有变化

NSString *dt = [deviceToken description];
dt = [dt stringByReplacingOccurrencesOfString: @"<" withString: @""];
dt = [dt stringByReplacingOccurrencesOfString: @">" withString: @""];
dt = [dt stringByReplacingOccurrencesOfString: @" " withString: @""];
这段代码运行在 iOS 13 上已经无法获取到准确的DeviceToken字符串了,iOS 13 通过[deviceToken description]获取到的内容已经变了。

解决方案

方案A:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    if (![deviceToken isKindOfClass:[NSData class]]) return;
    const unsigned *tokenBytes = [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);
}
 
方案B:
 
NSMutableString *deviceTokenString = [NSMutableString string];
const char *bytes = deviceToken.bytes;
NSInteger count = deviceToken.length;
for (int i = 0; i < count; i++) {
    [deviceTokenString appendFormat:@"%02x", bytes[i]&0x000000FF];
}
 

UITableViewCell的UITableViewCellAccessoryDisclosureIndicator显示不正常

解决方案:
cell.accessoryView = [[UIImageView alloc] initWithImage:...];
使用图片来显示。

Sign in with Apple -提供第三方登录的注意啦

解决方案

附上官方Demo:点我下载

控制器的 modalPresentationStyle 默认值变了

查阅了下 UIModalPresentationStyle枚举定义,赫然发现iOS 13新加了一个枚举值:
typedef NS_ENUM(NSInteger, UIModalPresentationStyle) {
    UIModalPresentationFullScreen = 0,
    UIModalPresentationPageSheet API_AVAILABLE(ios(3.2)) API_UNAVAILABLE(tvos),
    UIModalPresentationFormSheet API_AVAILABLE(ios(3.2)) API_UNAVAILABLE(tvos),
    UIModalPresentationCurrentContext API_AVAILABLE(ios(3.2)),
    UIModalPresentationCustom API_AVAILABLE(ios(7.0)),
    UIModalPresentationOverFullScreen API_AVAILABLE(ios(8.0)),
    UIModalPresentationOverCurrentContext API_AVAILABLE(ios(8.0)),
    UIModalPresentationPopover API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(tvos),
    UIModalPresentationBlurOverFullScreen API_AVAILABLE(tvos(11.0)) API_UNAVAILABLE(ios) API_UNAVAILABLE(watchos),
    UIModalPresentationNone API_AVAILABLE(ios(7.0)) = -1,
    UIModalPresentationAutomatic API_AVAILABLE(ios(13.0)) = -2,
};

解决方法

方案A:
如果你完全接受苹果的这个默认效果,那就不需要去修改任何代码
如果,你原来就比较细心,已经设置了modalPresentationStyle的值,那你也不会有这个影响
对于想要找回原来默认交互的同学,直接设置如下即可:
 
self.modalPresentationStyle = UIModalPresentationOverFullScreen;
 
 
方案B:
如果要一次全局更改的话,设置UIViewController Catagory即可以解决:
 
@implementation UIViewController(modalPresentationStyle)
 
- (UIModalPresentationStyle)modalPresentationStyle{
    if (@available(iOS 13.0, *)) {
        if ([self isKindOfClass:[UIActivityViewController class]]) {
            return UIModalPresentationPageSheet;
        }else{
            return UIModalPresentationFullScreen;
        }
    }
    return UIModalPresentationPopover;
}

即将废弃的 LaunchImage

从 iOS 8 的时候,苹果就引入了 LaunchScreen,我们可以设置 LaunchScreen来作为启动页。当然,现在你还可以使用LaunchImage来设置启动图。不过使用LaunchImage的话,要求我们必须提供各种屏幕尺寸的启动图,来适配各种设备,随着苹果设备尺寸越来越多,这种方式显然不够 Flexible。而使用 LaunchScreen的话,情况会变的很简单, LaunchScreen是支持AutoLayout+SizeClass的,所以适配各种屏幕都不在话下。

注意啦⚠️,从2020年4月开始,所有使⽤ iOS13 SDK的 App将必须提供 LaunchScreen,LaunchImage即将退出历史舞台*。

UISearchBar显示问题

SearchBar的高度只有1px

  1. 升级到iOS13,UISearchController上的SearchBar显示异常,查看后发现对应的高度只有1px,目前没找到具体导致的原因,

  2. 解决办法是: 使用KVO监听frame值变化后设置去应该显示的高度

黑线处理crash

  1. 之前为了处理搜索框的黑线问题会遍历后删除UISearchBarBackground,在iOS13会导致UI渲染失败crash;

  2. 解决办法是: 设置UISearchBarBackground的layer.contents为nil

TabBar红点偏移

  1. 如果之前有通过TabBar上图片位置来设置红点位置,在iOS13上会发现显示位置都在最左边去了。遍历UITabBarButton的subViews发现只有在TabBar选中状态下才能取到UITabBarSwappableImageView,

  2. 解决办法是: 修改为通过UITabBarButton的位置来设置红点的frame

参考文章

iOS13适配宝典

原文作者:沐雨07

原文地址:blog.csdn.net/shifang07/a…