The difference between theory and practice is a lot greater in practice than it is in theory.
Brian Bechtel
A great potent potable from the 2010 WWDC networking session.
2 ways to rotate
I spent too long writing a few lines of code that I no longer need. I feel that I need to do something with them so here they are.
Below are 2 methods for rotating a view while keep the rest of the UI from rotating (or at least appearing rotated). Since iOS 4, UINavigationController and friends are more easygoing about handling this automatically. Both of these methods really only apply to the situation where you are managing a custom view hierarchy and not relying on UINavigationController and UITabBarController like a good iPhone citizen. (You will notice in both methods I have mysterious object called “customContainerController” which is managing my view hierarchy, if you are so inclined you can try it out here)
Method 1: Brute Force
If you need to allow the rotation of a single view but don’t actually want to rotate the entire interface of the app, the following will allow you to do that. It isn’t really complex, but the devil is in the details. You need to bump and nudge a lot of things and you can spend a lot of time building and tweaking.
Interesting things:
You must set the bounds after applying the transform.
The bounds is manipulated as if the origin is in the upper left hand corner (UIInterfaceOrientationPortrait).
You need to adjust the bounds +20 / -20 to account for moving the status bar around.
Changing the orientation of the status bar does not change the interface orientation of the device.
You need to rotate the status bar back when dismissing the view (do that with no animation).
If you need the keyboard this won’t work because the keyboard respects the current interface orientation.
- (IBAction)close:(id)sender {
UIApplication *application = [UIApplication sharedApplication];
[application setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
[self.customContainerController loadThatOtherViewController];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
//manually rotate
//bounds changes are made as if the phone never rotated
//we are making these bounds tweaks to move aorund the status bar
CGRect bounds = [self.customContainerController.view bounds];
CGFloat r = 0;
switch ( interfaceOrientation ) {
case UIInterfaceOrientationPortrait:
r = 0;
break;
case UIInterfaceOrientationLandscapeRight:
r = M_PI/2;
bounds.origin.y-=20;
bounds.size.height+=20;
bounds.size.width-=20;
break;
case UIInterfaceOrientationPortraitUpsideDown:
r = M_PI;
bounds.origin.y-=20;
break;
case UIInterfaceOrientationLandscapeLeft:
r = 3*M_PI/2;
bounds.origin.x+=20;
bounds.origin.y-=20;
bounds.size.height+=20;
bounds.size.width-=20;
break;
}
UIApplication *application = [UIApplication sharedApplication];
[UIView animateWithDuration:[application statusBarOrientationAnimationDuration]
animations:^(void) {
CGAffineTransform t;
t = CGAffineTransformIdentity;
t = CGAffineTransformRotate(t, r);
self.view.transform = t;
self.view.frame = bounds;
}];
[application setStatusBarOrientation:interfaceOrientation animated:YES];
return YES;
}
Method 2: Tricking UIKit
This time we need to make UIKit ask us about rotation at an opportune time. To do this we can create and destroy a UIVIewController, causing all of the View Controller machinery to kick in. I picked this idea up from: SO
Interesting things:
Unlike the 1st method, you get to hook into the normal view controller autoresizing.
Presenting/dismissing a blank VC without animation is not visible to the user.
- (IBAction)close:(id)sender {
self.isClosingDown = YES;
//doing this to force an autorotation
UIViewController *c = [[UIViewController alloc]init];
[self presentModalViewController:c animated:NO];
[self dismissModalViewControllerAnimated:NO];
[c release];
[self.customContainerController loadThatOtherViewController];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(self.isClosingDown)
return (UIInterfaceOrientationPortrait == interfaceOrientation);
return YES;
}
Developer Forums: How to revert build settings made on target level?
Extremely undiscoverable way to delete target and project level build settings. (i.e. reverting to iOS / MacOS defaults)
Hint: Deleting the text is not enough
P. S. Another subtle gotcha: Although you can edit project level build settings while viewing the target build settings, you cannot delete them. First select the project, then delete.
Using Open Source Static Libraries in Xcode 4 | Carbon Five Community
Best breakdown yet of using static libraries and build settings in Xcode. Although it seems that Xcode Workspaces are still very much broken…
Github Trends
Now, I can increase the number of my watched repos exponentially.
Pilky.me - Xcode 4: the super mega awesome review
Big Xcode 4 review
Technical Note TN2239: iOS Debugging Magic
Nice tip on using [[self view] recursiveDescription] to print the view hierarchy.
iphone - UIButton in a UITableView header ignores most touches - Stack Overflow
Weird bug that has given me problems on several occasions
Source: faultline.org