Four Tips for Xcode Storyboard Users

Apple’s Xcode Storyboard is both your best friend and your worst enemy when it comes to developing state-of-the-art iOS, Mac OS X, tvOS, and watchOS apps. Sometimes, what would be really hard, like associating a function with a gesture is quick and easy. Sometimes, what should be easy, like toggling a property, requires hunting down a checkbox in an inspector that only shows up with the proper object selected.

Below are three common problems with Xcode Storyboards and what works for me to resolve them. Xcode Storyboard evolves with every release: these tips work for Xcode 7.1.1.

1. Is your Storyboard rendering as XML source code and not graphics?

Screen Shot 2015-11-23 at 9.56.10 AM

Somehow, someway Xcode magically switches the view of a storyboard from Interface Builder – Storyboard to Source Code. No matter, just secondary-click on the name of the storyboard in the Project Navigator and select Open As -> Interface Builder – Storyboard.

What is an Interface Builder? Back when the Mac OS X was the NextStep OS Interface Builder was a developer tool for creating views. This ancient app lives on the deep sub-basement of Xcode and sometimes unexpectedly appears.

2. Is your app blank in the simulator?

Screen Shot 2015-11-23 at 8.57.25 PM

It might be that you need to select your main view controller in Main.storyboard and set the “Is Initial View Controller” checkbox in the Attributes Inspector.

This usually happens when you have deleted the default view controller on a storyboard. You know, when you want to start over.

If the default storyboard is still around you can drag the Storyboard Entry Point arrow from the original view controller to point to your main view controller.

3. Having a hard time control-dragging between UI objects and the Document Outline?

Screen Shot 2015-11-23 at 9.13.06 PM

You’re not alone! You can use the Connections Inspector to drag-create connections without holding down the control key.

In the inspector just drag from the circle to the controller that you want to your UI object connected with.

Make sure you have the correct UI object on the storyboard and/or in the Document Outline selected so you connect the right things together.

4. Auto layout constraint values driving you batty?

Screen Shot 2015-11-23 at 9.14.46 PM

Setting up constraints is one of the most unintuitive parts of Xcode’s storyboards. Part of the problem is there a several ways to do it and Xcode doesn’t always seem to do what you ask it to do. Don’t worry! You can use the Document Outline to selection each individual constraint and adjust it’s values in the Size Inspector.

Generally I use the Align or Pin menus to initially set the auto layout constrains for an UI object.

Then I use the Resolve Auto Layout Issues menu to make the UI object conform to the initial constraint values with Update Frames.

Finally, since the UI object always looks weird I select each constraint in the Document Outline, adjust it in the Size Inspect, or delete it and start over.

There you go Xcoders! If I thinking of anything else I’ll update this post!

Fun with Core Graphics and Swift Part 2

Screen Shot 2015-11-09 at 9.24.06 PM

Hey, you have 10 minuets, don’t you?

Then you can add pinch and rotate gestures to our fake-genigraphics app. I didn’t realize it would be this easy. But sometimes Apple’s developer tools engineering team does something amazing–and gesture recognizers are super amazing.

A good way to start is to read the UIGestureRecognizer Tutorial on Ray Wenderlich’s website. I’ve said good things about Ray before. I don’t know him. However, Ray and his team of technical authors just have a way of spelling things out 100 times more clearly than Apple’s developer documentation.

After you’ve read the tutorial open up ViewController.swift in the fake-genigraphics project. Delete the boilerplate code in the ViewController class and replace it with the following code (from the tutorial):

Each of these functions is decorated with the @IBAction tag. That means we’re going to hook them up to events from our project’s Main.storyboard. This part still vexes me. I want to do everything in code and not use drag and drop to wire up events with functions (and properties with variables). Especially since I am left handed and to do a key part of the drag and drop I have to use the control key which only exists on the left side of my nifty Apple Magic Keypad.

Enough whining. Time to drag and drop!

Open up your Main.storyboard in the fake-genigraphics project. In the Object Library on the right find the section near the bottom with all the gesture recognizers. Drag a Pinch Gesture Recognizer out from the library and drop it on the BackgroundView in the storyboard. Now for the hard part: In the Document Outline on the left control-drag the Pinch Gesture Recognizer entry up and drop it on the ViewController entry. On the pop-up menu that suddenly appears choose Sent Actions Handle Pinch. (So weird).

Do these same steps again with the Rotation Gesture Recognizer. What you are doing is connecting events from the gesture recognizers to the functions in the ViewController marked with @IBAction.

Guess What? You’re done! Run your app in the simulator and on your iPhone or iPad. You can now zoom in and out and rotate the Background View like a pro. Notice how responsive and smooth the animation is. Alas there seems to be limits on how far you can zoom out. And you can’t rotate and zoom at the same time. I have trouble with rotating with my left hand. I’m convinced that nobody at Apple is left handled!

