Inspired by Julia Evans who I’ve been following awhile and unabashedly posts about things she’s just learning, I’m going to start posting about some stuff I’m just learning! I might not know it all yet and might make mistakes!! This is exciting!!!
It turns out, though, that people really want you to use Storyboard and Interface Builder. There don’t seem to be official samples that don’t use them (I picked half a dozen simple looking samples and they all seemed to have .xib or Storyboard files). After much google search term massaging (many of my searches turned up guides that assumed Interface Builder or Storyboard), I turned up a few posts that got me started. The first one got me some basic code so I could get grounded. The second was a great overview “map” of where I was going. The third told me how to remove the generated Storyboard (the new app templates with current Xcode always include a Storyboard).
A little while later, I had “Hello World” without using the GUI tools to construct the layout (and here I am a week or so later posting about it!) Since I had so much trouble finding what I needed, I thought I’d re-write it here. It’s also a form of rubber-duck learning: while I explain this into my editor (to post on the web), I’ll understand it better! On to the steps! First get an empty-ish project setup:
- Run Xcode (this is assuming you have it installed which I won’t go into).
- Create a new project. Pick Single View Application. Name it whatever.
- Delete the Storyboard file. Do this by clicking on it, then pressing the delete key.
- In “Supporting Files”, open Info.plist. Highlight the line that mentions the Storyboard.
Now we can go add code! Let’s look at our files. First, because we’re learning, let’s look at where “main” is (what will run first):
I already had to go look up some stuff! Even though I know C and C++, I’ve never really looked at Objective-C before. One thing is Objective-C uses “@something” all over for various directives. Objective-C is clearly a stitched together monster of a language but I kind of like that. I assume
@autoreleasepool is for some kind of memory management so I’m not worrying about it just yet. But
NSStringFromClass([AppDelegate class]) …. huh. The other examples just had text like
@"AppDelegate". What’s the difference? The
@"AppDelegate" version is just constructing an
NSString (versus a bare null-terminated string) with a particular class name. Turns out I want the latter way because it’s interrogating a class to get its name (call
AppDelegate and construct an
NSString from it). This means if I renamed
AppDelegate to something else, I’d get a build error rather than a runtime error).
All this is doing is constructing some main framework app (I’d guess with an embedded event loop) that delegates a lot of work to my code. So what does
AppDelegate header file:
The AppDelegate implementation file:
The examples I was looking at wanted to save off a reference to the window and the main controller, so I modified these two files. AppDelegate header:
The modified AppDelegate implementation:
A lot to unpack here! First there’s a window created using the frame (bounding box) generated by asking the
UIScreen class for the
mainScreen and getting its
rootController is set with an instance of
ViewController which is another class generated by Xcode for the simple project. Then, the window is told what view it has inside it and what its root view controller is. That second line I didn’t have initially and while the code “ran” I got an error and it wasn’t quite working right (the simulator didn’t show the simulated top status bar with time, battery, etc. in it). Clearly this matters somehow, although not critically. I’ll figure it out later! Finally, the
ViewController. Its header I didn’t need to modify:
The original version of this file didn’t have a lot going on:
The default template assumes I’ll be using ‘nibs’ and Storyboard (nibs are files that reflect how you construct the UI in the Interface Builder to define your views). But I want to define the view myself in code. So I needed to modify it to support this:
This constructs a really basic view that uses the entire space, sets the background color to white, then puts a label showing “Hello world!” on the screen. Looking this over while I type this up, I notice that in two places I’m asking for
[UIScreen mainScreen] and doing something with it. Clearly this is probably not quite right and I’ll have to figure that out. But I have a working “hello world!” What did I learn?
- Lots of basic Objective-C: how strings and properties are created, interfaces, implementation, sending messages (i.e. calling methods), etc.
- Various UIKit APIs.
- How to navigate the UIKit docs so I could figure out how to use UILabel and set colors.
And now, hopefully when someone searches the web for “iOS app hello world programmatic view” or something like that they find this useful!