iOS - UIStoryboard

简介: 前言 NS_CLASS_AVAILABLE_IOS(5_0) @interface UIStoryboard : NSObject @available(iOS 5.0, *) public class UIStoryboard : NSObjectStoryBoard 是苹果在 iOS5 中引入的新技术方案,目的是给纷繁复杂的 nib、xib 们一个温暖的家,让他们之间的关系更直观地展示出来,并提供了一种新的页面间跳转方式 Segue。

前言

    NS_CLASS_AVAILABLE_IOS(5_0) @interface UIStoryboard : NSObject
    @available(iOS 5.0, *)   public class UIStoryboard : NSObject
  • StoryBoard 是苹果在 iOS5 中引入的新技术方案,目的是给纷繁复杂的 nib、xib 们一个温暖的家,让他们之间的关系更直观地展示出来,并提供了一种新的页面间跳转方式 Segue。StoryBoard 的本质是一个 XML 文件,描述了若干窗体、组件、Auto Layout 约束等关键信息。Storyboard 不止是包含一个视图控件,而是所有的视图控件以及他们之间的关系。

  • Storyboard 对一个视图的官方术语是一个场景,但是一个场景其实就是一个 ViewController,用来描述软件界面,在 iPhone 中一次只能够展示一个场景,而在 iPad 中一次可以展示多个场景。一个项目中可以有不止一个 StoryBoard 文件,它们之间可以互相调用。

  • 使用 StoryBoard 的 iOS 项目均以初始化 StoryBoard 文件作为整个程序的初始化入口,UIViewController 类是由于被 StoryBoard 绑定而初始化,从而开始运行的。

1、StoryBoard

1.1 StoryBoard 视图界面

Storyboard1

  • 加载 StoryBoard 时会首先创建和显示箭头所指的控制器界面。

1.2 Storyboard 到代码的转换

  • 代码编译时编译器会自动将 Storyboard 转换为相应的代码。

    Storyboard8

    • 上图设置自动转换为:
        // 创建一个自定义的按钮
            UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    
            // 默认状态的文字
            [btn setTitle:@"点我啊" forState:UIControlStateNormal];
    
            // 默认状态的文字颜色
            [btn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    
            // 默认状态的背景
            [btn setBackgroundImage:[UIImage imageNamed:@"btn_01"] forState:UIControlStateNormal];

2、StoryBoard 界面设置

  • 1)启动 StoryBoard 设置

    • 修改 TARGETS => General => Development Info => Main Interface 的值。或者修改 Info.plist 文件中键 Main storyboard file base name 对应的值可以修改程序启动时加载的 StoryBoard。

      Storyboard6


      Storyboard7

    • 这个设置表明:程序启动时会加载 Main.storyboard

  • 2)View Controller 设置

    • Identity 设置面板

      Storyboard2

      Custom Class .
      -- Class StoryBoard 绑定的视图控制器
      -- Module
      Identity
      -- StoryBoard ID StoryBoard 的 ID
      -- Restoration ID
      --- Use StoryBoard ID 设置是否使用 StoryBoard ID
    • Attributes 设置面板

      Storyboard3

      Simulated Metrics .
      -- Size 屏幕尺寸
      --- Inferred 自动推断
      --- Freeform 自定义
      --- Page Sheet
      --- Form Sheet
      --- Master 主控制页
      --- Detail 详情页
      -- Orientation 屏幕方向
      --- Portrait 竖屏
      --- Landscape 横屏
      -- Status Bar 状态栏
      -- Top Bar 顶部控制条
      -- Bottom Bar 底部控制条
      View Controller
      -- Title
      --- Is Initial View Controller 设为初始场景,场景前面会显示灰色的小箭头,程序启动后会将这个场景作为应用程序的主屏幕
      -- Layout
      --- Adjust Scroll View Insets
      --- Hide Bottom Bar on Push 推出新的视图时隐藏底部控制条
      --- Resize View From Nib
      --- Use Full Screen (Deprecated)
      -- Extend Edges
      --- Under Top Bars
      --- Under Bottom Bars
      --- Under Opaque Bars
      -- Transition Style 设置页面出现效果
      --- Cover Vertical 向上推出
      --- Flip Horizontal 水平翻转
      --- Cross Dissoive 出现
      --- Partial Curl 向上翻页
      -- Presentation
      --- Full Screen
      --- Current Context
      --- Page Sheet
      --- Form Sheet
      --- Over Full Screen
      --- Over Current Context
      ---- Defines Context
      ---- Provides Context
      -- Content Size
      --- Use Preferred Explicit Size
  • 3)View 设置

    • Attributes 设置面板

      Storyboard4

      View .
      -- Mode
      -- Tag
      -- Interaction
      --- User Interaction Enabled 用户交互属性
      --- Multiple Touch 多点触控
      -- Alpha
      -- Background 背景颜色
      -- Tint 前景颜色
      -- Drawing
      --- Opaque
      --- Hidden 隐藏视图
      --- Clears Graphics Context
      --- Clip Subviews 子视图范围不允许超过父视图
      --- Autoresize Subviews 允许子视图随父视图缩放
      -- Stretching

