- 原本链接
- 本文为翻译文,如有错误,欢迎指正
ios11已经揭开神秘面纱,虽然整体画风依旧简单,但系统上的变化也是清晰可见的,其中之一就是ios标志性控件导航栏的设计发生了变化。
来看下ios11中新出现的Files
ios11-files.png
标题栏变大了,新的搜索框 --- 这都是ios11最醒目的变化。
来看一下横向的画面
ios11-tab.png
Tab Bar 高度减少,btn位置也发生了变化。
本文将针对ios中一些醒目的UI变化最一下简短的说明。
ios 的核心UI Bar控件:导航栏、UIToolBar、TabBar、搜索框等,以及margin,inset等各种UI约束。
UIBarItem
首先来看一下TabBar,导航栏,toolBar等的父类UIBarItem。
像上面两个截图展示的一样,横屏时也可以用较小的icon。请看下面截图
ios-竖屏.png
ios-横屏.png
在画面中间显示的是待选项目大的icon及title。
可以看出这并不是平时模式下常用的UI。
这是专门针对视力不好的人,在“文字放大查看”选项被选中时才出现的项目。
(使用方法:iPhone 设置app>通用>辅助功能>大号文字> 显示大号文字)
请按导航栏或是Tab bar时,将出现上图所述情况,放大显示现在已选中项目。
ios10及以前的系统,选择放大选项时,并不会同时方法导航栏或tab bar里的文字,因此对视力不好的人带来了一定的不便。
大家可以看到,ios11为覆盖此部分功能,引入的新的辅助性UI。
为设置UIBarItem,来看一下核心api。
// 标题
UIBarItem.title
// 图片
UIBarItem.image
// 横屏用图片
UIBarItem.landscapeImagePhone
// 视力不好的人专用的图片
UIBarItem.largeContentSizeImage
若通过StoryBoard设置,就不像上文一样用很多图片,也可以使用一个PDF文件,在这种情况下需要勾选Preserve Vector Data。
Preserve Vector Data.png
设置大的TitleBar
若想在导航栏中设置大的标题,只需要添加一行代码。
navigationBar.prefersLargeTitles = true
但如果只设置这一行代码,那与此导航栏想关联的所有viewController都会显示大标题。
一般来说只有第一或者第二个标题需要大号字体,以内容为主的画面不需要导航栏出现大的标题。
navigationItem.largeTitleDisplayMode
这是需要修改navigationItem的 largeTitleDisplayMode属性。
-
有.automatic, .always, .never 3个值, .automatic 是默认值
- .automatic 表示与之前画面相同
- .always表示总显示大号标题
- .never 表示不显示大标题,显示原字
-
navigationBar: UINaivgationBar 是 UINavigationController 里的property ,
-
navigationItem: 请记住UINavigationItem 是 UIViewController 的property
搜索栏
- 新的搜索框与之间相比简化许多,设计也是一目了然
navigationItem.searchController
navigationItem.hidesSearchBarWhenScrolling
- searchController: 只要设置UISearchController ,那搜索的UI就会自动设置出来。之前给搜索UI做约束比较麻烦,现在升级后的方式很简单 :)
UINavigationBar及 UIToolbar 都支持 Auto Layout
现在可以自定义UINavigationBar及UIToolbar 控件中的Auto Layout 属性.更准确的说,可以修改 Auto Layout 的大小属性; 使用intrinsicContentSize或是直接定义width, height 属性都可以。
Layout Margins
layout margins.jpg
- UIView的 layoutMargins: UIEdgeInsets在设置相关view的自子控件时起向导作用,引导并尽量使子空间只设置在该margin内侧.
(layoutMargins 并不是为约束 UI而强制使用的语法)
layoutMarginsGuide.jpg
layoutMarginsGuide是为了layoutMargins在 auto layout中使用的值.
_ios_11_3.jpg
在iOS 11中 ,新添加了directionalLayoutMargins, 官方推荐代替layoutMargins 使用。
_ios_11_5.jpg
layoutMargins作为 UIEdgeInsets,只有left和 right的值, directionalLayoutMargins作为 NSDirectionalEdgeInsets,也包含了 leading, trailing的值.
NSDirectionalEdgeInsets也是 iOS 11中新增加的类.
Directional 이란 개념은在 iOS UI 开发中Directional这个概念非常重要。
代替Left, Right,使用Leading, Trailing 的概念,对书写习惯为从右到左的国家来说非常重要。普通书写习惯为从左到右,因此UI的标准也是左边,但是对阿拉伯国家来说,习惯从右往左,因此UI约束也以右边为基准,与普通情况正好相反。
204_updating_your_app_for_ios_11_6.jpg
204_updating_your_app_for_ios_11_7.jpg
为directionalLayoutMargins的 trailing值赋值时,对一般情况会从右边留白,但针对以右边为基准的国家,对从左边留白。
204_updating_your_app_for_ios_11_8.jpg
layoutMargins, directionalLayoutMargins 无论变更哪一个,两个值都会同时改变。但要明确区本left, right, leading, trailing在概念上的差异。
204_updating_your_app_for_ios_11_9.jpg
iOS 11 之前的系统会提供 layoutMargins的默认值。是(8,8,8,8) 这种形式. 从此版本起将不再提供,默认值为0。
204_updating_your_app_for_ios_11_11.jpg
并且在 UIViewController中增加了新属性systemMinimumLayoutMargins .
204_updating_your_app_for_ios_11_12.jpg
- layoutMargins与 directionalLayoutMargins 都以systemMinimumLayoutMargins 为基准发生作用。
- 不要忘记, layoutMargins与 directionalLayoutMargins是UIView的属性, systemMinimumLayoutMargins是UIViewController的属性.
204_updating_your_app_for_ios_11_13.jpg
但也有可以忽视 systemMinimumLayoutMargins的方法。可以使用UIViewController.viewRespectsSystemMinimumLayoutMargins
204_updating_your_app_for_ios_11_14.jpg
204_updating_your_app_for_ios_11_15.jpg
204_updating_your_app_for_ios_11_16.jpg
忽略systemMinimumLayoutMargins,并将directionalLayoutMargins的值设为 .zero时,内容可以填充满整个屏幕
LayoutGuide and SafeArea
204_updating_your_app_for_ios_11_17.jpg
topLayoutGuide与 bottomLayoutGuide被废弃了.
在查看代替他们的属性前,先看一下以前的属性是什么作用。iOS 7中ios设计实在不怎么样,为强化内容,使用full screen,透明处理导航栏和toolBar.
关于iOS设计的相关细节,请参考 iOS Human Interface Guideline 文档。
2017722224420.png
一般来说内容较长时都需要滚动。要想知道导航栏或者工具栏实际哪些领域被覆盖的话,需要使用topLayoutGuide和 bottomLayoutGuide
edgesForExtendedLayout属性决定内容是否要覆盖底部Bar的部分。
204_updating_your_app_for_ios_11_18 (1).jpg
现在不比使用 topLayoutGuide和 bottomLayoutGuide.
作为替代,使用Safe Area这一属性。
虽然topLayoutGuide与 bottomLayoutGuide是UIViewController的属性,但新的Safe Area是 UIView的属性。
UIView.safeAreaInsets: UIEdgeInsets
UIView.safeAreaLayoutGuide: UILayoutGuide
可以通过这两个参数判断领域。
204_updating_your_app_for_ios_11_18 (1).jpg
204_updating_your_app_for_ios_11_20.jpg
204_updating_your_app_for_ios_11_22.jpg
除导航来和ToolBar之外,像上图中出现的图片bar部分的领域,可以通过自定义来解决, 通过设置UIViewController.addtionalSafeAreaInsets ,领域变更后可以调用两个方法来确定是否变更。
UIView.safeAreaInsetsDidChange()
UIViewController.viewSafeAreaInsetsDidChange()
UITableView
接下来是TableView,在ios11中tableview有一个重要的变化。
从现在起, UITableView 的Self-Sizing变为 Default.
换句话说,现在tableView是在Auto Layout 的基础上设置的。tableView 的cell及headView,footView等要通过 Auto Layout 来改变。
(当然,肯定可以继续按照以前的方式开发)
PS: UITableView以Auto Layout为基础的话,那就需要设置UITableView.estimatedRowHeight为 UITableViewAutomaticDimension.
iOS 11中,这是默认值,不需要单独设置;只是若按之间的方式开发,那需要做如下设置。
override func viewDidLoad() {
tableView.estimatedRowHeight = 0
tableView.estimatedSectionHeaderHeight = 0
tableView.estimatedSectionFooterHeight = 0
}
在来看一下其他tableView的 Separator inset .
首先,若在 iPad 上写一个简单的tableView.
import UIKit
class ViewController: UIViewController {
override func loadView() {
view = UITableView()
}
override func viewDidLoad() {
super.viewDidLoad()
let tableView = view as! UITableView
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
tableView.dataSource = self
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = "Table view cell"
return cell
}
}
UITableView1.png
iPad中,若使tableView充满整个若面, separatorInset 将自适应readable content guide.
在此基础上若想重新设置separatorInset该怎么办呢?
iOS11与之间版本有所不同,需要添加如下代码.
// in viewDidLoad
tableView.separatorInset = UIEdgeInsets(top: 0, left: 50, bottom: 0, right: 0)
UITableView2.png
UITableView3.png
虽然是一样的代码,但会像上图显示不同的结果。iOS 10 中 separatorInsets 还是以 readable content guide 为基准设置 inset ,
iOS 11 中则是像开发者希望的那样,从cell的最边缘开始算 inset.
那iOS 11若想向以前一样设置为readable content guide 该怎么办呢?
// in viewDidload
tableView.separatorInsetReference = .fromAutomaticInsets
将新属性 separatorInsetReference的值设为 값을 automatic即可。
separatorInsetReference: UITableViewSeparatorInsetReference 有两个枚举值.
public enum UITableViewSeparatorInsetReference : Int {
// The value set to the separatorInset property is interpreted as an offset from the edges of the cell.
case fromCellEdges
// The value set to the separatorInset property is interpreted as an offset from the automatic separator insets.
case fromAutomaticInsets
}
此外:
- UITableViewCell, UITableViewHeaderFooterView 的contentView 总在 safe area里面,一定要使用 contentView
- tableView的header和footer以及分组内部的header和footer都使用 UITableViewHeaderFooterView
204_updating_your_app_for_ios_11_23.jpg
最后,说明一下,在ios11中已完全支持Swipe Actions。
这真是让很多程序员热泪盈眶呀、
左、有都可以加入很多手势,iPhone的邮件app可以通过Swipe action删除。
详细内容请看WWDC17









网友评论