{"id":5,"date":"2010-03-13T19:55:10","date_gmt":"2010-03-14T03:55:10","guid":{"rendered":"http:\/\/bynomial.com\/blog\/?p=5"},"modified":"2010-04-24T15:42:38","modified_gmt":"2010-04-24T23:42:38","slug":"iboutlet-and-ibaction","status":"publish","type":"post","link":"http:\/\/bynomial.com\/blog\/?p=5","title":{"rendered":"IBOutlet and IBAction"},"content":{"rendered":"<p>One of the first big confusions I confronted when learning to work with xcode and Interface Builder was the connection between things in my code (particularly those marked as IBOutlets or IBActions) and corresponding things in Interface Builder. \u00c2\u00a0In many languages, you expect every file you work with to be explicitly mentioned by name somewhere in the code base &#8211; with xib files, this isn&#8217;t always the case \u00e2\u20ac\u201c at least not in any obvious way.<\/p>\n<h1>The problem<\/h1>\n<p>To illustrate the confusion and its solution, let&#8217;s explore a quick example:<\/p>\n<div id=\"attachment_6\" style=\"width: 369px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/MVCh.png\"><img aria-describedby=\"caption-attachment-6\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-6\" title=\"MainViewController.h\" src=\"http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/MVCh.png\" alt=\"\" width=\"359\" height=\"108\" srcset=\"http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/MVCh.png 359w, http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/MVCh-300x90.png 300w\" sizes=\"(max-width: 359px) 100vw, 359px\" \/><\/a><p id=\"caption-attachment-6\" class=\"wp-caption-text\">MainViewController.h<\/p><\/div>\n<div id=\"attachment_7\" style=\"width: 309px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/MVCm.png\"><img aria-describedby=\"caption-attachment-7\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-7\" title=\"MainViewController.m\" src=\"http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/MVCm.png\" alt=\"\" width=\"299\" height=\"224\" \/><\/a><p id=\"caption-attachment-7\" class=\"wp-caption-text\">MainViewController.m<\/p><\/div>\n<p>This view controller will set up a screen according to its xib file (MainViewController.xib), and modify the label&#8217;s text to match the text of any buttons which are pressed.<\/p>\n<p>This is a relatively easy piece of code for a newbie. \u00c2\u00a0If you&#8217;re new to Interface Builder (IB), though, you might not know how to correctly connect the UIButtons and UILabel in IB to the instance variable (<em>label<\/em>) and method (<em>toggleLabel:<\/em>) for use at runtime. \u00c2\u00a0Below are the steps to do that.<\/p>\n<h1>The Solution<\/h1>\n<p>1. Make sure you&#8217;ve already created the pieces that need to be connected:<\/p>\n<ul>\n<li>The instance variables, such as <em>label<\/em> here, marked with IBOutlet in your header file,<\/li>\n<li>the methods that need to be activated by controls, such as <em>toggleLabel:<\/em> here, marked with the IBAction return type, and<\/li>\n<li>the objects, such as UIButtons or UILabels, in Interface Builder that will be connected.<\/li>\n<\/ul>\n<p>2. Right-click on &#8220;File&#8217;s Owner&#8221; in the MainViewController.xib window, which brings up a list of assignable properties of that object which IB knows about (see the figure below).<\/p>\n<p>3. Click the open circle to the right of <em>label<\/em>, and drag the blue line that appears over to the UILabel in your working xib area. \u00c2\u00a0This ensures that the instance variable label will point to this UILabel when it&#8217;s created for you at runtime.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-8\" title=\"IB1\" src=\"http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/IB1.png\" alt=\"\" width=\"754\" height=\"530\" srcset=\"http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/IB1.png 754w, http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/IB1-300x210.png 300w\" sizes=\"(max-width: 754px) 100vw, 754px\" \/><\/p>\n<p>4. Next connect buttons to actions. \u00c2\u00a0Drag from the open circle next to <em>toggleLabel:<\/em> over to one of the UIButtons (e.g. the <em>tree<\/em> button in the figure).<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-10\" title=\"IB2\" src=\"http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/IB2.png\" alt=\"\" width=\"748\" height=\"536\" srcset=\"http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/IB2.png 748w, http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/IB2-300x214.png 300w\" sizes=\"(max-width: 748px) 100vw, 748px\" \/><\/p>\n<p>5. A UIButton generates many events, although the primary one is called &#8220;Touch Up Inside&#8221; (insert dirty joke here), which essentially means the user pushed the button. \u00c2\u00a0Interface Builder doesn&#8217;t complete the connection between the button and your method until you specify which action you mean \u00e2\u20ac\u201c and 99% of the time with buttons, you just care about the Touch Up Inside action, so choose that one.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-9\" title=\"IB3\" src=\"http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/IB3.png\" alt=\"\" width=\"749\" height=\"535\" srcset=\"http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/IB3.png 749w, http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/IB3-300x214.png 300w\" sizes=\"(max-width: 749px) 100vw, 749px\" \/><\/p>\n<p>6. Repeat the same process for any other buttons you want to connect with this method (toggleLabel:). \u00c2\u00a0Note that you can connect as many controls as you want to a single method (IBAction), although you can only connect a single control to an instance variable (IBOutlet), which makes perfect sense from the perspective of the code.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-11\" title=\"IB4\" src=\"http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/IB4.png\" alt=\"\" width=\"761\" height=\"533\" srcset=\"http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/IB4.png 761w, http:\/\/bynomial.com\/blog\/wp-content\/uploads\/2010\/03\/IB4-300x210.png 300w\" sizes=\"(max-width: 761px) 100vw, 761px\" \/><\/p>\n<p>7. Celebrate! \u00c2\u00a0Good job.<\/p>\n<h1>How it works<\/h1>\n<p>From the compiler&#8217;s point of view, an IBAction is just the void return type, and IBOutlet is ignored. \u00c2\u00a0The compiler more-or-less doesn&#8217;t know about those terms.<\/p>\n<p>But they are very significant for Interface Builder. \u00c2\u00a0IB knows about your code, and it recognizes those terms as marking variables and methods that can be connected to objects in a xib file, just as we&#8217;ve done here.<\/p>\n<p>How does it work at runtime? \u00c2\u00a0Essentially, UIViewController, as the superclass of MainViewController, knows to look for a file named &#8220;MainViewController.xib.&#8221; \u00c2\u00a0Yes, the correspondence is actually determined by matching a filename against the name of the class (and, yes, this feels a little hacky to me, although I admit it&#8217;s very convenient). \u00c2\u00a0If that xib file exists, the view in it is created with all the properties (positioning, fonts, strings, colors, connections, etc) at runtime. \u00c2\u00a0If you have many UILabels in your view, and many instance variables pointing to UILabels, then the code that creates these views for you will need to know which pointers are meant to point to which objects \u00e2\u20ac\u201c that&#8217;s why we need to provide these connections. \u00c2\u00a0The information for those connections is stored in the xib file, which the UIViewController code handles for you.<\/p>\n<p>There are a lot more interesting details behind the curtains, but that is the subject of another post.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the first big confusions I confronted when learning to work with xcode and Interface Builder was the connection between things in my code (particularly those marked as IBOutlets or IBActions) and corresponding things in Interface Builder. \u00c2\u00a0In many languages, you expect every file you work with to be explicitly mentioned by name somewhere [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false},"categories":[5,4,3],"tags":[38,39,102],"_links":{"self":[{"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5"}],"collection":[{"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5"}],"version-history":[{"count":0,"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5\/revisions"}],"wp:attachment":[{"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/bynomial.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}