Friday, February 8, 2013

Fixed Gradient Strips

Last time I posted my solution to custom annotations on iOS. In the week since I have had a chance to refine that solution a bit. While it's still not ready for prime time it keeps edging closer. The most recent issue I have tackled is how to make the custom annotation window have a very similar look to that of the standard annotation window. You know the look .. translucent gradient on top with a slightly more opaque solid color on bottom. Sounds easy, right? Well it is easy when all of your annotation windows are the same height. But what would be the point of a custom annotation window with a fixed height?

I could use a standard gradient strip and stretch it to the height of the window, but that would mean the gradient would appear to peak at different heights on different sized windows. Too sloppy. Instead I created a fixed size gradient strip about the same height as the one you see on the standard annotation window .. I chose 26 points. When loading my custom annotation window I build two background views: upperView and lowerView. The upperView is 26 points high and uses the gradient strip as it's tiled background. The lowerView is the remaining height of the view (self.bounds.size.height - 26) and has a solid color the same as the ending color of the gradient. This produces a satisfying and consistent annotation window regardless of the overall height.

This is a simple solution to my problem. Got your own ideas about how to solve this? Leave me a note and tell me what you think.

Friday, February 1, 2013

Fun With Annotations

I have recently experienced the joy of creating custom map annotations for an iOS project. I found many examples online of how to create custom annotations .. none of them were simple. That surprised me. The problem is simple .. the solution should be equally simple.

First, let's all blame Apple for really missing the boat on this one. They could have made this very easy for us by supplying a convenient way to hook into the standard callout view for an annotation. Most of us simply want to add some additional views to the callout. To achieve this Apple could have supplied an addSubviewToCallout: method. Or better yet, Apple could have provided a mapView:calloutViewForAnnotation: method. This follows their own convention and would have made our lives easier.

The solutions I saw online are problematic .. some do not support panning and zooming. They are kludgey .. some require you to add a new annotation to the map as a phony callout. All seem goofy to me. So, out of frustration I developed my own method.

My solution is also a kludge (Apple is the only one that can fix this) .. but a fairly elegant one. Here is what I did.


Create a Custom Annotation

Create a subclass of MKAnnotationView, let's call it MyAnnotationView. It is important subclasses of MKAnnotationView are initialized using the initWithAnnotation:reuseId method. My initializer also takes a third parameter .. the name of a nib from which it loads the callout view. This allows for easy reuse of the solution.

initWithAnnotation:reuseId:nibName

Expose the Callout View

I added a calloutView property to MyAnnotationView so the map delegate could retrieve it later. MyAnnotationView doesn't know or care what you put into the callout view. It's up to the map delegate to perform any setup for the callout view.

Show the Callout on Selection

I implemented mapView:didSelectAnnotationView: and mapView:didDeselectAnnotationView: methods for the map delegate. These call corresponding methods on MyAnnotationView. When the annotation is selected, it's callout view is added as a subview to the annotation view. I place the callout above the annotation view, just like the standard callout. When the annotation is deselected, I call it's removeFromSuperview method.

What's Missing?

As you an see my annotation doesn't have the fancy pointer at the bottom like the standard callout. That's easy to remedy. Again, I'm loading the callout from a nib, so I could simply decorate the view in IB with a border image that points down. I will probably spend lots of time making this look just so, but my main objective -- create a reusable custom annotation -- has been accomplished.


Thursday, May 3, 2012

Testing with Frank

Okay. I've seen a lot of great stuff this week and I would love to share it all. But one of the highlights was a demonstration on testing with Frank given by Step Christopher. Frank is a really slick testing environment that lets you setup meaningful tests that clearly convey the application workflow in a way easily understandable by non-programmers. I'm excited about trying Frank in my own projects.

At the Ranch

This week I've been at the Big Nerd Ranch taking the Advanced iOS class with Jonathan Blocksom. I've wanted to take a BNR class since I first bought Cocoa Programming for Mac OS X by the Big Nerd himself, Aaron Hillegass. The BNR books take a very hands-on approach that I have found to be very effective. I was pleased to find out their courses use the same approach (even more so) and have a consistent feel to their books. For those that don't know, the Big Nerd Ranch offers a fully immersive learning environment. Students and instructors stay on the ranch, which gives you impromptu opportunities to ask questions and really pick someone's brain. It's been a blast! I have learned a ton and met some really great guys.

Thursday, March 22, 2012

Prototyping with App Cooker

I recently started a new project that requires a considerable amount of form entry on the iPad. The notion of using IB to mock up the UI seemed daunting, so I decided to look for prototyping alternatives. After an hour of digging around on the net and reading reviews I settled on App Cooker.

First impressions are important. If I don't get comfortable with a tool in the first 30 minutes of use then I probably never will. App Cooker did not disappoint. In no time I felt like an old pro. Building mockups is easy and intuitive. App Cooker provides easy access to most of your iOS widgets and views. It's easy to chain pages together so users can step through your prototype and see how the app should flow. The demo mode is simple yet effective.

App Cooker provides a lot of functionality beyond just prototyping that I have not had a chance to use. But even without those features it's a great tool .. one that I can easily recommend.

Monday, March 19, 2012

What's new, iPad?

So I got the "new" iPad on Friday. It's pretty .. very pretty. And coming from a first gen iPad it also seems very, very fast. I've had the opportunity lately to do some iOS development at my day job, so I think it makes sense to immerse myself with iOS. First impressions have been good. At this point I still can't see myself dropping the MacBook entirely. After all, I can't run Xcode on my iPad. But for most day-to-day tasks it works surprisingly well.

Balance

Someone suggested I need to blog more. I agree. It's time to rebalance my priorities and find more time for the simple things .. like blogging. So, stay tuned for updates!