iOS 9 Storyboard 教程(一上)

原帖地址


Storyboard是在iOS5之后新增的一个令人兴奋的功能,使用Storyboard可以节省很多的时间来构建你的app界面.

  • 为了向你介绍什么是Storyboard,我会以一张图片为例.下面这张图就是你在本教程中使用Storyboard完成的一个app.


  • 你也许还不是十分了解这个app是做什么的,但是你可以清楚的看到它哪些界面,以及这些界面关系.

  • 你可以在Storyboard看到所有的ViewController的布局,并且可以描述它们之间的联系.使用Storyboard中,你可以更好的理解在app中所有的界面.

  • Storyboard可以描述在多个场景之间的过渡(transitions).这些过渡被称作”segues”.在Storyboard,你可以通过正确的连接你的ViewController来创建这些segues.感谢segues!你只需要很少的代码管理你的UI.

  • Storyboard可以让tableView与基本的cell和静态cell的工作更容易.你几乎可以完全在Storyboard中设计你的tableView,这样就减少了大量的代码.

  • Storyboard可以让Auto Layout更加容易,使用Auto Layout允许你在元素之间的数学关系,确定这些元素之间的位置关系.这个强大的工具可以让你更容易操作不同尺寸和大小的设备.在这个教程中你将使用Auto Layout,但是关于Auto Layout的知识在不在本教程的范围之内,不过你可以在Auto Layout Tutorial或者watch the video series了解更多关于Auto Layout的内容.

在这篇Storyboard教程中,你将会创建一个简单地app,允许你创建一个玩家和游戏以及他们技能的列表,在学习的过程中,你将学会在一些最常见的任务中使用Storyboard.

让我们开始吧!

打开Xcode,接着创建一个新的工程,选择 Single View Application.如下图:

之后Xcode会创建这个项目,Xcode的主窗口如下图:

新的项目包含两个类, AppDelegate.swift 和 ViewController.swift,以及本教程的关键:Main.storyboard文件. 这个app仅支持竖屏,所以需要在General->Deployment Info -> Device Orientation取消Landscape Left和Landscape Right选项. 现在让我们看一看Storyboard.在项目导航栏里点击Main.storyboard,之后会在 Interface Builder编辑器里看到Storyboard.

一个viewController的的storyboard官方术语是”场景(scene)”,你可以使用这个术语.所谓场景(scene)就是一个控制器在storyboard中的显示.

你可以看到包含一个空view的简单viewController.在storyboard,左边的箭头指向一个ViewController,这个箭头代表这个ViewController是一个初始控制器.

在storyboard编辑器中,你可以从右下角Object Library中拖拽出一些控件来为你的ViewController设计布局.你会看到仅仅一瞬间就完成了,它是多么神奇啊!

Note:

你可能会注意到在storyboard中,默认的控制器是正方形的.Xcode7可以为这些默认控制器设置Auto Layout和Size Classes.Auto Layout和Size Classes允许你灵活地改变用户界面的尺寸,这对于有许多尺寸的iPhone和iPad来说是非常有用的.为了能够学到更多关于size classes的内容,查看Adaptive Layout video tutorial series,在本课程中,你会把可选的步骤场景在你的storyboard中,这样你就可以更容易的看到最终屏幕上的样子.

在你探索之前,调整模拟场景为iPhone6/6s. 在Document Outline选择 View Controller .如果你没有看到Document Outline,点击storyboard中左下角的这个按钮:


在Attributes Inspector底下的Simulated Metrics(模拟度量)属性,改变Size为iPhone 4.7 inch,如图:

在storyboard中,这个尺寸是iPhone6/6s的屏幕尺寸. 在storyboard中,“inferred”是Simulated Metrics里默认的设置.Simulated Metrics是一个在storyboard中的视觉辅助设计,也就是你的屏幕最终的样子.仅仅需要记住的是,它们不会在运行时被使用. 为了体会storyboard是如何工作的,可以在右下角控制器面板的Object Library中拖拽一些控件:

当你拖拽这些控件的时候,它们会出现在左侧的 Document Outline 中:

storyboard中显示了你创建的所有控制器,目前仅仅有一个view controller (或者是scene)在你的storyboard中,但是在本教程中你会加入其他几个控制器.在这个场景之上有,一个微型版的Document Outline,称作Dock.

在这个场景中,Dock显示了顶层的对象,每一个场景都拥有至少一个View Controller 对象, 一个 First Responder 对象, 和一个 Exit 选项,但是它也可能拥有其他顶级的对象.Dock可以很方便的连接这些outlet和action.如果你想要连接其他的view controller,你可以很简单地从Dock中拖拽它的图标.

