iOS开发系列--XIB开发

2023-05-16

在iPhone开发中,一般都会用NIB文件来来负责界面显示,也就是MVC模型里面的视图对象,而NIB文件只包含用户界面元素,不包含任何源码,那么怎么让视图对象和视图控制器关联起来呢?这就需要用到两个非常重要的概念:插座变量(outlet)和文件拥有者代理对象(File's Owner)。

视图控制器的视图和Nib文件

视图控制器主要的职责就是配置和管理应用程序中所有的视图,一般来说,视图控制器的视图是放在一个Nib文件中,当然也可以不需要Nib文件,通过程序创建视图,典型的如UITableViewController这样的视图控制器,就可以不需要Nib文件。在创建视图控制器实例时,其中一个主要的构造函数 initWithNibName:bundle: 的第一个参数就是视图控制器对应的Nib文件的名字。视图控制器在其 loadView 方法中加载它的Nib文件。如果是使用 initWithNibName:bundle: 构造函数生成的实例,并且你想在视图加载完成后进行额外的设置,只要重写视图控制器的 viewDidLoad 方法就好了。

在Xcode中点击打开视图控制器的Nib文件(即RootViewController.xib文件),在Xcode中即可直接查看和编辑。文件包含三个对象,文件拥有者代理(File's Owner),第一响应者代理(First Responder)以及一个视图(View)。视图(View)是视图控制器的主视图,在主视图中还可以添加若干子视图。文件拥有者代理(File's Owner)代表Nib文件对应的视图控制器类。理解文件所有者代理的角色,以及如何建立文件所有者和Nib文件中界面元素之间的连接,是非常重要的。

201106072252.jpg

小贴士: 在Xcode中编辑Nib文件时,可以通过点击右上角工具栏按钮 201106072256.jpg  显示隐藏相应 面板 ,方便对界面编辑和属性设置。 

文件拥有者(File's Owner)

在一个Nib文件中,文件拥有者对象是其中最重要的对象之一,因为正是通过它,来建立起应用程序代码和Nib界面文件中对象之间的连接,具体来说,它就是对应Nib文件的视图控制器对象。以本项目为例,RootViewController.xib这个Nib文件的文件拥有者对象就是RootViewController类的实例。

一般来说,在使用模板同时创建UIViewController文件和对应的Nib文件时,它默认会设置Nib文件对应的文件拥有者为创建的UIViewController类。如果要修改或者设置Nib文件对应的文件拥有者,可以使用 Identity Inspector 面板进行设置。

201106080842.jpg

如上图所示, 本项目的RootViewController.xib文件对应的文件所有者,在Identity Inspector 面板中,Custom Class部分的Class项,可以看到对应的值是RootViewController,这表示文件拥有者就是RootViewController类的实例,就可以在Xcode中访问文件拥有者类里面标志为IBOutlet的属性和IBAction的方法,和Nib文件中的界面元素建立关联。

视图插座变量

在Xcode中,使用 Inspector 面板,或者在连接面板,可以查看、创建、删除对象之间的连接。要查看视图控制器的连接,可以通过以下步骤:

  1. 在Xcode的界面中,从左侧的文件组选中要查看的视图控制器的Xib文件
  2. 在视图编辑界面,点击选中 File's Owner
  3. 在 Inspector 面板,选中 Connection inspector,这里会显示文件所有者所有的插座连接
  4. 在视图编辑界面,按住Control键点击 File's Owner 或者在 File's Owner上点击右键,弹出一个黑色半透明的面板显示文件所有者的所有连接

201106090009.jpg

在上面第三步,右侧面板显示的连接面板和右键点击File's Owner弹出的半透明连接面板,显示的信息和作用都是一样的,可以根据个人习惯灵活使用。到目前为止唯一的连接是视图控制器的 view 插座变量。一个插座变量就对应视图控制器类的一个属性(有时候也可以是一个实例变量),只不过这个属性和nib文件中的某个界面元素连接在一起。此处的view的连接,表明当nib文件 RootViewController.xib 被加载,并且UIView的实例解档之后,视图控制器的view实例变量会被设置为指向nib文件中的视图。

201106090039.jpg

中间测试

在项目开发中,尤其在对开发工具和语言不熟悉的时候,需要经常性的对新增的功能进行测试,以确保当前功能运行是正常的。比如我们新增了RootViewController这个自定义视图控制器,需要去测试一下它是不是已经成功添加。要测试视图控制器工作正常,简单的办法修改视图控制器的视图的背景色,例如修改为粉红色背景,然后重新运行,看看是不是界面变成了红色背景。

要设置视图控制器的视图的背景色,步骤如下:

  1. 在Xcode的界面中,从左侧的文件组选中视图控制器的Xib文件(RootViewController.xib)
  2. 在右侧的功能区域,选择属性面板(Attributes inspector)
  3. 在编辑区域,选择视图
  4. 在视图的属性面板,点击背景色(Background)对应的颜色下拉框,会弹出颜色选择面板
  5. 在颜色选择面板,选择一个合适的颜色,例如粉红色
  6. 保存nib文件
  7. 点击左上角工具栏的Run按钮,编译运行项目
201106090138.jpg

正常情况下,编译应该不会出现任何错误,运行后会弹出模拟器,结果如下图所示:

201106090251.jpg

确认没有问题后,再将应用的背景色还原。还原的话,将视图的背景色设置为白色就好了。

配置视图

Xcode提供了一套对象库,可以直接添加到Nib文件中。其中一部分示界面元素,例如按钮和文本输入框;其他一部分是控制器对象,例如视图控制器。我们当前项目的nib文件已经包含了视图,现在只要添加按钮和文本输入框就好了。从对象库中将用户界面元素拖动到视图中,基本步骤如下:

  1. 在Xcode的界面中,从左侧的文件组选中视图控制器的Xib文件(RootViewController.xib)
  2. 在右侧的功能区域,显示对象库(object library)
  3. 添加一个按钮(UIButton),一个文本输入框(UITextField),两个文本标签(UILabel)到视图中。可以从对象库里面拖动并将它们放到视图
    201106090318.jpg
  4. 参考前面的原型设计,对界面元素的尺寸和布局进行调整
  5. 将右侧功能区域切换到属性面板(Attributes inspector)
  6. 选中文本输入框(Text Field),设置Placehold属性为“请输入姓名”
  7. 选中左上侧的文本标签(UILabel),设置Text属性为“姓名”
  8. 选中下面的文本标签(UILabel),设置Text属性为空,Alignment属性设置为居中对齐
  9. 选中按钮(UIButton),设置Title属性为“招呼”
  10. 设置好的界面如下所示:201106090505.jpg

如果我们想让用户在输入时有一些更好的体验,比如用户输入英文名时,默认会首字母大写;比如键盘会显示完成(Done)按键,点击后完成输入隐藏键盘。要支持这样的输入细节,通过设置文本框属性就可以完成:

  • 在Capitalization下拉列表,选择Words,以支持首字母大写
  • 在Return Key下拉列表,选择Done,以支持键盘上显示完成(Done)按键

201106090522.jpg

保存文件后,编译运行程序,可以看到运行的界面效果和我们在Xcode中摆放的效果是一样的。点击按钮,按钮会高亮,在文本输入框中点击,会弹出输入键盘,键盘里可以看到完成(Done)按钮。但是还不能根据输入的内容去显示文字,还不能隐藏键盘,因为目前我们还仅仅完成了视图部分的工作,还需要让视图中的对象和视图控制器的对象之间建立连接,并添加相应的逻辑,才能实现。

201106090526.jpg

实现视图控制器

实现视图控制器需要完成以下几件事:

  1. 定义插座变量和动作方法,和Nib文件的视图中的界面元素进行关联
  2. 实现点击按钮后的相关逻辑——根据输入的名字显示相应的招呼语,判断输入的名字是不是为空是不是超长
  3. 用户点击键盘上的完成(Done)按键后,键盘会消失

建立连接

从业务角度来看,我们需要和界面的几个元素建立关联:

  1. 文本输入框,获取它的输入文字
  2. 文本标签,让它显示特定文字
  3. 按钮,响应它的点击事件

在Xcode4之前,Interface Builder和Xcode是分开的,一般是先在Xcode中定义好插座变量和动作方法,然后再在InterfaceBuilder中去建立界面元素和视图控制器之间的连接,到Xcode4之后,Interface Builder和Xcode已经统一合并在了一起,所以这部分也有一些变化,Xcode4让这部分工作变的更加容易一些,可以直接从视图编辑界面拖动连接到代码文件。

在我们正在开发的SayHello项目中,现在我们需要添加一个动作方法到视图控制器,当界面上的按钮被点击时,它会发送一个sayHello:消息到视图控制器,所以接下来要为按钮创建一个sayHello:动作方法:

  1. 1、在Xcode中,选择视图控制器对应的Nib文件(RootViewController.xib)
  2. 2、显示Assistant editor201106090630.jpg
  3. 3、让Assistant显示视图控制器的头文件(RootViewController.h)
  4. 4、按住Control键,从Nib文件中的按钮拖动到头文件的方法声明代码区域201106090634.jpg
  5. 在弹出的面板中,将按钮和视图控制器之间的连接设置为动作(Action)
    • 设置 Connection 为 Action
    • 设置 Name 为 sayHello:
    • 设置 Type 为 id
    • 设置 Event 为 Touch Up Inside,也就是用户在点击按钮,然后释放后触发
    • 设置 Arguments 为 Sender
    • 201106090639.jpg
  6. 点击Connect建立连接

通过上面的为按钮添加动作的操作,完成了两件事

  1. 添加了相应的代码到视图控制器的类中
    头文件中增加了如下代码:

    - (IBAction)sayHello:(id)sender;

    并且实现文件中增加了相应的实现方法:

    - (IBAction)sayHello:(id)sender {

    }

    IBAction 是一个特殊的关键字,它唯一的作用是告诉Interface Builder将某个方法当成目标/动作关联中的动作。它被定义为void。

  2. 建立了按钮到视图控制器之间的连接。建立连接的意义,等同于在按钮上调用 addTarget:action:forControlEvents: ,并且 target 是文件拥有者(File's Owner)也就是视图控制器,action 是 sayHello: 方法,对应的事件是 UIControlEventTouchUpInside。

接下来要建立文本输入框和文本标签之间的连接:

  1. 1、在Xcode中,选择视图控制器对应的Nib文件(RootViewController.xib)
  2. 2、显示Assistant editor201106090630.jpg
  3. 3、让Assistant显示视图控制器的头文件(RootViewController.h)
  4. 4、按住Control键,从Nib文件中的文本输入框拖动到头文件的方法声明代码区域201106090654.jpg
  5. 5、在弹出的面板中,将文本输入框和视图控制器之间的连接设置为插座(Outlet)
    • 设置 Connection 为 Outlet
    • 设置 Name 为 nameTextField
    • 设置 Type 为 UITextField
    • 201106090704.jpg
  6. 6、点击Connect建立连接

通过上面的为文本输入框添加插座变量的操作,完成了两件事

  1. 添加了相应的代码到视图控制器的类中
    头文件中增加了如下代码:

     

    @property (nonatomic, retain) IBOutlet UITextField *nameTextField;

    并且实现文件中增加了相应的实现方法:

    在顶部增加了:

     

    @synthesize nameTextField;

    在 dealloc 方法中添加了

     

     

    [nameTextField release];

    在 viewDidUnload 方法中添加了:

     

     

    [self setNameTextField:nil];

    IBOutlet是一个特殊的关键字,它唯一的作用是通知Interface Builder将某个实例变量或者属性当成插座变量。实际上,这个关键字被定义为空白,因此在编译的时候它没有任何作用。

  2. 建立了文本输入框到视图控制器之间的连接。建立连接的意义,等同于在视图控制器上调用 setNameTextFiled: 方法,将文本输入框作为参数传入。

按照上面创建文本输入框插座变量相同的方法,再建立用来显示问候语的文本标签的插座变量,并且将插座变量命名为 greetingLabel,类型为 UILabel。

实现逻辑代码

点击视图中的按钮,它会向视图控制器发送 sayHello: 消息,之后,视图控制器会取得文本输入框文字内容,根据内容来更新用来显示问候语的文本标签的内容。以下是RootViewController.m文件中 sayHello: 方法代码的实现:

- (IBAction)sayHello:(id)sender {

// 获取文本输入框内容,并存储到变量中

NSString *nameString = nameTextField.text;

 

// 检查输入的名字是否为空,如果为空,弹出提示信息

if (nameString.length == 0) {

UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"名字不能为空" message:@"请输入名字后,重新点击按钮。" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];

[alertView show];

[alertView release];

greetingLabel.text = @"";

return;

}

 

// 检查名字是不是超过16个字符,超过16个字符自动截断

if (nameString.length > 16) {

nameString = [nameString substringToIndex:16];

}

 

// 根据输入的名字,生成问候语

NSString *greeting = [NSString stringWithFormat:@"你好,%@!", nameString];

// 显示问候语

greetingLabel.text = greeting;

}

对于这个方法有几点补充说明:

  • UIAlertView是专门用来显示消息提示对话框
  • stringWithFormat:方法符串按照格式化字符串所指定的格式创建一个新字符串。%@表明此处应该使用一个字符串对象来代替。
同时添加多个outlet
在IB中,选中一个view并右键点击,将会出现灰色的HUD,可以在其上方便地拖拉或设定事件和outlet。你可以同时打开多个这样的面板来一次性添加所有outlet。右键点击面板, 随便拖动一下面板,然后再打开另一个。你会发现前一个面板也留下来了 ,这样你就可以方便地进行拖拽设定了。
 
多个Outlet HUD
当然,对于成组和行为类似的IBOutlet,应该直接使用IBOutletCollection来进行处理会更方便。
问题1:下图中,如果弹出框中红色矩形没有内容,要如何建立?如何让xib控件与ViewController中的变量关联起来?
以上资料经综合整理各方面资料而成。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS开发系列--XIB开发 的相关文章

  • [OpenCV实战]15 基于深度学习的目标跟踪算法GOTURN

    目录 1 什么是对象跟踪和GOTURN 2 在OpenCV中使用GOTURN 3 GOTURN优缺点 4 参考 在这篇文章中 xff0c 我们将学习一种基于深度学习的目标跟踪算法GOTURN GOTURN在Caffe中搭建 xff0c 现在
  • **在Linux的shell脚本里激活conda 虚拟环境**

    在Linux的shell脚本里激活conda 虚拟环境 之前突发其想 xff0c 既然在命令行可以通过conda activate tf激活tf的虚拟环境 xff0c 那么能不能写个脚本实现呢 xff1f 费了好大劲 xff0c 发现并不行
  • Hierarchical Russian Roulette for Vertex Connections论文研读

    第二篇论文研读文章了 xff0c 虽然依旧很菜 xff0c 但这一篇开始就相对轻松一点了 文档种有些问题 xff0c 其中所有 实时 应该替换为 高效 Hierarchical Russian Roulette for Vertex Con
  • ARM通用中断控制器GIC之中断控制

    在阅读本章之前 xff0c 可以参考笔者之前关于GIC的一些描述 xff1a ARM通用中断控制器GIC generic Interrupt Controller 简介 ARM架构Generic Interrupt Controller G
  • 最小生成树之Kruskal算法

    给定一个无向图 xff0c 如果它任意两个顶点都联通并且是一棵树 xff0c 那么我们就称之为生成树 Spanning Tree 如果是带权值的无向图 xff0c 那么权值之和最小的生成树 xff0c 我们就称之为最小生成树 MST Min
  • xcode11解决:xcode multiple commands produce .../xxx/Assets.car

    最近在xcode 11上使用pod碰到一个问题 xff0c Assets car被生成多次 问题如下 xff1a Multiple commands produce 39 Users luowei Library Developer Xco
  • 算法 —— 冒泡排序

    冒泡排序 冒泡排序是比较两个相邻元素 xff0c 如果它们不符合预期的顺序就交换的一个排序过程 冒泡排序就像水中气泡上升到水面的运动一样 xff0c 数组的每个元素在每次迭代中都把当前迭中最大 或最小 的元素移动到最后 xff0c 因此被称
  • UICollectionView viewForSupplementaryElementOfKind 不调用

    发现UICollectionView 的 方法不调用 func collectionView collectionView UICollectionView viewForSupplementaryElementOfKind kind St
  • UICollectionViewCell 自动大小的两种常用方式

    方法一 xff1a 自动计算 override func viewDidLoad super viewDidLoad if let flowLayout 61 collectionView collectionViewLayout as U
  • UITableViewCell 图片自适应

    常见的一种方法是异步Completed时 xff0c 根据图片大小计算cell的高度并缓存到字典里后 xff0c 刷新tableView或indexPath 但这里介绍另一种更好的方式是使用约束处理 xff0c 对imageView的上下左
  • Swift编译死锁问题

    最近在Swift OC混编项目里遇到个奇怪的问题 xff0c 这样一行代码尽然引发了Swift编译过程死锁 xxSwiftModel salary 61 xxOCModel salary doubleValue 如果哪位大神知道根因 xff
  • 多线程及聊天室程序

    1 一个多线程程序 新建一个 win32 console application 取名 xff1a MultiThread 选空的工程 xff0c 并建立一个名为 MultiThread 的源文件编辑 xff1a include inclu
  • SQL Server 2008语句大全完整版

    61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 设置内存选项 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • Swift从相册选择图片,图文混排并且可以保存、上传数据

    博主最近突发奇想想做一个自己的日记本App xff0c 在过程中遇到了一些坑 xff0c 摸索了很久才做出一个简单的日记本功能 先来看看一下效果吧 xff1a 先来说说这次用到的一些东西吧 xff1a 1 UIImagePickerCont
  • 2022年ABC模块样题十套分享

    2022年ABC模块样题十套分享 样题分享传送门
  • C# WinForm基础

    1 WinForm基础 Form1 cs using System using System Collections Generic using System ComponentModel using System Data using S
  • 做独立开发的一些感想

    好久没在CSDN上写东西 xff0c 这次写点感想吧 想想自己独立开发也有好多年了 xff0c 从刚毕业做的在线销售系统 xff0c 再到spring boot做写的my finances xff0c 再后来转iOS做的万能输入法 我的浏览
  • Vue3之script-setup全面解析

    可能很多同学 xff08 包括我 xff09 刚上手 Vue 3 0 之后 xff0c 都会觉得开发过程似乎变得更繁琐了 xff0c Vue 官方团队当然不会无视群众的呼声 xff0c 如果你基于脚手架和 vue 文件开发 xff0c 那么
  • windows下hadoop的部署和使用

    本教程在windows10环境下安装配置hadoop 43 hbase 43 spark 一 下载压缩包 xff1a 1 JavaJDK xff0c 1 8以上 2 Hadoop2 8 3 xff0c 下载地址 xff1a http arc
  • VS2019 C++的跨平台开发——Cmake项目(二)

    这一篇主要补充Windows下WSL xff08 Linux 子系统 xff09 创建 以及在WSL和远程Linux系统下编译和调试CMake项目 Widnows下创建WSL 1 右键左下角的Windows图标 61 应用和功能 61 启用

随机推荐