3、StoryBoard 关联

3.1 添加控件代码关联

  • 打开 Assistant Editor 同时显示界面设计与代码,按住 Ctrl 键同时拖动控件到代码里,在弹出的上下文菜单中设置需要关联的类型,即可在代码里自动生成代码,这里主要有两种关联类型,一种是 Outlet 连接,就是在代码里创建界面元素的成员变量引用,另一种是 Action 事件,把界面元素的响应事件方法添加到代码里来。如果已经创建了代码,也可以把控件直接拖放到对应代码上,这时候就不是插入而是直接建立连接了。

  • 1) IBAction:
    从返回值角度上看,作用相当于 void,只有返回值声明为 IBAction 的方法,才能跟 storyboard 中的控件进行连线。

  • 2) IBOutlet:
    只有声明为 IBOutlet 的属性,才能跟 storyboard 中的控件进行连线。

  • 3) 连线容易出现的问题:
    如果遇到这种错误,90% 的可能都是因为连线有问题,比如一些线已经 “过期”。

    • 1> 连接的方法代码被删掉,但是连线没有去掉:

              unrecognized selector sent to instance 0x7f9bf9610910libc++abi.dylib: terminating with 
          uncaught exception of type NSException
    • 2> 连接的属性代码被删掉,但是连线没有去掉:

              'NSUnknownKeyException', reason: '[<ViewController 0x7fdf7048b200> setValue:forUndefinedKey:]: 
          this class is not key value coding-compliant for the key
  • Objective-C

        // Outlet 连接
        @property (weak, nonatomic) IBOutlet UILabel *myLabel;
    
        // Action 事件
        - (IBAction)buttonClick:(UIButton *)sender {
    
        }
  • Swift

        // Outlet 连接
        @IBOutlet weak var myLabel: UILabel!
    
        // Action 事件
        @IBAction func buttonClick(sender: UIButton) {
    
        }

3.2 添加 segue 关联

  • 右键(或 control + 鼠标左键)拖动控件到目标场景,在弹出的上下文菜单中选择 show 等。如果是两个 Controller 之间建立包含关联,则上下文之间会有 Relationship Segue 的选项,选择 view controller 即可。

  • segue 界面关联类型:

    Storyboard5

    Relationship Segue 包含关联
    show 导航推出,推出页自带返回按钮
    show detail 详情推出
    present modally 视图控制器之间跳转
    popover presentation 视图控制器之间跳转返回
    custom 自定义方式跳转
  • Objective-C

        // 系统自带场景跳转相关方法,可以不写该方法
        - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    
            /*
                segue:场景里跳转的线
                sender:触发跳转的对象
            */
    
            // 获取目标视图控制器
            UIViewController *viewController = segue.destinationViewController;
            viewController.view.backgroundColor = [UIColor orangeColor];
        }
  • Swift

        // 系统自带场景跳转相关方法,可以不写该方法
        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    
            /*
                segue:场景里跳转的线
                sender:触发跳转的对象
            */
    
            // 获取目标视图控制器
            let viewController = segue.destinationViewController
            viewController.view.backgroundColor = UIColor.purpleColor()
        }

