Activity 2-unit 2-update 2024. English translation
My Favourite 10 Things about Xcode/ObjectiveC
1. My Favourite Ten Xcode Things
Tuesday, October 11, 11
Some of my favourite Xcode and Objective-C type things.
2. (Or: Please tell me a better way of
doing these things)
Tuesday, October 11, 11
Three phases of iPhone development:
1. Argh! Square brackets!
2. Ok, how do I do this?
3. Ok, what’s the BEST way to do this?
The common theme is that each stage is full of puzzles, and puzzles are attractive to certain
types of brains. You think, you solve, you get a little rush. Addictive!
3. 1. Xcode Keyboard Shortcuts
Flip between .h and .m
Control + Command + Arrow up
Switch between open tabs
Shift + Command + [ or ]
Find anywhere in project
Shift + Command + F
Tuesday, October 11, 11
I spend many hours using Xcode every day. The transition to Xcode 4 wasn’t too bad,
although it took a while to get used to the way it splits views. I’m happy enough now though.
At least it’s not Eclipse, and when I go back to Visual Studio it irritates me that I need to
double-click on things a lot.
4. 1b. Xcode Keyboard Shortcuts
Toggle Debug Console
Shift + Command + Y
Open a file
Shift + Command + O
Tuesday, October 11, 11
Open a file is fantastic. Use it.
5. 2. Drag from the NIB editor into .h files
Hold down Control and drag a control into
your .h file, to create actions and properties
(and the associated methods in .m).
Tuesday, October 11, 11
I love this.
6. 3. Useful NSString initialization
-(NSString *)getAxis
{
! return [NSString stringWithFormat:
@"X:%0.2f Y:%0.2f Z:%0.2f",
_accelerometer[0],
_accelerometer[1],
_accelerometer[2]];
}
Tuesday, October 11, 11
Very nice - and because there is no ALLOC, it’s an autorelease object.
Just don’t put a BOOL in there.
8. 4. Useful NSString comparisons
Don’t check to see if a string is empty like
this:
if (myString == nil) { NSLog(@"empty!"); }
Use this:
if ([myString isEqualToString:@""]) { NSLog(@"empty!"); }
Or this:
if ([myString length] == 0) { NSLog(@"empty!"); }
Tuesday, October 11, 11
But if it’s just whitespace, that might not work..
10. 5. Testing to see if a file exists
There is no file system. Except there is.
if ([[NSFileManager defaultManager]
fileExistsAtPath:[[NSBundle mainBundle]
pathForResource:@"picture" ofType:@"jpg"]])
return YES;
Tuesday, October 11, 11
Also, are you using large image files? Tempted to stick with PNG? Try JPG instead.
Same quality in photograph images, but can be 1/10th of the size.
11. 6. Time delay before method call
-(void) myMethod
{
}
[self performSelector:@selector(myMethod)
withObject: nil
afterDelay: 1.0];
[NSObject
cancelPreviousPerformRequestsWithTarget :self
selector :@selector(myMethod)
object :nil];
Tuesday, October 11, 11
Multithreading for dummies - a great way to get animation working when the main thread
would otherwise be blocked. WARNING! Remember to cancel it if you don’t use it before the
reference goes away!
12. 7. Delegate callback to parent AppDelegate
// In AppDelegate
-(void)callMe
{
}
// In some other class
- (void)viewDidLoad
{
[super viewDidLoad];
[(AppDelegate*)
[[UIApplication sharedApplication] delegate] callMe];
}
Tuesday, October 11, 11
Just need to add callMe to .h in AppDelegate, and #import that into the other class.
However, think about why you are doing this: it’s very likely that a Singleton will be a better
idea.
13. 8. Using delegates to perform actions when
modal dialog closed.
// In the Modal Dialog UIViewController Class, .h
file
@interface CityPickerViewController : UIViewController
<UIPickerViewDelegate>
{
!
! id delegate;
!
}
- (id)delegate;
- (void)setDelegate:(id)newDelegate;
@end
Tuesday, October 11, 11
So you want to trigger something when a modal dialog is closed. Use this to allow the Modal
dialog UIViewController class to call a method back in the class that called it.
14. 8b. Using delegates to perform actions
when modal dialog closed.
// In the Modal Dialog UIViewController Class, .m file
- (id)delegate {
return delegate;
}
- (void)setDelegate:(id)newDelegate {
delegate = newDelegate;
}
-(void) updateCity: (id)sender
{
! // replaced by delegated call
!
}
-(void)callWhenDialogClosing
{
! [[self delegate] updateCity:self];!
}
Tuesday, October 11, 11
So you want to trigger something when a modal dialog is closed. Use this to allow the Modal
dialog UIViewController class to call a method back in the class that called it.
15. 8b. Using delegates to perform actions
when modal dialog closed.
// In the class that is calling the modal dialog
-(void) updateCity: (id)sender
{
! [self drawLocation];!
[myPickerView dismissModalViewControllerAnimated:YES];
}
-(IBAction) clickNearestCity: (id)sender
{
myPickerView = [[CityPickerViewController alloc]
initWithNibName:@"CityPickerViewController" bundle:nil];
! myPickerView.delegate = self;
....
Tuesday, October 11, 11
You can’t keep the pointer to the view nice and local now, as you’ll need to close it yourself in
the delegate. Yes, it smells a bit. Suggestions welcome.
16. 9. Two-part animation block
[UIView beginAnimations:@"clickBounce" context:tempButton];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.2]; !
[UIView setAnimationDidStopSelector:@selector(part2:finished:context:)];
[myButton setTransform:CGAffineTransformMakeScale(.9,.9)];
[UIView commitAnimations];
Tuesday, October 11, 11
Blocks have a terribly ugly syntax, but if you can get over it, they are useful. And increasing
in importance. If you wanted an animation to have multiple parts, you needed to use the
DidStopSelector, and it was a pain.
17. 9b. Two-part animation block
[UIView animateWithDuration:1.0
animations:^
{
myButton.alpha = 1.0;
myButton.transform = CGAffineTransformMakeScale(1.5, 1.5);
}
completion:^(BOOL completed)
{
myButton.alpha = 0.8;
myButton.transform = CGAffineTransformMakeScale(1, 1);
}
];
Tuesday, October 11, 11
Much neater, no extra methods, easier to pass values between different components of the
animation etc etc
18. 10. UICollections, Tags and iOS 5
Declare a Collection, and then link all your
buttons to it..
IBOutletCollection(UIButton) NSArray *menuButtonsCollection;
Tuesday, October 11, 11
Piece of cake in NIB editor.
19. 10b. UICollections, Tags and iOS 5
Now you can iterate over them all..
for (UIButton *button in menuButtonsCollection)
{
[button setImage:[UIImage imageNamed:@"pic.png"]
forState:UIControlStateNormal];
}
Tuesday, October 11, 11
Handy to programmatically fade out all buttons for example.
Remember you can also set TAGS in the NIB editor, and then act on those in the loop.
You don’t need to only use one type of object, use (id) for any control.
20. 10b. UICollections, Tags and iOS 5
If you need to change them all at once..
[[UISwitch appearance] setOnTintColor: [UIColor redColor]];
Tuesday, October 11, 11
Note: need to re-open the view to see the changes.