Site Perso de

Thomas JANNAUD

Des actualités personnelles sous un style impersonnel, et inversement.



Troubleshooting with iOS. UI tips
12 Février 2012

Back in the iPhone Apps with JapanEasy, check it out ! I would like to help the community back too by writing down here a few things that solved my headaches while making this app. As always I would like to say when you play with the "developer enemily" Cocoa framework.

width/height bug after rotation

If you reimplement - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation in your UIViewController, watch out if you use the .width and .height properties ! The iPhone and iPad have different behaviours on this. When you go from portrait to landscape, width and height are swapped on the iPhone but not on iPad. Example: if your view was 320*480 on the iPhone, it will be 480*320 in landscape. But if it was 748*1024 on the iPad, it will still be 748*1024 in landscape. Same for all objects on your view. So .height and .width should be handled with care. I filed a bug to Apple and I hope they will take care of it...

NavigationController imbricated in a TabViewController

If you have a TabViewController and that you want a certain tab to be included in a NavigationController (a good example is the "contact" tab in the phone app, when you click on a contact and you see the detailed view) : in AppDelegate.m, do :

view_controller_1 = [[FirstViewController alloc] initWithNibName:@"View1_iPhone" bundle:nil];
...
main_view_controller = [[FirstViewController alloc] initWithNibName:@"View1_iPhone" bundle:nil];
UINavigationController* view_controller_with_navigation = [[UINavigationController alloc] initWithRootViewController:main_view_controller];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:view_controller_1, view_controller_2, view_controller_with_navigation, view_controller_4, nil];

Doing it this way, you will have 4 tabs, and the 3rd one (view_controller_with_navigation) will be able to load a detailed view this way :

MyDetailedViewController* detailed_view_controller = [[MyDetailedViewController alloc] initWithNibName:@"DetailedView_iPhone" bundle:[NSBundle mainBundle]];
detailed_view_controller.title = @"Details";
self.navigationController.navigationBarHidden = NO; // So the navigation controller is not nil
[self.navigationController pushViewController: detailed_view_controller animated:YES];
self.navigationItem.title = @"Not Detailed";

Tap on UITextView

If you need a UITextView ta reacts to a tap, declare this in the .h of the controller :

@interface UITextViewTapIntercept : UITextView
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
@end

In the .m

@implementation UITextViewTapIntercept

-(void)touchesEnded:(NSSet *) touches withEvent:(UIEvent *) event {
if ([touches count] == 1) {
for (UITouch *touch in touches) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"NOTIFICATION_TAP_TEXT" object:self];
}
}
[self.nextResponder touchesEnded: touches withEvent:event];
[super touchesEnded:touches withEvent:event];
}

@end

Now you just need to listen to the @"NOTIFICATION_TAP_TEXT" notification, and do as if you received an IBAction. I don't know why Apple didn't do it for us. You will also need to : 1) In the .nib replace UITextView by UITextViewTapIntercept, and 2) Check "User Interaction Enabled", a box not far from the text view's "background color" property.

To listen to the notification :

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
...
[[NSNotificationCenter defaultCenter] addObserverForName:@"NOTIFICATION_TAP_TEXT" object:nil queue:nil usingBlock:^(NSNotification* notification) {
[self doAction:notification.object];
}];

.xib problems

Among other things, delete MainWindow.nib : this file is useless. Also, if your application crashes right at the beginning before doing anything, you probably have a problem in your nibs. For instance you had a UILabel* my_label, then you rename it with UILabel* my_awesome_label. IB will probably fail to recognize the change and you will have an object with the old "my_label" outlet that will point to nothing, so watch out for things like that. Also, if changing things on objects on the code have no UI effect, then your objects are probably "nil". Check that the IBOutlet links are good. Twice.

For all these points it took me usually something like 3 or 4 hours of research on the internet to make them work. So please Apple, have docs of 5 lines instead of 15 pages, and with code rather than text. Thank you...

À lire aussi :
Laissez un commentaire !

Pas besoin de vous connecter, commencez à taper votre nom et une case "invité" apparaîtra.