故事板(Storyboard)

article/2025/9/14 17:50:54

1 使用Storyboard完成各项常见功能

1.1 问题

故事板Storyboard是IOS5开始引入的一个新的系统,将多个视图文件(类似xib文件)集中到一个单独的可视化工作区间,负责创建和管理所有的界面及界面间的跳转,每一个Storyboard中的单个视图文件称之为场景Scene,可以使用Xcode的Interface Builder来进行编辑。

本案例将学习如何使用Storyboard完成场景的创建,并且使用两种不同的方式实现Modal模式的跳转,如图-1所示:

图-1

1.2 方案

首先创建一个SingleViewApplication项目,会自动帮我们创建好一个TRViewController类,并且自动带有Storyboard文件,默认情况下Storyboard里面有一个已经创建好的场景,已和TRViewController类绑定。

另外不用在程序的入口方法中创建Window对象和根视图控制器,StoryBoard会自动帮我们创建。

其次再新创建一个场景,从对象库中拖放一个视图控制器对象到StoryBoard中即可,并创建一个视图控制器类TRViewController2,继承至UIViewController。

在Storyboard中选中第二个场景,在右边栏的第三个检查器中修改类名,将TRViewController2和第二个场景绑定。

然后分别在第一个场景和第二个场景中拖放一个Button控件,在右边栏的第四个检查器中设置好相关属性。

选中第一个场景中的Button控件,按住Control键往第二个场景拉线,实现Modal方式的页面跳转。给场景二中的Button添加事件方法,通过代码的方式实现界面的回跳。

最后通过Segue加代码的方式实现界面跳转,在场景一中再拖放一个Button控件并关联成方法。选中场景一上面的黄色圆球按钮,按住Control键往第二个场景上拖拽,释放鼠标选择Modal模式跳转。

选中Segue对象,在右边栏的检查器四中给Identifier进行赋值,给Segue对象取一个标识“Segue”,identifier是一个NSString类型的属性。

在TRViewController.m文件中实现Button的事件方法,使用performSegueWithIdentifier:sender:方法实现页面跳转。

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建一个带有Storyboard的项目

首先创建一个SingleViewApplication项目,Xcode会自动帮我们创建好一个TRViewController类,并且自动带有Storyboard文件。

默认情况下Storyboard里面有一个已经创建好的场景,并且已经和TRViewController类绑定。另外不需要再到程序的入口方法中创建Window对象和根视图控制器对象,StoryBoard会自动帮我们创建,在StoryBoard文件中有一个箭头指向的场景就是程序的根视图控制器,如图-2所示:

图-2

步骤二:创建第二个场景并和代码绑定

在Storyboard中创建一个新场景,从对象库中拖放一个视图控制器对象到StoryBoard中,如图-3所示:

图-3

然后创建一个视图控制器类TRViewController2,继承至UIViewController。在Storyboard中选中第二个场景,在右边栏的第三个检查器中修改类名,将TRViewController2和第二个场景绑定在一起,如图-4所示:

图-4

步骤三:通过Segue实现界面跳转

StoryBoard中每个视图上的控件,都和xib文件的操作方式一样,可以直接拖拽摆放在视图上,也同样可以通过拉线的方式关联成IBOutlet,IBCollectionOutlet以及IBAction等属性。

首先分别在第一个场景和第二个场景中拖放一个Button控件,在右边栏的第四个检查器中设置好相关属性。

然后选中第一个场景中的Button控件,按住Control键往第二个场景拉线,释放鼠标,在弹出的窗口中选择Modal方式,如图-5所示:

图-5

最后给场景二中的Button添加事件方法back:,在该方法中通过代码的方式实现界面的回跳,代码如下所示:

  1. - (IBAction)back:(UIButton *)sender {
  2. [selfdismissViewControllerAnimated:YEScompletion:nil];
  3. }

这里需要注意返回到第一个界面时,不能再继续使用连线的方式,否则会创建新的视图控制器对象,而不是返回以前的视图控制器。

步骤四:通过Segue加代码的方式实现界面跳转

首先在场景一中再拖放一个Button控件并关联成方法goToSecond:。选中场景一上面的黄色圆球按钮,按住Control键往第二个场景上拖拽,释放鼠标选择Modal模式跳转,如图-6所示:

图-6

注意此时应该选中的是场景本身,而不再是按钮。然后选中Segue对象,在右边栏的检查器四中给Identifier进行赋值,identifier是Segue对象一个NSString类型的属性,表示Segue的标识,用于区分不同的Segue对象,本案例给Segue对象取一个标识“Segue”,如图-7所示:

