iOS11的一些新特性
iOS 11 为整个生态系统的 UI 带来了丰富多彩的新风格。在增加用户体验的同时不免也会对我们的现有App带来一些异常,需要去适配。
1.UIKit Bars的改版
1.在浏览功能上的大标题视图(向上滑动后标题会回到原来的UI效果)、横屏状态下tab上的文字和icon会变为左右排列。
![](https://img.haomeiwen.com/i3021135/908e8910d2058287.png)
当然,如果图标和文字觉得太小了,可以长按item进行放大操作。具体只需要添加代码
![](https://img.haomeiwen.com/i3021135/c8eecfa4c372bcbf.png)
2. iOS11导航栏
- 设置导航栏大标题:
navigationBar.prefersLargeTitles
,显示的时机可以用navigationItem.largeTitleDisplayMode
设置枚举值。 - 设置导航栏搜索控制器
searchController : self.navigationItem.searchController = searchController
3.上面设置titleView
为customView
时出现宽度缩小的问题 (这个网上提到了这个问题,但是我自定义代码并没有出现这个情况)
3.调整相册权限的key
NSPhotoLibraryUsageDescription
改为 NSPhotoLibraryAddUsageDescription
。(beta版本好像又改过来了,我现在没有调整key也是可以访问相册的)
4.近场通讯
首先也要在info.plist配置NFCReaderUsageDescription
5.无线配备
6. 弃用API,scrollview和tableview的改变
iOS11弃用了automaticallyAdjustsScrollViewInsets
属性,新增contentInsetAdjustmentBehavior
来替代它。这可能使得一些刷新出现头部错乱。contentInsetAdjustmentBehavior
其实是一个枚举值。用来管理adjustedContentInset
- -
automatic
和scrollableAxes
一样,scrollView
会自动计算和适应顶部和底部的内边距并且在scrollView
不可滚动时,也会设置内边距. - -
scrollableAxes
自动计算内边距. - -
never
不计算内边距 - -
always
根据safeAreaInsets
计算内边距
我们这里要设置为 never
,所以我们的OC代码可以这样写:
声明tableView的位置 添加下面代码
if (@available(iOS 11.0, *)) {
self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
self.tableView.contentInset = UIEdgeInsetsMake(0, 0,0, 0);
self.tableView.scrollIndicatorInsets = _tableView.contentInset;
}
在iOS8引入
Self-Sizing
之后,我们可以通过实现estimatedRowHeight
相关的属性来展示动态的内容。Self-Sizing
在iOS11下是默认开启的,Headers,Footers, and cells都默认开启Self-Sizing
,所有estimated
高度默认值从iOS11之前的 0 改变为UITableViewAutomaticDimension
.
如果目前项目中没有使用estimateRowHeight
属性,在iOS11的环境下就要注意了,因为开启Self-Sizing
之后,tableView是使用estimateRowHeight
属性的,就会可能会使代理方法设置高度失效.
通过以下方法进行关闭:
Table Views:separatorInset 扩展
iOS 7 引入separatorInset
属性,用以设置 cell 的分割线边距,在 iOS 11 中对其进行了扩展。可以通过新增的UITableViewSeparatorInsetReference
枚举类型的separatorInsetReference
属性来设置separatorInset
属性的参照值。
typedef NS_ENUM(NSInteger, UITableViewSeparatorInsetReference) {
UITableViewSeparatorInsetFromCellEdges, //默认值,表示separatorInset是从cell的边缘的偏移量
UITableViewSeparatorInsetFromAutomaticInsets //表示separatorInset属性值是从一个insets的偏移量
}
7.拖放
8.文件管理
9.tableView右滑操作
增加了两个代理方法来取代原来的代理方法(tableView: editActionsForRowAtIndexPath:
)
// Swipe actions
// These methods supersede -editActionsForRowAtIndexPath: if implemented
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath
创建 UIContextualAction
对象时,UIContextualActionStyle
有两种类型,如果是置顶、已读等按钮就使用UIContextualActionStyleNormal
类型,delete操作按钮可使用UIContextualActionStyleDestructive
类型,当使用该类型时,如果是右滑操作,一直向右滑动某个cell,会直接执行删除操作,不用再点击删除按钮。
10.Safe Area
以前做悬浮(支付,头部标题等),系统为我们提供了viewController的topLayoutGuide
和bottomLayoutGuide
方法进行约束,但是在iOS11中被废弃了,引用了一个新的概念。safeArea
,它提供两种方式:safeAreaInsets
或safeAreaLayoutGuide
来提供给你safeArea
的参照值,即 insets
或者 layout guide
。同时如果改变Insets
时会获得两个回调
UIView.safeAreaInsetsDidChange()
UIViewController.viewSafeAreaInsetsDidChange()
这个iOS的safe Area
涉及到的第三方库有mansory
和 IQkeyboard
所以可能这两个库也会进行一些适配
11.UIToolbar and UINavigationBar— Layout
在 iOS 11 中,当苹果进行所有这些新特性时,也进行了其他的优化,针对 UIToolbar 和 UINavigaBar 做了新的自动布局扩展支持,自定义的bar button items、自定义的title都可以通过layout来表示尺寸。 需要注意的是,你的constraints需要在view内部设置,所以如果你有一个自定义的标题视图,你需要确保任何约束只依赖于标题视图及其任何子视图。当你使用自动布局,系统假设你知道你在做什么。
12. 管理margins 和 insets
基于约束的Auto Layout,使我们搭建能够动态响应内部和外部变化的用户界面。Auto Layout为每一个view都定义了margin。margin指的是控件显示内容部分的边缘和控件边缘的距离。 可以用layoutMargins
或者layoutMarginsGuide
属性获得view的margin,margin是视图内部的一部分。layoutMargins允许获取或者设置UIEdgeInsets
结构的margin。layoutMarginsGuide
则获取到只读的UILayoutGuide
对象。
在iOS11新增了一个属性:directional layout margins
,该属性是NSDirectionalEdgeInsets
结构体类型的属性:
typedef struct NSDirectionalEdgeInsets {
CGFloat top, leading, bottom, trailing;
} NSDirectionalEdgeInsets API_AVAILABLE(ios(11.0),tvos(11.0),watchos(4.0));
layoutMargins
是UIEdgeInsets
结构体类型的属性:
typedef struct UIEdgeInsets {
CGFloat top, left, bottom, right;
} UIEdgeInsets;
从上面两种结构体的对比可以看出,NSDirectionalEdgeInsets
属性用leading 和 trailing 取代了之前的 left 和 right。
directional layout margins
属性的说明如下:
directionalLayoutMargins.leading is used on the left when the user interface direction is LTR and on the right for RTL.
Vice versa for directionalLayoutMargins.trailing.
例子:当你设置了trailing = 30;当在一个right to left 语言下trailing的值会被设置在view的左边,可以通过layout margins的left属性读出该值。
如下图所示:
还有其他一些更新。自从引入layout margins
,当将一个view添加到viewController时,viewController会修复view的layoutMargins
为UIKit定义的一个值,这些调整对外是封闭的。从iOS11开始,这些不再是一个固定的值,它们实际是最小值,你可以改变你的view的layoutMargins为任意一个更大的值。而且,viewController新增了一个属性:viewRespectsSystemMinimumLayoutMargins,如果你设置该属性为”false”,你就可以改变你的layout margins为任意你想设置的值,包括0。