IBOutlet and IBAction

167

在Xcode和Interface Builder中使用IBOutlets和IBActions的目的是什么?

如果我不使用IBOutlets和IBActions会有什么区别吗?


Swift:

@IBOutlet weak var textField: UITextField!

@IBAction func buttonPressed(_ sender: Any) { /* ... */ }

Objective-C:

@property (nonatomic, weak) IBOutlet UITextField *textField;

- (IBAction)buttonPressed:(id)sender { /* ... */ }

14
所有答案都提到了相同的想法,但没有人解释为什么如果你在源代码中不包含IBAction/IBOutlet,Interface Builder似乎仍然能够正常工作。除了使用IBAction和IBOutlet之外,是否还有其他原因?或者将它们省略掉也可以吗? - bobobobo
2
迈克尔·罗杰斯在下面的回答中解释了为什么即使省略了IBAction,代码仍然能够正常工作。 - Krishna
IBAction存在于目标-动作交互机制的一部分,您可以在此处了解IBAction如何适合其中:https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaEncyclopedia/Target-Action/Target-Action.html#//apple_ref/doc/uid/TP40010810-CH12您可以在此处了解插座:https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaEncyclopedia/Outlets/Outlets.html#//apple_ref/doc/uid/TP40010810-CH10-SW1 - William Power
11个回答

216

IBActionIBOutlet 是宏定义,用于表示可以在界面构建器中引用的变量和方法。

IBAction 解析为 void,而 IBOutlet 不解析为任何内容,但它们向 Xcode 和界面构建器表明这些变量和方法可以在界面构建器中使用,将 UI 元素链接到您的代码。

如果您根本不打算使用界面构建器,则不需要再代码中使用它们,但如果您要使用界面构建器,则需要为将在 IB 中使用的方法指定 IBAction,并为将在 IB 中使用的对象指定 IBOutlet


你需要为将在IB中使用的方法指定IBAction,为将在IB中使用的对象指定IBOutlet。它们有什么区别? - cyrilchampier
4
IBActions和方法之间的差异与IBOutlet和对象之间的差异相同。IBActions用于处理方法,IBOutlet用于连接对象。 - Jasarien
仅作澄清,由于我的帖子已被编辑,IBOutlet不会解析为id。考虑这个例子:IBOutlet UILabel *nameLabel; - 如果IBOutlet解析为id,那么该代码将读取id UIlabel *namelabel;,这会产生编译器错误。正如我最初所述,IBOutlet不会解析为任何内容。 - Jasarien

38
传统的在Interface Builder中标记一个方法使得你可以拖动连接到它上面的方式是让这个方法返回类型为IBAction。然而,如果你将方法改为void类型(因为IBAction被定义为void),并提供一个(id)参数,该方法仍然可见。这提供了额外的灵活性。
这三种方法都可以从Interface Builder中看到:
-(void) someMethod1:(id) sender; 
-(IBAction) someMethod2; 
-(IBAction) someMethod3:(id) sender;

详细信息请参见苹果的Interface Builder用户指南,特别是标题为Xcode Integration的部分。


1
这是上述指南建议的链接:https://developer.apple.com/library/ios/recipes/xcode_help-interface_builder/_index.html - Aggressor

32

如果您使用界面构建器(因此有IB前缀)来创建GUI组件,则需要使用IBOutlet和IBAction。IBOutlet用于将应用程序中的属性与IB中的组件相关联,而IBAction用于允许将方法与IB中的操作相关联。

例如,假设您在IB中定义了一个按钮和标签。为了通过按下按钮动态更改标签的值,您需要在应用程序中定义一个类似以下的属性和操作:

UILabel IBOutlet *myLabel;
- (IBAction)pushme:(id)sender;

然后在IB中,您需要将myLabel与标签连接,并将pushme方法与按钮连接。这些连接需要具有IBAction和IBOutlet才能在IB中存在。


13
如果不包括IBOutlet标签,为什么它仍然有效? - bobobobo
8
这些宏在编译时不起作用,只是为了让界面构建应用程序能够在源代码中找到这些方法和接口构建文件,以便您可以在接口构建器和您的代码之间拖动,在连接建立后再也不重要了。 - Nathan Day
IBAction在编辑时也至少过去十年没有做任何事情。您也可以在Interface Builder中连接一个(void)方法。 - J. Cocoe