图-7

在TRViewController.m文件中实现Button的事件方法goToSecond:,在该方法中使用performSegueWithIdentifier:sender:方法实现页面跳转,identifier参数就是刚才设置的Segue的标识,代码如下所示:

  1. - (IBAction)goToSecond:(UIButton *)sender {
  2. [selfperformSegueWithIdentifier:@"Segue" sender:nil];
  3. }

1.4 完整代码

本案例中,TRViewController.m文件中的完整代码如下所示:

  1. #import "TRViewController.h"
  2. @interfaceTRViewController ()
  3. @end
  4. @implementationTRViewController
  5. - (IBAction)goToSecond:(UIButton *)sender {
  6. [selfperformSegueWithIdentifier:@"Segue" sender:nil];
  7. }
  8. @end
 

本案例中,TRViewController2.m文件中的完整代码如下所示:

  1. #import "TRViewController2.h"
  2. @interface TRViewController2 ()
  3. @end
  4. @implementation TRViewController2
  5. - (IBAction)back:(UIButton *)sender {
  6. [selfdismissViewControllerAnimated:YEScompletion:nil];
  7. }
  8. @end
 

2 将场景嵌入到导航中并进行Push跳转

2.1 问题

本案例在StoryBoard中分别使用手动和自动的方式创建带有导航控制器的场景,并实现Push模式的界面跳转,如图-8所示:

图-8

2.2 方案

首先创建一个带有Storyboard的SingleViewApplication项目。先使用手动的方式给场景添加导航控制器:

1)从对象库拖拽一个NavigationController对象到storyboard中,删除NavigationController自带的视图控制器(默认是一个表视图控制器);

2)选中NavigationController对象,往自己的视图控制器上拉线,释放鼠标,在弹出的对话框中在选择root view Controller,就完成了添加导航控制器。

然后将上一步拖拽的NavigationController对象删除,再使用自动嵌入NavigationController的方式给视图控制器添加导航控制器。

选中需要被导航控制器包含的场景,在Xcode菜单栏中选中Editor选项,然后选中Embed In,最后在弹出的窗口中选中NavigationController即可。

最后再创建一个新的场景,从对象库拖拽一个视图控制器对象到storyboard中,在上一个场景中拖拽一个跳转按钮,然后选中按钮按住Control键连线到新创建的场景上,在弹出的菜单中选择Push即可实现界面的跳转。

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:使用手动的方式给场景添加导航控制器

首先创建一个带有Storyboard的SingleViewApplication项目。从对象库拖拽一个NavigationController对象到storyboard中,删除NavigationController自带的视图控制器(默认是一个表视图控制器),如图-9所示:

图-9

然后选中storyboard中的NavigationController对象,往自己的视图控制器上拉线,释放鼠标,在弹出的对话框中选择root view Controller,如图-10所示:

图-10

最后不要忘了将程序入口的箭头移动到NavigaitonController的前面,表示程序从此处入口,如图-11所示:

图-11

步骤二:使用自动的方式给场景添加导航控制器

先将上一步拖拽的NavigationController对象删除,然后选中需要被导航控制器包含的场景,在Xcode菜单栏中选中Editor选项,然后选中Embed In,最后在弹出的窗口中选中NavigationController即可,如图-12所示:

图-12

步骤三:实现Push模式跳转

首先创建一个新的场景,从对象库拖拽一个视图控制器对象到storyboard中。然后在上一个场景中拖拽一个跳转按钮,在右边栏检查器四设置按钮的相关属性。

最后选中按钮,按住Control键往新创建的场景上拉线,在弹出的菜单中选择Push即可实现界面的跳转,如图-13所示:

图-13

如果此时入口箭头消失了,可以在storyboard中选中NavigationController,然后在右边栏检查器四中的Is Initial View Controller选择框上打钩,如图-14所示:

图-14

如果不需要另外写代码,可以不用创建视图控制器类。最后在StoryBoard中完成的界面如图-15所示:

图-15

3 给场景添加Title、按钮、ToolBar等

3.1 问题

本案例直接在上一个案例的基础上实现,学习如何在Storyboard中给导航栏添加标题和按钮,并设置ToolBar工具条,如图-16所示:

图-16

3.2 方案

首先给导航栏添加标题,选中场景一,双击导航栏的中间区域,即可编辑场景一的导航栏所显示的标题,相当于使用代码给self.title属性赋值,也可以在右边栏的检查器四中编辑标题。场景二也可以通过同样的方式编辑标题。

