2

After a long while I've finally started working with Objective-C again, on my only complete app so far. The goal is to eventually refactor for ARC and possibly storyboards, but for the time being I'm polishing the iOS 4.x target. I am quite rusty, so bar with me if this is a stupid question.

I have a button in my main view that triggers the showAction method. The method is as follows:

- (void)showAbout
{
    AboutViewController *aboutView = [[[AboutViewController alloc] init] autorelease];
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
    {
        aboutView.modalPresentationStyle = UIModalPresentationFormSheet;
    }
    else
    {
        aboutView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    }
    [self presentModalViewController:aboutView animated:YES];
}

The AboutViewController class has this .h:

@interface AboutViewController : UIViewController <UIActionSheetDelegate, MFMailComposeViewControllerDelegate> {
}

- (IBAction)dismiss:(UIButton *)sender;
- (IBAction)feedback:(UIButton *)sender;

@property (retain) IBOutlet UIButton *dismissButton;
@property (retain) IBOutlet UIButton *feedbackButton;
@property (retain) IBOutlet UIImageView *background;
@property (retain) IBOutlet UITextView *textView;

@end

and everything has been connected properly in the .xib file (the same one for iPhone and iPad). The actions are triggered as expected, and the outlets are accessible, but only on iPhone. When running on iPad, only textView is properly initialized, and all the rest points to nil.

In the .m I have tried this:

@implementation AboutViewController

@synthesize dismissButton = _dismissButton;
@synthesize feedbackButton = _feedbackButton;
@synthesize background = _background;
@synthesize textView = _textView;

// ...

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    NSLog(@"obj self.dismiss: %@", self.dismissButton);
    NSLog(@"frame dismiss: %@", NSStringFromCGRect(self.dismissButton.frame));
}

On iPhone I get this:

2012-02-08 22:51:00.341 myapp[17290:207] obj self.dismiss: <UIButton: 0x70281d0; frame = (180 410; 120 30); opaque = NO; autoresize = LM+W+RM+TM; layer = <CALayer: 0x7028260>>
2012-02-08 22:51:00.342 myapp[17290:207] frame dismiss: {{180, 410}, {120, 30}}

On iPad, instead, I get this:

2012-02-08 22:51:40.428 myapp[17320:207] obj self.dismiss: (null)
2012-02-08 22:51:40.428 myapp[17320:207] frame dismiss: {{0, 0}, {0, 0}}

There is nothing else that happens depending on the UI Idiom, and I'm really confused about this. It's as if on the iPad the outlets for anything other than textView are not set, even though they are correctly linked up in the .xib file. In viewWillAppear, self.textView is working as expected also on iPad. I also tried doing this in viewDidLoad, which should be called before viewWillAppear if I'm not mistaken, and even in the dismiss: method, but they are just never available.

The reason I need to access the buttons' frames is that the about view is relatively complex and fails to reposition its subviews automatically. The only thing I need to do is make the buttons wider on the larger modal view on iPad.

Any hints would be greatly appreciated!

Thanks in advance.

Jollino
  • 190
  • 2
  • 9
  • Are you using a different .xib for iPad? Or is it possible that you think you aren't, but the way you set up the hybrid app project means it created a separate .xib for iPad without you realising? – Nick Lockwood Feb 08 '12 at 22:59
  • No, I only made a different iPad .xib for another MainWindow class, and all the others (including this one) share the same .xib. This project started out as iPhone only, so I manually created that one and differentiated the workflow in the App Delegate to set the root view controller as needed (it's a split view controller on iPad, a navigation controller on iPhone.) – Jollino Feb 09 '12 at 00:09
  • Have you tried doing a clean build from the product menu? It's just that the same nib binding differently depending on whether it's iPad or iPhone seems really unlikely, so I suspect the problem lies elsewhere. – Nick Lockwood Feb 09 '12 at 00:31
  • Have you tried putting your outlet logging in viewDidLoad instead? Maybe the event order is different on iPad, and somehow the viewWillAppear is firing before the view has loaded. – Nick Lockwood Feb 09 '12 at 00:32
  • It was originally in viewDidLoad and I moved to viewWillAppear (or even viewDidAppear) to make sure they were connected; I even tried logging from a target action, but it's as if they're never hooked up. Interestingly, when accessing sender from the target action, the object exists but accessing its frame property yields an EXC_BAD_ACCESS (and gdb shows that there is indeed no frame property). I did try cleaning and rebuilding and reconnecting the First Responder outlets to the views in the xib, but to no avail. I'm quite baffled... – Jollino Feb 09 '12 at 08:09
  • Try *not* autoreleasing the AboutViewController before presenting it (I know that will leak - it's just an experiment). – Nick Lockwood Feb 09 '12 at 08:45
  • I had already tried it and just did so again to make sure: same thing. I'm just surprised that the textview is the only thing that works perfectly, but everything's initialized the same way. (I have even tried changing the order of `@property` and `@synthesize`, and deleting the referencing outlet in the .xib and re-making it.) – Jollino Feb 09 '12 at 09:38
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/7499/discussion-between-jollino-and-nick-lockwood) – Jollino Feb 09 '12 at 15:05
  • @Jollino I'm having the exact same issue. Were you able to resolve the problem? – Aaron Feb 20 '13 at 22:32

1 Answers1

2

Did you ever have a separate .xibs for iPad and iPhone? If so you might have the same issue I had. That is until @AliSoftware dropped some knowledge on me:

UIView in nib is nil on iPad, and not nil on iPhone

Essentially you need to:

  1. Delete the Build Products Directory
  2. Delete your app from all your simulators
  3. Build and Run

I believe the problem is that a ghost .xib for iPad was hanging around causing issues. Truly wiping the apps clean did the trick. Good luck!

Community
  • 1
  • 1
Aaron
  • 7,055
  • 2
  • 38
  • 53