Note:

你可能不太想使用First Responder.它是一个代理对象,指的是任何对象在任何给定的时间内的第一响应状态.举一个例子,你可以把按钮的Touch Up Inside事件连接到First Responder的selector上.如果在某个时候,一个文本框是输入的焦点,然后你可以按下按钮来让作为第一响应者的文本字段拷贝到粘贴板.

运行这个app,它应该看起来和你在编辑器里设计的完全一样(你的可能看上去不同于下面的截图—这仅仅是为了演示,不会在以后的教程中使用):

你定义的这个 View Controller作为初始的控制器—但是app怎样才能加载它呢?看一看应用程序的代理就可以找到答案.打开AppDelegate.swift你会看到源代码从这里开始.

import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate { 
    var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 
    // Override point for customization after application launch. 
    return true 
}

在AppDelegate这个类的指定文件的头部,@UIApplicationMain属性作为模块的入口点.这个属性使用storyboard所必须的.你的应用程序委托继承自UIResponder,并且他还有一个UIWindow属性.所有的方法都是空的.甚至是application(_:didFinishLaunchingWithOptions:) 也只是简单地返回了true.

这个秘密在一个叫做info.plist的文件中.在导航栏里点击 Info.plist 你将看到下面这些内容:

这里写图片描述
这里写图片描述

Storyboard app使用的这个键UIMainStoryboardFile,也被称为”storyboard file base name”,为了能够指定Storyboard的名称,必须在加载被命名的storyboard文件,自动地从storyboard中实例化”Initial View Controller”,然后把控制器的view添加到一个新的UIWindow对象上.
你也可以在General tab里Deployment Info下地Project Settings里看到这个部分:

这里写图片描述
这里写图片描述

现在来创建一个包含几个view controller的Ratings app吧~##仅仅把它添加到我的标签里你将要创建的Ratings app有一个TabBarController,并且跟着两个item,使用storyboard非常容易创建.你将会在一个空的storyboard上开始创建,所以切换回Main.storyboard ,然后删除默认创建的view controller.这可以通过在Document Outline 点击View Controller 然后按下delete键,就可以删除了.为了方便,再一次改变Simulated Metrics让其作为一个iPhone来显示这个场景.当你做之前,在Document Outline选中Tab Bar Controller,然后在右侧的 Attributes Inspector ,改变 Size 为iPhone 4.7 inch.这两个view controller也会跟着改变,大小都变为 iPhone 6/6s的尺寸.

这里写图片描述
这里写图片描述

这个新的 Tab Bar Controller 已经预配置好了两个view controller.UITabBarController也被称作container view控制器,因为它包含了一个或者更多其他的视图控制器.其他两个常用的容器是Navigation Controller 和Split View Controller(在后面你将使用的是Navigation Controller).容器之间的关系是由Tab Bar Controller 和 view controller 的箭头代表的.下图看到的在箭头中间的图标代表特定的嵌入关系.

这里写图片描述
这里写图片描述

Note:

如果你想同时移动或缩小Tab Bar Controller和它的附加视图控制器,你可以按住⌘-点击或点击和拖拽多个选中的场景.这才有可能使他们在一起.(选中的场景有一条蓝色的轮廓.)


往第一个view controller(当前显示的标题是”Item 1”)中拖拽一个UILabel,双击,然后设置这个label的标题为”First Tab”.然后也拖拽一个UILabel在第二个view controller(“Item 2”),设置这个label的标题为”Second Tab”.当你在这两个控制器之间接切换时确实看到发生了某些变化.


Note:

当你缩小编辑器的时候,你是不能往这些控制器里拖拽控件的.你可以通过双击这个工作区间来返回到正常缩放尺寸.


编译并且运行(Build & Run),之后你会在控制台里看到类似下面的错误信息:Ratings[18955:1293100] Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the designated entry point is not set?幸运地是,错误信息非常清楚 — 你从来就没有设置一个入口点,也就是说在你删除默认创建的控制器之后,你并没有设置Initial View Controller.为了解决这个问题,选中Tab Bar Controller然后在右侧的 Attributes Inspector 里勾选 Is Initial View Controller.

这里写图片描述
这里写图片描述

在工作区间里,这个箭头之前指向被删除的view controller ,现在指向的是这个Tab Bar Controller.

这里写图片描述
这里写图片描述