然后给导航栏添加左右按钮,选中场景一,直接从对象库中拖拽一个BarButtonItem控件到场景一的NavigationBar的左区域或右区域即可,可以在检查器四中设置BarButtonItem控件的的相关属性。

最后设置ToolBar工具条,在StoryBoard中可以直接设置显ToolBar,选中NavigationController,在右边栏的检查器四中的shows ToolBar选择框上打勾,然后在具体的界面场景中向ToolBar拖放BarButtonItem。

3.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:给导航栏添加标题

首先给导航栏添加标题,选中场景一,双击导航栏的中间区域,即可编辑场景一的导航栏所显示的标题,相当于使用代码给self.title属性赋值,如图-17所示:

图-17

或者在右边栏的检查器四中编辑导航栏的标题,如图-18所示:

图-18

用同样的方式给场景二的导航栏添加标题。

步骤二:给导航栏添加左右按钮

在Storyboard中选中场景一,从对象库中拖拽一个BarButtonItem控件到导航栏的左区域上,如图-19所示:

图-19

然后在右边栏的检查器四中设置BarButtonItem的相关属性,BarButtonItem的样式、标题、图片等都可以直接进行设置,如图-20,图-21所示:

图-20

图-21

最后按同样的方式再拖拽一个BarButtonItem控件到导航栏的右区域上,如图-21所示:

图-21

在Storyboard中是不能往导航栏拖拽多个左按钮或右按钮的,如果需要放置多个按钮,就只能通过代码的方式。

步骤三:设置ToolBar工具条

首先让ToolBar工具条显示出来,在StoryBoard中可以直接设置显示ToolBar,选中NavigationController,在右边栏的检查器四中的shows ToolBar选择框上打勾,如图-22所示:

图-22

然后选中场景一,向ToolBar依次拖放BarButtonItem,在右边栏的检查器四中可以设置BarButtonItem的样式,完成效果如图-23所示:

图-23

4 将场景嵌入到TabBar

4.1 问题

本案例直接在上一个案例的基础上完成,在StoryBoard中分别使用手动和自动的方式创建带有标签控制器的场景,如图-24所示:

图-24

4.2 方案

和操作导航控制器类似,首先从对象库中拖拽一个TabBarController对象到Storyboard中,删除TabBarController自带的视图控制器。

然后选中TabBarController,按住Control键连线到场景一的NavigaitionController(ToolBar需要隐藏),释放鼠标在弹出的窗口中选择view controllers。

在场景一的NavigationController上选中TabBar的Item,在右边栏的检查器四中设置相关属性,例如按钮样式、标题,显示图片等。以同样的方式给TabBarController再添加两个子视图控制器。

最后将上一步拖拽的TabBarController对象删除,再使用自动嵌入TabBarController的方式给视图控制器添加导航控制器。

选中场景一的导航控制器,在Xcode菜单栏中选中Editor选项,然后选中Embed In,最后在弹出的窗口中选中TabBarController即可。然后以拉线的方式关联其他子视图控制器。

4.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:使用手动的方式给场景添加标签控制器

从对象库拖拽一个TabBarController对象到storyboard中,删除TabBarController自带的视图控制器,如图-25所示:

图-25

然后选中storyboard中的TabBarController对象,往场景一的NavigationController上拉线,释放鼠标,在弹出的对话框中在选择root view Controller,如图-26所示:

图-26

在场景一的NavigationController上选中TabBar的Item,在右边栏的检查器四中设置相关属性,例如按钮样式、标题,显示图片等,如图-27所示:

图-27

最后以同样的方式给TabBarController添加两个子视图控制器,并将程序入口的箭头放置到TabBarController的前面,表示程序从此处入口,如图-28所示:

图-28

步骤二:使用自动的方式给场景添加标签控制器

先将上一步拖拽的TabBarController对象删除,然后选中需要被导航控制器包含的场景,在Xcode菜单栏中选中Editor选项,然后选中Embed In,最后在弹出的窗口中选中TabBarController即可,如图-29所示:

图-29

然后以拉线的方式关联其他子视图控制器,使用同步骤二相同的方法设置TabBar上Item的属性。

5 使用segue方式跳转时的传值

5.1 问题

Storyboard让界面跳转变得更加的简单,那么同样也会存在界面之间的正向传值和反向传值,本案例使用Segue实现页面之间的跳转和正向传值(反向传值和之前的方法相同),将第一个界面TextField里面的输入内容传递给第二个界面,如图-30所示:

图-30

5.2 方案