4、StoryBoard 场景跳转

  • 1)创建 按钮 与 Controller 间 segue 关联,无需添加代码,直接点击按钮即可实现页面跳转。

  • 2)创建 Controller 与 Controller 间 segue 关联,并设置 segue 的 Identifier 值,在按钮点击响应事件中添加页面跳转代码。

    • Objective-C

          // 根据 segue Identifier 跳转界面
          [self performSegueWithIdentifier:@"segueIdentifier" sender:self];
    • Swift

          // 根据 segue Identifier 跳转界面
          self.performSegueWithIdentifier("segueIdentifier", sender: self)
  • 3)设置要跳转到的 Controller 的 StoryBoard ID,在按钮点击响应事件中添加页面跳转代码。

    • Name:StoryBoard 文件名称,Identifier:ViewController 中设置的 StoryBoard ID 名称

    • Objective-C

          UIViewController *secondViewController = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"storyboardID"];
      
          UIViewController *secondViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"storyboardID"];
      
          [self presentViewController:secondViewController animated:YES completion:nil];
    • Swift

          let secondViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("storyboardID") 
      
          let secondViewController = self.storyboard!.instantiateViewControllerWithIdentifier("storyboardID") 
      
          self.presentViewController(secondViewController, animated: true, completion: nil)
  • 4)不同 StoryBoard 文件中,设置要跳转到的 Controller 的 Is Initial View Controller 或者 StoryBoard ID,在按钮点击响应事件中添加页面跳转代码。

    • 若 StoryBoard 中设置了 Is Initial View Controller 可以直接使用 instantiateInitialViewController 初始化,若 StoryBoard 中没有设置 Is Initial View Controller 必须使用 instantiateViewControllerWithIdentifier 初始化。

    • Objective-C

          UIViewController *secondStoryBoardVC = [[UIStoryboard storyboardWithName:@"secondStoryBoard" bundle:nil] instantiateInitialViewController];
      
          UIViewController *secondStoryBoardVC = [[UIStoryboard storyboardWithName:@"secondStoryBoard" bundle:nil] instantiateViewControllerWithIdentifier:@"secondStoryBoard"];
      
          [self presentViewController:secondStoryBoardVC animated:YES completion:nil];
    • Swift

          let secondStoryBoardVC = UIStoryboard(name: "secondStoryBoard", bundle: nil).instantiateInitialViewController()!
      
          let secondStoryBoardVC = UIStoryboard(name: "secondStoryBoard", bundle: nil).instantiateViewControllerWithIdentifier("secondStoryboardID")
      
          self.presentViewController(secondStoryBoardVC, animated: true, completion: nil)

5、StoryBoard 页面传值

  • 1)Segue 传值 - 正反传值

    • Objective-C

          // 系统自带场景跳转相关方法
          - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
      
              // 1、发送方,获取输入框中的数据
              NSString *msg = _sendTextField.text;                                                
              UIViewController *vc = segue.destinationViewController;
      
              // 2、发送方,发送数据,Key 与接收方设置的接收变量需一致
              [vc setValue:msg forKey:@"passData"];
          }
      
          // 3、接收方,声明接受数据变量,需与发送方设置的 Key 一致
          @property(nonatomic, retain)NSString *passData;
      
          // 4、接收方,接收数据
          _receiveLabel.text = _passData;
    • Swift

          // 系统自带场景跳转相关方法
          override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
      
              // 1、发送方,获取输入框中的数据
              let msg = sendTextField.text
      
              let vc = segue.destinationViewController 
      
              // 2、发送方,发送数据,Key 与接收方设置的接收变量需一致
              vc.setValue(msg, forKey: "passData")
          }
      
          // 3、接收方,声明接受数据变量,需与发送方设置的 Key 一致
          var passData:String?
      
          // 4、接收方,接收数据
          receiveLabel.text = passData
  • 2)复合传值

  • 3)单例传值
  • 4)userDefaults 传值

  • 5)代理传值
  • 6)Block/闭包 传值

