While vacationing in Hawaii recently I was contacted by a developer named Peter who had some iOS programming questions for me. Peter’s background is in WPF, just like me, and he is now moving into iOS programming (welcome to the club!). I replied letting him know that I would answer his questions once I returned to the mainland, what Hawaiians call the rest of the U.S.
Peter’s questions resonated with me. They were things that I, too, was unsure about when I first got into iOS programming, years ago. I assume that these questions must arise for many WPF developers getting into iOS, so I am sharing my reply to Peter here, for the benefit of others.
Our trip to Hawaii was great. The sunshine must have fried a few neurons, I forgot about your email. Thanks for the reminder. :)
I’ll start off by saying that my book iOS Programming for .NET Developers addresses what you’re asking about (and a whole lot more), so I’ll summarize here. You can read the book for more detail and background.
“The first thing I’m having trouble with is understanding how Apple wants us to style the controls. I’ve been doing some searching online and so far what I’ve found is that a lot of effects (table view cell dropshadow, gradients) are done through static images as the UIView’s background. This feels very wrong to me, you know after being used to having the “luxuries” of XAML borders and such. I found another way which is manipulating the Layers in code; this still feels kinda wrong. So, in short what is the recommended way of styling your UI? How do you do it? Do you use the designer?”
Unlike XAML technologies, which rely heavily on vector-based UI elements to replace a control’s UI, iOS views are quite often styled/customized with images. Styling can be done in code by directly setting properties on a UIView, or via appearance proxies, which is conceptually similar to the WPF styling system. That approach is somewhat limited in terms of what can be adjusted and how drastically. For example, you can use an appearance proxy to set a tintColor property on all UIButtons, but that just introduces a custom color into Apple’s color computation code. If you want to radically change the visual style of a UIButton, an image is the way to go.
I also felt the use of images was “wrong” at first, after so many years working with custom data/control templates, but I quickly got used to it. I don’t see the reliance on images to be a shortcoming, it’s actually a lot easier, assuming someone on your team is capable of producing attractive images.
I do most of an app’s styling in code, since app-specific styles use shared colors and resizable images defined in code. For one-off images in some UIView there is no reason not to apply them using Interface Builder, unless you prefer to keep all styling in code.
“The second issue I’m having trouble wrapping my head around is yet again with UI design. Basically as far as I understand UIView is the general container (I guess the closest thing to a border?). So, does this mean a page will be littered with a whole bunch of UIViews? For example if my page had 2 sections I would have 1 UIView for each section and a third in the middle to have some sort of divider?”
UIView is more akin to WPF’s UIElement than Border. UIView is the base class for all UIKit objects shown on an iPhone or iPad screen. It does not have a default appearance, but it does support having children (known as subviews) whose frames are relative to the top-left corner of the parent UIView. This is very similar to the visual tree concept in WPF. I wouldn’t say a screen/page is “littered” with UIViews. That’s like saying that a forest is littered with trees. Read Apple’s View Programming Guide for iOS to get a quick introduction.
“Lastly, layouts! Coming from WPF I’m used to percentages (Grid); things resizing based on the parent container’s size etc etc. I kind of cringe having to set fixed sizes, am I doing it wrong?”
Layout was based on frames (a.k.a. rectangles) and auto-resizing (a.k.a. springs and struts) until iOS 6 came out. Now we have AutoLayout, which I wrote an introduction about here. AutoLayout uses a system of constraints to define the layout logic for a set of UIViews, and reduces/eliminates the need for hard-coded frames. The downside of AutoLayout is that it can get pretty complicated for non-trivial views, and throws errors if the set of constraints you specify is incomplete or invalid.
Personally, I still use auto-resizing with frames, mostly because the projects I’m working on need to support iOS 5.1 and greater, so AutoLayout is not an option. I find working with AutoLayout in Interface Builder to be something like building a house of cards; it’s too easy to accidentally mess it up with a flick of the wrist. Some people think AutoLayout is great, though, so maybe they know something I don’t.
I hope this has been helpful for you. It takes a while, but eventually the iOS way of doing things feels just as natural as the WPF way.