首先同样创建好一个SingleViewApplication项目,在Storyboard里面拖放两个视图控制器的场景,分别和两个视图控制器类TRFirstViewController和TRSecondViewController绑定。

其次在第一个场景中拖放一个TextField控件和一个Button控件,并将TextField关联成私有属性textField。

在第二个场景中拖放一个Label控件和一个Button控件,并将Label关联成私有属性label,将Button关联成方法back:,该方法用于回跳到第一个界面。

然后选中场景一中的Button,按住Control键往第二个场景拉线,实现Modal模式的跳转。

在TRSecondViewController类中定义一个NSString类型的公开属性massage,用于接收传递过来的数据。

最后在TRFirstViewController.m文件中重写方法prepareForSegue:sender:,该方法会在界面跳转之前被自动调用,Segue参数就是连接两个场景的Segue对象。在该方法内部将textField输入框中的内容赋值给TRSecondViewController的message属性,从而进行传值。

在TRSecondViewController.m文件中重写方法viewWillAppear:,在此方法中将接收到数据显示到label上;

5.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建项目,搭建场景

在创建好的Xcode项目中创建两个视图控制器类TRFirstViewController和TRSecondViewControlle,全都继承至UIViewController。

在Storyboard里面拖放两个视图控制器的场景,分别和两个视图控制器类TRFirstViewController和TRSecondViewController进行绑定。

其次在第一个场景中拖放一个TextField控件和一个Button控件,并将TextField关联成TRFirstViewController的私有属性textField,代码如下所示:

  1. @interfaceTRFirstViewController ()
  2. @property (weak, nonatomic) IBOutletUITextField *textField;
  3. @end

在第二个场景中拖放一个Label控件和一个Button控件,并将Label关联成TRSecondViewController的私有属性label,将Button关联成方法back:,该方法用于回跳到第一个界面,代码如下所示:

  1. //Label的输出口属性
  2. -@interfaceTRSecondViewController ()
  3. @property (weak, nonatomic) IBOutletUILabel *label;
  4. @end
  5. //Button的back:方法
  6. - (IBAction)back:(UIButton *)sender {
  7. [selfdismissViewControllerAnimated:YEScompletion:nil];
  8. }

步骤二:创建Segue对象,实现界面跳转

选中场景一中的Button,按住Control键往第二个场景拉线,释放鼠标在弹出的窗口中选择Modal模式,实现界面跳转,如图-31所示:

图-31

在TRSecondViewController类中定义一个NSString类型的公开属性massage,用于接收传递过来的数据,代码如下所示:

  1. @interfaceTRSecondViewController : UIViewController
  2. @property (nonatomic,strong) NSString *message;
  3. @end

步骤三:关联代码,实现方法

首先在TRFirstViewController.m文件中重写方法prepareForSegue:sender:,该方法会在界面跳转之前被自动调用,Segue参数就是连接两个场景的Segue对象,可以通过segue.destinationViewControllerSegue属性获取到TRSecondViewController对象,并将textField输入框中的内容赋值给TRSecondViewController的message属性,从而进行传值,代码如下所示:

  1. -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  2. //拿到目标VC对象
  3. TRSecondViewController *destination = segue.destinationViewController;
  4. //给destination的公开属性赋值
  5. destination.message = self.textField.text;
  6. }

最后在TRSecondViewController.m文件中重写方法viewWillAppear:,在此方法中将接收到数据显示到label上,代码如下所示:

  1. -(void)viewWillAppear:(BOOL)animated {
  2. [superviewWillAppear:animated];
  3. self.label.text = self.message;
  4. }

5.4 完整代码

本案例中,TRFirstViewController.m文件中的完整代码如下所示:

  1. #import "TRFirstViewController.h"
  2. #import "TRSecondViewController.h"
  3. @interfaceTRFirstViewController ()
  4. @property (weak, nonatomic) IBOutletUITextField *textField;
  5. @end
  6. @implementationTRFirstViewController
  7. //父类中的方法,此方法会在Segue跳转之前自动调用
  8. -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  9. //拿到目标VC对象
  10. TRSecondViewController *destination = segue.destinationViewController;
  11. //给destination的公开属性赋值
  12. destination.message = self.textField.text;
  13. }
  14. @end
隐藏

本案例中,TRSecondViewController.h文件中的完整代码如下所示:

  1. #import<UIKit/UIKit.h>
  2. @interfaceTRSecondViewController : UIViewController
  3. @property (nonatomic,strong) NSString *message;
  4. @end
 

