ios11新特性
1.UIKit Bars的改版
在浏览功能上的大标题视图(向上滑动后标题会回到原来的UI效果)、横屏状态下tab上的文字和icon会变为左右排列。
当然,如果图标和文字觉得太小了,可以长按item进行放大操作。具体只需要添加代码
- iOS11导航栏
在UI navigation bar中新增了一个BOOL属性prefersLargeTitles,将该属性设置为ture,navigation bar就会在整个APP中显示大标题,如果想要在控制不同页面大标题的显示,可以通过设置当前页面的navigationItem的largeTitleDisplayMode属性;
navigationItem.largeTitleDisplayMode
typedef NS_ENUM(NSInteger, UINavigationItemLargeTitleDisplayMode) {
/// 自动模式依赖上一个 item 的特性
UINavigationItemLargeTitleDisplayModeAutomatic,
/// 针对当前 item 总是启用大标题特性
UINavigationItemLargeTitleDisplayModeAlways,
/// Never
UINavigationItemLargeTitleDisplayModeNever,
}
设置导航栏搜索控制器
searchController :self.navigationItem.searchController = searchController
上面设置titleView为customView时出现宽度缩小的问题 (这个网上提到了这个问题,但是我自定义代码并没有出现这个情况)
3.调整相册权限的key
NSPhotoLibraryUsageDescription
改为NSPhotoLibraryAddUsageDescription
(beta版本好像又改过来了,我现在没有调整key也是可以访问相册的)
4.近场通讯
首先也要在info.plist配置NFCReaderUsageDescription
5.无线配备
- 弃用API,scrollview和tableview的改变
iOS11弃用了automaticallyAdjustsScrollViewInsets
属性,新增contentInsetAdjustmentBehavior
来替代它。这可能使得一些刷新出现头部错乱。contentInsetAdjustmentBehavior其实是一个枚举值。用来管理adjustedContentInset
-automatic和scrollableAxes一样,scrollView会自动计算和适应顶部和底部的内边距并且在scrollView不可滚动时,也会设置内边距.
-scrollableAxes自动计算内边距.
-never不计算内边距
-always根据safeAreaInsets计算内边距
我们这里要设置为never,所以我们的OC代码可以这样写:
声明tableView的位置 添加下面代码
if(@available(iOS11.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滑动操作
在iOS8之后,苹果官方增加了UITableVIew的右滑操作接口,即新增了一个代理方法(tableView: editActionsForRowAtIndexPath:)和一个类(UITableViewRowAction),代理方法返回的是一个数组,我们可以在这个代理方法中定义所需要的操作按钮(删除、置顶等),这些按钮的类就是UITableViewRowAction。这个类只能定义按钮的显示文字、背景色、和按钮事件。并且返回数组的第一个元素在UITableViewCell的最右侧显示,最后一个元素在最左侧显示。从iOS 11开始有了一些改变,首先是可以给这些按钮添加图片了,然后是如果实现了以下两个iOS 11新增的代理方法,将会取代(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
这两个代理方法返回的是UISwipeActionsConfiguration类型的对象,创建该对象及赋值可看下面的代码片段:
- ( UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
//删除
UIContextualAction *deleteRowAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:@"delete" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
[self.titleArr removeObjectAtIndex:indexPath.row];
completionHandler (YES);
}];
deleteRowAction.image = [UIImage imageNamed:@"icon_del"];
deleteRowAction.backgroundColor = [UIColor blueColor];
UISwipeActionsConfiguration *config = [UISwipeActionsConfiguration configurationWithActions:@[deleteRowAction]];
return config;
}
创建UIContextualAction对象时,UIContextualActionStyle有两种类型,如果是置顶、已读等按钮就使用UIContextualActionStyleNormal类型,delete操作按钮可使用UIContextualActionStyleDestructive类型,当使用该类型时,如果是右滑操作,一直向右滑动某个cell,会直接执行删除操作,不用再点击删除按钮,这也是一个好玩的更新。
typedef NS_ENUM(NSInteger, UIContextualActionStyle) {
UIContextualActionStyleNormal,
UIContextualActionStyleDestructive
} NS_SWIFT_NAME(UIContextualAction.Style)
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内部设置,所以如果你有一个自定义的标题视图,你需要确保任何约束只依赖于标题视图及其任何子视图。当你使用自动布局,系统假设你知道你在做什么。
- 管理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属性读出该值。
原文作者:AlvinCrash
原文链接:https://www.jianshu.com/p/2ca9ecdb07ce