7
我在学习键值编码时遇到了这个图表,认为它可能对某些人有所帮助。它有助于理解IBOutlet的含义。
通过查看流程图,可以看出IBOutlets只是为了将属性名称与Nib文件中的控件名称匹配而存在。

How nib file is loaded, screenshot of Matt's online book for iOS6


这个答案解释了IBOutlets为什么和如何工作,而不仅仅是它们做什么。 - Orange Mushroom

7

Interface Builder使用它们来确定可以与窗口/视图中使用的界面控件进行“连线”的成员和消息。

IBOutlet和IBAction仅作为标记存在,当Interface Builder在设计时解析您的代码时,它会寻找它们,它们不会对编译器生成的代码产生任何影响。


4
一个Outlet是从代码到UI的链接。如果你想显示或隐藏一个UI元素,如果你想获取一个文本字段的文本或启用或禁用一个元素(或其他许多事情),你必须在源代码中定义该对象的outlet,并通过“接口对象”将该outlet链接到UI元素。之后,你可以像在编码中使用任何其他变量一样使用outlet。
IBAction - 由用户界面对象触发的特殊方法。Interface Builder可以识别它们。
@interface Controller
{
  IBOutlet id textField; // links to TextField UI object
}

- (IBAction)doAction:(id)sender; // e.g. called when button pushed

如需更多信息,请参阅Apple文档

备注:本段内容涉及IT技术,建议专业人士进行阅读。


哦,不,IBOutlet不是那样用的。你是从哪里得到这个想法的? - Richard J. Ross III

3

这个问题中最受欢迎的评论之一特别问道:

所有的答案都提到了相同类型的想法...但没有人解释为什么如果在源代码中不包括IBAction/IBOutlet,Interface Builder似乎仍然可以正常工作。是否有其他原因需要使用IBAction和IBOutlet或者不使用它们也可以?


这个问题在 NSHipster 上有很好的回答:

IBAction

https://nshipster.com/ibaction-iboutlet-iboutletcollection/#ibaction

早在2004年(甚至更早),一个方法不再需要使用IBAction才能被Interface Builder所注意。任何具有签名-(void){name}:(id)sender的方法都将在outlets面板中可见。
尽管如此,许多开发人员仍然发现在方法声明中使用IBAction返回类型很有用,以表示特定方法是通过操作连接的。即使没有使用Storyboards/XIBs的项目也可能选择使用IBAction来调用目标/操作方法。

IBOutlet:

https://nshipster.com/ibaction-iboutlet-iboutletcollection/#iboutlet

与IBAction不同,IBOutlet仍然需要用于在代码中将属性与Storyboard或XIB中的对象连接起来。
通常情况下,在视图控制器和其管理的视图或控件之间建立IBOutlet连接(除了视图控制器可能针对响应者执行的任何IBAction之外)。但是,一个IBOutlet也可以用于公开顶层属性,例如另一个控制器或可以被引用的视图控制器访问的属性。

3

IBAction 和 IBOutlets 用于将在 Interface Builder 中创建的界面与控制器连接起来。如果您不使用 Interface Builder 并完全使用代码构建界面,则可以制作一个不使用它们的程序。但实际上,我们大多数人都使用 Interface Builder,一旦您想要在界面中实现一些交互性,就必须使用 IBActions 和 IBoutlets。


2

IBOutlet

  • IBOutlet是一个属性。
  • 当nib(IB)文件被加载时,它成为封装数据的一部分,连接到一个实例变量。
  • 每个连接都会被解档和重新建立。

IBAction

  • Attribute指示该方法是一个动作,您可以从Interface Builder中的故事板连接到该方法。

@ - 动态模式 IB - Interface Builder


1
当您使用Interface Builder时,可以使用连接检查器来设置带有事件处理程序的事件,事件处理程序应该是具有IBAction修饰符的函数。视图可以与相同类型的引用以及IBOutlet修饰符链接。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接