本案例中,TRSecondViewController.m文件中的完整代码如下所示:

  1. #import "TRSecondViewController.h"
  2. @interfaceTRSecondViewController ()
  3. @property (weak, nonatomic) IBOutletUILabel *label;
  4. @end
  5. @implementationTRSecondViewController
  6. -(void)viewWillAppear:(BOOL)animated {
  7. [superviewWillAppear:animated];
  8. self.label.text = self.message;
  9. }
  10. - (IBAction)back:(UIButton *)sender {
  11. [selfdismissViewControllerAnimated:YEScompletion:nil];
  12. }
  13. @end
 

6 使用代码的方式实现界面跳转

6.1 问题

使用Segue实现界面跳转的好处就是方便、灵活。但是程序中经常也会用到手动方式跳转界面。本案例直接在上一个案例的基础上实现,使用代码的方式实现storyboard场景之间的跳转,以及storyboard和xib之间的跳转,如图-32所示:

图-32

6.2 方案

首先让场景一嵌入NavigationController,然后在场景一上面拖拽一个Button控件,并将标题命名为“goToSecondVCByCode”,将按钮关联成TRFirstViewController的方法goToSecondVC:。

其次选中场景二,在右边栏的检查器三中的设置Storyboard ID值,给场景二命名一个标识为“SecondVC”。

然后在TRFirstViewController.m文件中实现goToSecondVC:方法,该方法内部通过Storyboard的instantiateViewControllerWithIdentifier:方法获取到TRSecondViewController对象,并通过push方法实现跳转。

最后实现Stroyboard跳转到xib,创建一个带有xib的视图控制器类TRThirdViewController,在xib中拖放一个回跳按钮,关联成TRThirdViewController的方法backToFirst:,实现该方法通过dismiss方法回跳到第一个界面。

在场景一上面拖拽一个Button控件,并将标题命名为“goToThirdXibByCode”,将按钮关联成TRFirstViewController的方法goToThirdVC:,在该方法内通过initWithNIbName获取到TRThirdViewController对象,并通过push方法实现界面跳转。

6.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:使用代码实现场景一和场景二之间的跳转

首先让场景一嵌入NavigationController,然后在场景一上面拖拽一个Button控件,并将标题命名为“goToSecondVCByCode”,并将按钮关联成TRFirstViewController的方法goToSecondVC:。

然后选中场景二,在右边栏的检查器三中的设置Storyboard ID值,给场景二命名一个标识为“SecondVC”,如图-33所示:

图-33

最后在TRFirstViewController.m文件中实现goToSecondVC:方法,该方法内部通过Storyboard的instantiateViewControllerWithIdentifier:方法获取到TRSecondViewController对象,并通过push方法实现跳转,代码如下所示:

  1. - (IBAction)goToSecondVCByCode:(UIButton *)sender {
  2. TRSecondViewController *secondVC = [self.storyboardinstantiateViewControllerWithIdentifier:@"SecondVC"];
  3. secondVC.message = self.textField.text;
  4. [self.navigationControllerpushViewController:secondVCanimated:YES];
  5. }

步骤二:实现从Storyboard文件和Xib文件之间的跳转

storyboard和xib是可以一起工作,从storyboard可以直接跳转到xib文件(仅限push跳转方式),操作方式和以前完全相同。

首先创建一个带有xib的视图控制器类TRThirdViewController,继承至UIViewController。

然后在xib文件中拖放一个回跳按钮,并将按钮关联成TRThirdViewController的方法backToFirst:,实现该方法,代码如下所示:

  1. - (IBAction)backToFirst:(UIButton *)sender {
  2. [selfdismissViewControllerAnimated:YEScompletion:nil];
  3. }

最后在场景一上面拖拽一个Button控件,并将标题命名为“goToThirdXibByCode”,将按钮关联成TRFirstViewController的方法goToThirdVC:,在该方法内通过initWithNIbName获取到TRThirdViewController对象,并通过push方法实现界面跳转,代码如下所示:

  1. - (IBAction)goToThirdXibByCode:(UIButton *)sender {
  2. TRThirdViewController *thirdVC = [[TRThirdViewControlleralloc]initWithNibName:@"TRThirdViewController" bundle:nil];
  3. [self.navigationControllerpushViewController:thirdVCanimated:YES];
  4. }

6.4 完整代码