目录
相关文章
|
iOS开发
iOS开发UI之日期控件的使用(UIDatePicker)
iOS开发UI之日期控件的使用(UIDatePicker)
441 0
|
3月前
|
测试技术 Swift iOS开发
探索iOS自动化测试:使用Swift编写UI测试
【8月更文挑战第31天】在软件开发的海洋中,自动化测试是保证船只不偏离航线的灯塔。本文将带领读者启航,深入探索iOS应用的自动化UI测试。我们将通过Swift语言,点亮代码的灯塔,照亮测试的道路。文章不仅会展示如何搭建测试环境,还会提供实用的代码示例,让理论知识在实践中生根发芽。无论你是新手还是有经验的开发者,这篇文章都将是你技能提升之旅的宝贵指南。
|
机器学习/深度学习 安全 测试技术
阿里云EMAS-专家测试服务iOS和Android上百种机型性能、兼容及UI等测试
阿里云EMAS测试专家有着集团内部多个日活过亿规模APP经验,提供EMAS专家测试,客户只需提交测试需求,从用例设计、脚本录制、海量机型测试、整理测试结果、48小时输出专家测试报告均由阿里云EMAS测试专家一站式服务完成。覆盖功能测试、深度兼容测试、性能测试、UI适配测试以及隐私合规检测等,帮助用户以更低成本获得高质量的全面测试能力,可用于APP正式发版前验收,规避手机APP上线前或发版过程中各类隐患。
518 0
阿里云EMAS-专家测试服务iOS和Android上百种机型性能、兼容及UI等测试
|
jenkins 测试技术 macaca
iOS UI 自动化测试原理以及在 Trip.com 的应用实践
笔者入职 Trip.com 已满一年,回顾这一年的工作历程,约一半的时间都在做 UI 自动化测试相关内容。从而,笔者更深入地研究了 iOS 平台下的自动化测试技术,目前也在负责部门 App 自动化测试平台的搭建和维护。故想借这篇文章一并将所踩过的坑以及学习到的技术,系统且全面地整理出分享给大家。
387 0
iOS UI 自动化测试原理以及在 Trip.com 的应用实践
|
iOS开发
iOS开发UI篇 - Quartz 2D简单使用
iOS开发UI篇 - Quartz 2D简单使用
iOS开发UI篇 - Quartz 2D简单使用
|
缓存 运维 监控
如何优化iOS系统上的图文评论UI界面
在我们的社交 APP 上,⽤户的动态由精美的照⽚ 、视频和⽂字组成。对于每张照⽚和视频, 我 们都会展示出完整的标题和五个最新评论。由于⽤户喜欢使⽤标题来讲述照⽚背后的故事, 因此它们通常很⻓ 、很复杂, 并且可能包含超链 接和表情符号。渲染如此复杂的⽂本带来了⼀些问题, 它在滚动时造成性能下降。 即使在 iPhone 12 这样的新设备上, 复杂标题的初始⽂本绘制需要⻓达 50 毫秒, ⽽⽂本展示 需要⻓达 30 毫秒, 渲染速度很慢。⽂本问题还是简单问题, 有时我们需要加载更加复杂的图⽚甚⾄视频。所有这些步骤都发⽣在 UI 线程上, 导致app在⽤户滚动时丢帧。
如何优化iOS系统上的图文评论UI界面
|
存储 数据库 开发者
iOS9系列专题五——全新的联系人与联系人UI框架(二)
iOS9系列专题五——全新的联系人与联系人UI框架
393 0
iOS9系列专题五——全新的联系人与联系人UI框架(二)
|
编解码 安全 Linux
flutter 在windows和linux上运行IOS UI模拟器
之前发视频总是有人留言,我用的什么模拟器,今天给大家说一下 我一般用的是device_preview这个插件,这个插件的闲置是只能做UI上的模拟,并没有真正的运行环境。 近似您的应用程序在另一台设备上的外观和性能。
395 0
|
iOS开发 C++
iOS子线程更新UI的两种方法
iOS子线程更新UI的两种方法
524 0
|
API iOS开发 开发者
iOS9系列专题五——全新的联系人与联系人UI框架(一)
iOS9系列专题五——全新的联系人与联系人UI框架
207 0