Fun with Core Graphics and Swift

Screen Shot 2015-11-07 at 12.15.12 AM

A long time ago in a galaxy far, far away… I was a computer graphics artist. Specifically I was a Genigraphics
console operator. I worked the night shift creating illustrations and slides with vector graphics for big corporations. This was the early 1980s and fast, cheap personal computers with color graphics had not quite been invented yet. Later when I learned to program the Apple Macintosh I had a head start–I had created hundreds of vector images using computer graphic primitives by hand! The ability to draw lines, circles, and rectangles with code blew my mind.

I’m thinking it would be fun to do some graphics exercises with Swift and Apple’s Core Graphics. Maybe recreate some of those Genigraphics images from 30 years ago. Somewhere in the basement I have a box of 35mm slides and 8″ floppy disks. Probably not readable but I should be able to create a few images from memory. Genigraphics was the ancient ancestor of PowerPoint and Keynote. Every element in an illustration or on a slide had to be created from a graphic primitive. A gradient color fill was created with 30 or 40 overlapping rectangles, each with an incrementally different color.  And remember all the primitives were created by a human hand!

One of the most time consuming effects involved creating a grid for a background. It involved much duplicating, aligning, and counting.

So let’s create a clunky Genigraphcis grid in Swift using Core Graphics and display it in a UIView on and iOS device!

Launch Xcode and create a new iOS single view application. Make sure you choose Swift as the language. It doesn’t matter what you call your app. Run the new blank app just to make sure Xcode did it’s job.

Kill the app and go back to Xcode. Create a new iOS Cocoa Touch Class source file. Call it BackgroundView and make it a subclass of UIView. Go to your main.storyboard and select the View in your View Controller. In the Identity Inspector set the class of the View to BackgroundView.

Run the app again just make sure it builds and then kill it and return to Xcode.

Select BackgroundView.swift. You should see a drawRect function provided by Apple. Delete all the comments so it’s ready for some grid code…

This function is called whenever iOS needs to paint your view on the screen. The rect is the area that needs to be painted. The first time drawRect is called the rect is the same size as your view. Later on when drawRect is called the rect is just the area of the view that needs to be updated. So I get the view width and height from the bounds. I’m also assuming the origin (left, top corner) is always 0,0. Add the following code to your drawRect function so you can get the the bounds width and height and compare it to the rect (technically called the “dirty rect” because that is the part of the view that needs to redrawn).

I like to define all my important variables together near the top of my functions because I always know where to find them. Swift let’s you declare and define variable throughout the code. (I only use that freedom for unimportant “throw away” variables that are used inside loops and other control structures.)

Add the code to define your gridlines starting points, lengths, and line width.

Core Graphics likes all your coordinates to be CGFloats. Since the resolution of an iOS device can be just about anything size these coordinates represent an idealize space as points. On a high resolution iOS device, like an iPhone 6s Plus you’re going to get 3 pixels for every point. My iPhone 6 Plus has a resolution of 1242 × 2208 but Core Graphics gives me 414 × 736 to work with. I’m just going to live with that for now.

I want a nice square grid so I use the either the viewWidth or viewHeight (which ever is smaller) divided 15 as the length of a grid cell.

Now it’s time to set the style of our lines: color and width. As I recall Genigraphics only had 64 colors or maybe 128. I’ll figure that out next weekend. In the meantime I choose blue with a width of 2.

Wow! That’s a lot of code just to set the color and line width. It’s a little complicated because Core Graphics is context-based. You have to get the current graphics context and modify it to draw. In the code above I’m also creating a color the hard way via a color space and RGBA (Red Green Blue Alpha) color values. All this work will let me have a fine degree of control of the color of the gridlines later on.

Finally, I’m going to draw my horizontal and vertical gridlines!

I’m just fooling around at this point so I don’t know if two repeat loops is the most efficient way to draw a grid. Right now I’m just happy to see a grid show up. I’ll optimize it later–if needed! To draw my lines I start at 0 and draw each line a cellLengh apart. CoreGraphics is a bit like Logo’s turtle graphics: I have to add drawing commands to the context, building up the image step by step behind the scenes.

If you run the code that this you will see nothing! Go ahead… I dare you!

That’s because you need to tell the graphics context to blast your drawing commands from the context on to the view. One line of code does it.

If you have been typing along you now have a custom UIView that draws a grid properly no matter now you hold your iPhone.

If you want to see the grid on your storyboard add

just above the class declaration. But be careful! Buggy Core Graphics rendering can freeze up Xcode. (It happened to me while writing this code.) I keep @IBDesignable commented out until I know my drawing code is working.

You can find all the code on GitHub.

Next week I’ll add some more complex drawing in the OG Genigraphics style. This is a good start for your own explorations. Have fun and don’t worry! You can’t blow up your computer by writing code.