本案例中,TRFirstViewController.m文件中的完整代码如下所示:

  1. #import "TRFirstViewController.h"
  2. #import "TRSecondViewController.h"
  3. #import "TRThirdViewController.h"
  4. @interfaceTRFirstViewController ()
  5. @property (weak, nonatomic) IBOutletUITextField *textField;
  6. @end
  7. @implementationTRFirstViewController
  8. -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  9. TRSecondViewController *destination = segue.destinationViewController;
  10. destination.message = self.textField.text;
  11. }
  12. - (IBAction)goToSecondVCByCode:(UIButton *)sender {
  13. TRSecondViewController *secondVC = [self.storyboardinstantiateViewControllerWithIdentifier:@"SecondVC"];
  14. secondVC.message = self.textField.text;
  15. [self.navigationControllerpushViewController:secondVCanimated:YES];
  16. }
  17. - (IBAction)goToThirdXibByCode:(UIButton *)sender {
  18. TRThirdViewController *thirdVC = [[TRThirdViewControlleralloc]initWithNibName:@"TRThirdViewController" bundle:nil];
  19. [self.navigationControllerpushViewController:thirdVCanimated:YES];
  20. }
  21. @end
 

7 完成乐库项目中的静态表

7.1 问题

使用storyboard实现静态表视图比xib方式更简单、更方便,更灵活。本案例使用Storyboard重新完成乐库项目中的“更多”界面,如图-34所示:

图-34

7.2 方案

首先同样创建一个SingleViewApplication项目,将Storyboard中原有的场景删除,然后从对象库中拖拽一个TableViewController的对象到Storyboard中,该表视图控制器就是该程序的根视图控制器。

其次让TableViewController嵌入NavigationController,在Storyboard中选中TableView,然后在右边栏的第四个检查器中,将content属性设置为Static Cells即将表视图设置为静态,可以直接在storyboard的场景中操作表视图的表头视图、分区和单元格。

然后根据界面需要直接在表视图的表头视图、分区和单元格上拖拽所需要的视图和控件。

再创建一个表视图控制器类TRMusicTableViewController,和Storyboard中的场景进行绑定,将TableView的三问方法删除,不再需要手动实现。

最后在Storyboard中通过Segue实现点击单元格跳转和点击辅助视图跳转。

7.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建静态表视图场景

首先在创建好的Xcode项目中,将Storyboard中原有的场景删除,然后从对象库中拖拽一个TableViewController的对象到Storyboard中,该表视图控制器就是该程序的根视图控制器,如图-35所示:

图-35

然后让TableViewController嵌入NavigationController,在Storyboard中选中TableView,然后在右边栏的第四个检查器中,将content属性设置为Static Cells即将表视图设置为静态,将Sections设置为3,表示有三个分区,如图-36所示:

图-36

步骤二:表头视图、分区和单元格

在storyboard中可以直接操作静态表视图的表头视图、分区和单元格,包括拖放视图和控件,设置坐标和宽高,还可以直接复制粘贴。

首先设置表头视图,直接拖放一个View控件到TableView中,注意要摆放到表头视图所在的位置(在单元格的前面),如图-37所示:

图-37

在View视图界面上直接拖放所需要的控件,并在右边栏的检查器中设置各个控件的相关属性,如图-38所示:

图-38

其次设置每个TableViewCell,本案例中有三个分区,第一个分区何第二个分区都有三个单元格,第三个分区有一个单元格。每个分区的单元格都是拖放的一个TableViewCell对象,先设置前两个分区的单元格。

选中需要编辑的单元格,在右边栏的第四个检查器中可以设置单元格的各种属性,包括单元格的样式,辅助视图的样式,分隔线的样式,图片等,如图-39所示:

图-39

然后根据界面需求直接将对象库中的控件拖放到TableViewCell的ContentView中,其中第二个分区的第二个单元格还需要自定义辅助视图,在Storyboard中自定义辅助视图也很简单,将一个Switch控件拖放到场景中,但不要放进视图控制器中,如图-40所示:

图-40

选中场景中TableViewCell,在右边栏的检查器六中(或选中TableViewCell点右键),连接accessoryView到该控件,如图-41所示:

图-41

第一分区和第二分区的tableViewCell设置完成后,Storybaord中的界面如图-42所示:

图-42

接下来设置第三个分区的单元格,第三个分区的单元格只有一个,但是单元格的高度是自定义的,首先选中单元格,在右边栏的检查器四中将style设置为Custom,在检查器五中设置单元格的高度,如图-43所示:

图-43

然后调整整个TableView的高度,选中场景在右边栏的检查器四中将Size 设置为Freeform,如图-44所示:

图-44

再选中tableView,在检查器五中设置TableView的高度,如图-45所示:

图-45

最后在tableViewCell的ContentView上拖放界面所需要的控件,并设置相关属性,最后完成的效果如图-46所示:

图-46