这就意味着,当你运行app的时候,UIApplication会让Tab Bar Controller 作为主屏幕.运行app尝试一下.这个app现在有一个tab bar,并且你可以在两个two view controller之间进行切换:

这里写图片描述
这里写图片描述

Tip:

想要改变 initial view controller,你也可以在view controller之间拖拽这个箭头.


Xcode附带了构建一个带标签app的模板(也叫标签应用模板),你可以使用这个模板,但是它却不能很好地知道这应该如何工作,所以如果你觉得有必要,你也可以手动创建一个Tab Bar Controller.


Note:

如果你的Tab Bar Controller连接了超过5个子控制器,当你运行app的时候,他会自动地把这些控制器都加上.多么简洁啊!

-----##添加一个Table View Controller目前只有两个UIViewController连接到了 Tab Bar Controller上.现在,你需要用一个UITableViewController来替换第一个UIViewController.在Document Outline栏里点击第一个view controller ,然后按delete键删除.然后从Object Library中拖拽出一个新的Table View Controller到先前view controller的位置.

这里写图片描述
这里写图片描述
现在你需要把这个Table View Controller放在一个导航控制器里.在Table View Controller选中情况下,再Xcode的菜单栏里选择Editor\Embed In\Navigation Controller .这也就添加了另一个控制器.
这里写图片描述
这里写图片描述
你也可能会从Object Library拖拽一个已经嵌入tableview 的Navigation Controller,并且这个个嵌入命令也能节省很多时间.因为这个Navigation Controller 也是view controller的容器(就好像Tab Bar Controller),它有一个关系指向Table View Controller.你也可以在看见Document Outlin里看到这个关系.
这里写图片描述
这里写图片描述
可以注意到的是Table View Controller已经嵌入到了一个导航栏里.Interface Builder会自动把它放在那里,因为这个控制器将显示在这个Navigation Controller的框架里.那并不是一个真正的UINavigationBar对象,但它是一个模拟的对象.Simulated Metrics将在这个控制器里推断上下文,然后在Navigation Controller会显示一个导航栏.在一个 Tab Bar Controller里会显示一个标签栏,等等...新的控制器是正方形的.当你把它们嵌入到 Tab Bar Controller ,一瞬间,它们就会改变它们的大小里匹配它们的父视图控制器.为了把这两个新的控制器连接到Tab Bar Controller,按住control并且拖动Tab Bar Controller到Navigation Controller上.当你放首位的时候,会出现一个小的.选择Relationship Segue – view controllers选项:
这里写图片描述
这里写图片描述
这样在这两个控制器之间就创建了一个新的箭头关系.这也是一个嵌入关系,正如你看到的 Tab Bar Controller. Tab Bar Controller有两个嵌入的关系,对应每一个标签.这个Navigation Controller本身也与Table View Controller有一个嵌入关系. 当你创建了这个新连接的时候,这个Tab Bar Controller就添加了一个新的标签.并且有一个简单地名字为”Item”.对于这个app来说,如果你想让这个新的控制器作为第一个标签,那么你只可以拖动来改变的它们的顺序.
这里写图片描述
这里写图片描述
尝试运行一下这个app.现在第一个导航控制器里的标签包含了一个 table view.
这里写图片描述
这里写图片描述
只要你把一个view controller连接到了Tab Bar Controller上,你就可以在Document Outline或者这个控制器的底部看到生成了一个Tab Bar Item对象.你可以在Tab Bar Controller上使用Tab Bar Item来配置标签的标题和图标.选中 Navigation Controller里的Tab Bar Item,之后在Attributes inspector里设置标题为Players.
这里写图片描述
这里写图片描述
用相同的方式给view controller的Tab Bar Item重命名为Gestures.一个精心设计的app也应该在这些标签上放一些图片, 教程的资源包含了一个为images的子文件夹.拖拽这个文件夹到工程中的 Assets.xcassets文 里.
这里写图片描述
这里写图片描述
你可能猜到了,给Gestures项的是Gestures.png. 一个内嵌在Navigation Controller中view controller有一个Navigation Item,用来配置导航栏(navigation bar).在Document Outline离选择Table View Controller的Navigation Item然后在Attributes inspector中改变它的标题为Players.
这里写图片描述
这里写图片描述
注意到了么?现在在Document Outline里的Item已经变为了Players啦~另外,你也可以双击导航栏然后改变标题.需要注意的是,你应该双击Table View Controller中的模拟导航栏,而不是在Navigation Controller里真正的导航栏对象.运行app,你就会惊叹于你的漂亮的标签栏,然而却没有写一行代码!
这里写图片描述
这里写图片描述

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容