美文网首页iOS
ios11下的app UI变化及代码设置

ios11下的app UI变化及代码设置

作者: Arang | 来源:发表于2017-07-22 23:24 被阅读670次
  • 原本链接
  • 本文为翻译文,如有错误,欢迎指正

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

相关文章

网友评论

    本文标题:ios11下的app UI变化及代码设置

    本文链接:https://www.haomeiwen.com/subject/eioukxtx.html