步骤三:删除三问方法

创建一个表视图控制器类TRMusicTableViewController,继承至UITableViewController,注意不要再带有xib文件,将TRMusicTableViewController和Storyboard中的场景进行绑定,如图-47所示:

图-47

然后在TRMusicTableViewController.m文件中删除自动生成的三问协议U方法,通过Storyboard搭建的静态表视图不在需要通过代码加载数据,Storyboard会自动帮我们完成创建,可以根据程序需要实现表视图其他的委托事件的响应方法,例如didSelectRowAtIndexPath:方法。

步骤四:通过Segue实现跳转

在Storyboard中点击单元格Cell跳转和点击辅助视图AccessoryView跳转都可以通过Segue来实现,不需要额外写代码。

首先在storyboard中另外拖放两个场景,然后选中第一个分区的第一个单元格,按住Control键往第二个场景上拖拽,释放鼠标选Selection Segue选项下的Push模式即完成通过点击单元格跳转,如图-48所示:

图-48

再次选中第一个分区的第一个单元格,按住Control键往第三个场景上拖拽,释放鼠标,这次选择Accessory Action选项下的Push模式即完成通过点击单元格的辅助视图完成跳转,如图-49所示:

 

转载于:https://www.cnblogs.com/52190112cn/p/5049388.html


http://chatgpt.dhexx.cn/article/m0JfeyG3.shtml

相关文章

什么是故事板?(故事图、Storyboard)(软件显示效果的视觉草图,用于视频创作和广告设计,表达作者的创意)

故事板是软件显示效果的视觉草图&#xff0c;用于视频创作和广告设计&#xff0c;表达作者的创意。20世纪90年代以来&#xff0c;电脑绘制软件渐渐取代了过去的手绘故事板&#xff0c;许多大制作的商业影片&#xff0c;都在拍摄之前用电脑动画模拟的方式创建故事板&#xff0c;…

JSONObject 使用方法详解

JSONObject-lib包是一个beans,collections,maps,java arrays和xml和JSON互相转换的包&#xff0c;本文给大家介绍jsonobject使用方法相关知识&#xff0c;感兴趣的朋友一起学习吧 1.JSONObject介绍 JSONObject-lib包是一个beans,collections,maps,java arrays和xml和JSON互相转…

JSONObject使用方法及详解

最近自己负责的项目涉及到JSON数据的解析,所以在学习之后讲讲自己的认识及见解,希望对大家有帮助. 首先我们来讲讲JSONObject,JSON的数据格式如下: [ { name1 : { name2: { name3: value1 , name4: value2 } } } , { } ] 从外到里看&#xff0c;例子中就是一个数组&…

JSON与JAVA数据的转换。JSONObject.fromObject()和JSONObject.toBean()

六个架包&#xff08;666&#xff09; 首先我们系统中要用到JSON解析&#xff0c;所以要引入这六个架包。饱饱 不引入这六个架包的话&#xff0c;使用JSONObject.fromObject 和 SONObject.toBean会报错&#xff0c;而且有的时候编译器不会告诉你是架包缺少的错误哦&#xff…

使用JSONObject解析

一、JSON数据 1、JSON串访问方式&#xff1a; 2、简介 – JSON(JavaScript Object Notation) 是一种轻量级的数据 交换格式。 – JSON 数据的书写格式&#xff1a; " KEY " : " VALUE " JSON 结构有两种结构&#xff1a; 1、对象&#xff08;表的一列&…

JSONObject使用方法详解

1.JSONObject介绍 JSONObject-lib包是一个beans,collections,maps,java arrays和xml和JSON互相转换的包。 2.下载jar包 http://xiazai.jb51.net/201707/yuanma/lib_jb51.rar 提供了除JSONObject的jar之外依赖的其他6个jar包&#xff0c;一共7个jar文件 说明&#xff1a;因为工作…

JSONObject使用方法

1.JSONObject介绍 JSONObject-lib包是一个beans,collections,maps,java arrays和xml和JSON互相转换的包。 2.下载jar包 http://files.cnblogs.com/java-pan/lib.rar 提供了除JSONObject的jar之外依赖的其他6个jar包&#xff0c;一共7个jar文件 说明&#xff1a;因为工作中项目…

JSONObject类

&#xff08;1&#xff09;是什么&#xff1f; 阿里巴巴提供的一个json快速转换工具类&#xff0c;实现了Map接口&#xff0c;通过Key Value形式存储数据&#xff0c;初始化大小为16&#xff0c;有参构造方法需要传入一个Map。 项目中实际用途&#xff1a; 用于Json转具体的Ob…

