I’ve been updating apps for iOS 7 in addition to writing a book about it, so I thought I’d share what I’ve learned. If you’re updating apps for iOS 7 (and especially if you’re still supporting iOS 6), read on. I hope you learn something here.
Table Views
Table views in iOS 7 can’t return 0 from -tableView:heightForHeaderInSection
for a grouped table view (UITableViewStyleGrouped). Try switching to a plain table view (UITableViewStylePlain) if you don’t want a header. In iOS 7, both table views appear nearly the same visually, so you’re not out much by switching to plain.
Make sure to nil your delegates and data sources on table views, too. (Thanks to Stuart Hall for pointing this out.)
- (void)dealloc { self.tableView.delegate = nil; self.tableView.dataSource = nil; }
Why your views are hidden beneath the status and navigation bars (and what to do about it)
If you had an app that was built with the iOS 6 SDK and recently tried to build it with the iOS 7 SDK, you may have noticed that the tops of your views were hidden by the status bar and navigation bar. You can thank Apple for the translucency effect in iOS 7, where the status bar and navigation bar appear to be translucent. The real problem is that they’ve changed the height of the view – the top of the view on a UIViewController used to be at the bottom of the (opaque) status bar. Or if you had a navigation bar, too, the top of the view was positioned at the bottom of that. Not so any more – Apple wants views to appear underneath the status and navigation bars, especially when scrolling as in a scroll view or table view. Here’s how you can determine the height of those if you’re supporting both iOS 6 and 7:
- (CGFloat)topOfViewOffset
{
CGFloat top = 0;
if ([self respondsToSelector:@selector(topLayoutGuide)])
{
top = self.topLayoutGuide.length;
}
return top;
}
The respondsToSelector verifies that yes, indeed, we can call the topLayoutGuide
method on our UIViewController
. That is, we’re running on iOS 7 or above. If your target is iOS 7, no need to create a topOfViewOffset
method – you can just call self.topLayoutGuide.length
in your view controller.
I’m supporting iOS 6, so I’ve added the above method to a category on UIViewController
which saves me the trouble of copying it to every single one of my view controllers. I can just import that category and do something like this in my view controller:
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
CGFloat topPadding = 10;
self.headlineLabel.frame =
CGRectMake(10, self.topOfView + topPadding, self.view.frame.size.width - 20, 30);
}
Make sure to call topOfViewOffset
(or topLayoutGuide
) in viewDidLayoutSubviews
, not in viewDidLoad
. Stuff’s all wacky in viewDidLoad
- calling topLayoutGuide.length
there returns a big fat 0.
Hide the status bar
If you want to hide the status bar, just implement this method in your view controller:
- (BOOL)prefersStatusBarHidden
{
return YES;
}
Text to Speech with AVSpeechSynthesis
iOS 7 introduces Text to Speech with the AVSpeechSynthesis API. Using it is really easy:
AVSpeechSynthesizer *synthesizer = [[AVSpeechSynthesizer alloc] init];
AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:@"Hey there!"];
[synthesizer speakUtterance:utterance];
There are voices, volume, pitch, delegates, and more in this API. If you want to learn more, check out the docs or get yourself a copy of Developing an iOS 7 Edge. (Disclaimer: I co-authored it and it’s an awesome way to get up to speed on iOS 7. ;)
Conclusion
There’s a lot of new stuff in iOS 7, and a lot of changes to the way things used to work. Updating apps has been a struggle for me – especially in handling the translucent status and navigation bars – so I hope this saves you a ton of time. I’ll be updating this post as I learn more, so if you want to learn new things as I learn them, sign up in the form below.