Monday, July 18, 2011

Making Your Mac App Support Full Screen in 1 Minute

Full screen mode is a cool feature on Mac OS X Lion. I'd like to let my app support full screen. I googled, but did not find any tutorial. I thought there would be an option like'Support full screen' when a new project is created with the new Xcode 4.1 on Lion. Surprisingly, there is no that option. Today I watched a video of WWDC2011 and made this article. I am sure you can follow the steps to make your app support full screen in 1 minute.

I created a new Mac OS X Cocoa Application with Xcode 4.1 on Lion and named it MyFullScreen.

1. Set Base SDK Mac OS X 10.7

2. Choose MainMenu.xib in Project navigator

3. Choose 'Window - MyFullScreen' in Objects

4. Choose 'Primary Window' for Full Screen in Attributes inspector. You will see a new icon on the top-right corner of your main window. Run this app. It already supports full screen!

Make Full Screen

5. You need to add a menu item. Choose 'Menu - View', and then drag 'Full Screen Menu Item' in Object Library into 'Menu - View'.

Full Screen Menu Item

We are done! It is very easy.

Decreasing the iPhone/iPad app size

1. Delete unnecessary files.

2. Convert PNG images to JPG format. We like PNG because it supports transparency. But for those images without transparency, the size of png is twice of jpg file. I converted PNG files to JPG and reduced the app size from 17MB to 9MB.

3. For the universal app, iPad version could reuse retina @2x images.

The way to stop UIView animations

#import <QuartzCore/QuartzCore.h>

[self.view.layer removeAllAnimations];

Adding a framework in Xcode 4

The steps of adding a framework in Xcode 4:

1. Click current project in Project navigator.

2. Click a target in Project editor.

3. Choose Build Phases tab.

4. Expand Link Binary With Libraries

5. Click + button, add a framework.

6. Go back to Project navigator. You will see the new framework added. You can drag it into Framework group. If you have more than one target, you need not repeat the steps for other target. Just choose this framework in Project navigator, and make selection in Target Membership in File Inspector on the right Utility window of Xcode.

What's New in iOS 5 sdk

The key developer-related features introduced in iOS 5.0 (Official doc):

1. iCloud

2. Storyboard

Storyboard is not xib. "A storyboard file captures your entire user interface in one place and lets you define both the individual view controllers and the transitions between those view controllers." I think It sounds like Keynote or Powerpoint. You can design every page's content and the transition between pages.

3. Newsstand (for magazines and newspapers)

4. New Frameworks

- GLKit (Game Library Kit?). The GLKit framework (GLKit.framework) contains a set of Objective-C based utility classes that simplify the effort required to create an OpenGL ES 2.0 application.

- Core Image. A powerful set of built-in filters for manipulating video and still images, such as touching up, correcting photos, face and feature detection.

- Twitter.

- Accounts. A single sign-on model for certain user accounts. Apps can use it to access twitter account.

- Generic Security Services.

5. Automatic Reference Counting (ARC).

Actually, it is a new feature of the language and the compiler. It helps you manage the objects lifetime and memory. There are some restrictions to use ARC:

1. You don't need to (and are not allowed to) call retain/release/autorelease.

2. You don't need to (but can) implement your dealloc method.

3. You can't use NSAutoreleasePool objects. Actually, they are replaced by @autoreleasepool keyword.

3. You can't define object points in C structures.

4. You can't directly cast between object and nonobject types (for example, between id and void*).

For more information about ARC itself, see Programming With ARC.

Showing an animation when NSView loading

An UIView of one of my iOS app shows a fade-in animation. I implemented this animation in viewDidLoad. When I was porting this app onto Mac OS X, I found there is no viewDidLoad.

I tried adding the fade-in animation in awakeFromNib, but no animation appeared.

My solution: Put the animation code in a method and call it after a short delay.

[self performSelector:@selector(animationShowButton) withObject:nil afterDelay:0.2];

Implementing Fade-In Fade-Out animation in NSView on Mac OS X

It is easy to implement Fade-In animation in UIView on iOS. We just need to change alpha value in the animation.

theView.alpha = 0.0f;

[UIView beginAnimations:@"fadeIn" context:nil];

[UIView setAnimationDuration:1.0];

theView.alpha = 1.0f;

[UIView commitAnimations];

But the following code does not work in NSView on Mac Snow leopard.

[theView setAlphaValue:0.0f];

[[theView animator] setAlphaValue:0.8f];

I found addSubView and removeFromSuperview can have fade-in fade-out effects.

[[theSuperview animator] addSubview:theView];

There is a problem. We cannot change the duration time in the following code:

CABasicAnimation *animation = [CABasicAnimation animation];

animation.duration = 3.0f;

[theSuperview setAnimations:[NSDictionary dictionaryWithObjectsAndKeys:animation, @"FadeIn", nil]];

[[theSuperview animator] addSubview:theView];

Now I have the solution.

Fade-in animation:

[NSAnimationContext beginGrouping];

[[NSAnimationContext currentContext] setDuration:2.0];

[[theSuperview animator] addSubview:theView];

[NSAnimationContext endGrouping];

Fade-out animation:

[NSAnimationContext beginGrouping];

[[NSAnimationContext currentContext] setDuration:2.0];

[[theView animator] removeFromSuperview];

[NSAnimationContext endGrouping];

Change the parameter order in Objective-C formatting string

(I got this idea from cocoa programming for mac os x 3rd)

When we do localizations, the problem is the words order of a language differs to other languages. For example, this sentence "Ted wants a scooter." may be something like "A Scooter is what Ted wants" in another language.

You can localize strings this way:

NSString * theFormat = NSLocalizedString(@"WANTS", @"%@ wants a %@"); x = [NSString stringWithFormat:theFormat, @"Ted", @"Scooter"];

It works well in a language:

"WANTS" = "%@ wants a %@";

But we need to change the token order this way in another language:

"WANTS" = "A %2$@ is what %1$@ wants".