JSON, JSONObject, JsonObject

JSON是一个抽象类 JSONObject是一个继承自JSON的类 JSON,JSONObject 和 JsonObject 1. JAR 包不同&#xff0c;对于可以调用的内置方法函数也不同 JSONObject属于 org.json.JSONObject包&#xff0c; JsonObject 属于 com.google.gson.JsonObject包 2. 存储方式不同 JS…

JSONObject

JSONObject JSONObject 介绍 // JSONObject 是一个类 JSONObject jsonObject = new JSONObject(); // JSONObject 只是一种数据结构,可以理解为JSON格式的数据结构(key-value 结构),可以使用put方法给json对象添加元素。 // JSONObject可以很方便的转换成字符串,也…

js构造函数详解

典型的面向对象编程语言&#xff08;比如C和Java&#xff09;&#xff0c;存在“类”&#xff08;class&#xff09;这个概念。所谓“类”就是对象的模板&#xff0c;对象就是“类”的实例。但是&#xff0c;在JavaScript语言的对象体系&#xff0c;不是基于“类”的&#xff0…

JavaScript构造函数

什么是构造函数 构造函数&#xff08;Constructor&#xff09;的创建方式和普通函数一样。但通常首字母进行大写&#xff0c;用于和普通函数区分。 但是当一个函数创建好以后&#xff0c;我们并不知道它是不是构造函数&#xff08;即使函数名的首字母为大写&#xff09;。只有…

C#构造函数

在C#中&#xff0c;构造函数就是与类具有相同名称的成员函数&#xff0c;通常使用类中的构造函数来初始化类的成员属性。C#中的构造函数有三种&#xff1a; 第一种&#xff1a;实例构造函数。 当使用new关键字创建类的对象时&#xff0c;可以使用实例构造函数来初始化和创建类…

构造函数与拷贝构造函数

拷贝构造函数和构造函数不能分开说&#xff0c;他们都是初始化对象的一种方法。但是我们这里用构造函数辅助说明拷贝构造函数&#xff0c;主要说说拷贝构造函数的声明&#xff0c;用途和使用注意事项。 众所周知&#xff0c;构造函数是一个初始化类对象的函数&#xff0c;即使不…

C# 静态构造函数

目录 写在前面语法格式用法与特性主要作用语法特性 关于泛型的测试测试代码运行结果 写在前面 今天在创建WPF自定义控件时&#xff0c;在模板代码中看到了静态构造函数这种写法&#xff0c;说来惭愧&#xff0c;以前在Java用过这种语法&#xff0c;心知C#也应该会有的&#xf…

构造函数详解

构造函数详解 类的6个默认的成员函数 构造函数的概念&#xff1a; 构造函数是一个特殊的成员函数&#xff0c;名字与类名相同&#xff0c;创建类类型对象时由编译器自动调用&#xff0c;保证每个数据成员都有一个合适的初始值&#xff0c;并且在对象的生命周期内只调用一次。…

C++中的指针类型与构造函数,析构函数

1. 指针类型的作用 1.1 指针取出字节 任何类型的指针占用的空间大小都是相同的 &#xff08;32位CPU是4字节&#xff1b;64位CPU是8字节&#xff09; 既然任何类型的指针占用的空间大小都是相同的&#xff0c;为什么指针还需要类型呢&#xff1f; 指针只是指向了一个内存地址…

c++拷贝构造函数

一. 什么是拷贝构造函数 首先对于普通类型的对象来说&#xff0c;它们之间的复制是很简单的&#xff0c;例如&#xff1a; int a 100; int b a; 而类对象与普通对象不同&#xff0c;类对象内部结构一般较为复杂&#xff0c;存在各种成员变量。 下面看一个类对象拷贝的简单…

C++构造函数

文章目录 1 构造函数的定义及特征2 默认构造函数2.1 合成的默认构造函数2.1.1 默认初始化2.1.2 合成的默认构造函数初始化类成员变量的规则2.1.3 有些场合不能使用合成的默认构造函数 2.2 全缺省的默认构造函数&#xff08;参数都为默认实参的构造函数&#xff09; 3 构造函数初…

C++ 构造函数详解

目录 0. 什么是构造函数 1. 默认构造函数 2. 一般构造函数 3. 拷贝构造函数 4. 转换构造函数 5. 移动构造函数 0. 什么是构造函数 在定义类的成员函数的时候&#xff0c;一般的成员函数与普通的全局函数没有太大的区别&#xff0c;在定义函数的时候都需要说明要返回的类…