1

I am just working on iOS app and I want to make it universal for both iPhones and iPads. This is done and works without any problems:

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
    self.viewController_iPhone = [[ViewController_iPhone alloc] initWithNibName:@"ViewController_iPhone" bundle:nil];
} else {
    self.viewController_iPad = [[ViewController_iPad alloc] initWithNibName:@"ViewController_iPad" bundle:nil];
}

if (self.viewController_iPhone == nil)
    self.window.rootViewController = self.viewController_iPad;
else
    self.window.rootViewController = self.viewController_iPhone; 

There is a view for each controller (ViewController_iPad.xib, ViewController_iPhone.xib). It doesn't matter which view is loaded in my problem. In a view there is a subview added (UIScrolView). And in this ScrollView there are two views from xib:

NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:@"SubView1" owner:self options:nil];
UIView *view = [nibContents objectAtIndex:0];
view.frame = CGRectMake(2, 0, scrollView.frame.size.width - 2, scrollView.frame.size.height);
[scrollView addSubview:view];


nibContents = [[NSBundle mainBundle] loadNibNamed:@"SubView2" owner:self options:nil];
view = [nibContents objectAtIndex:0];
view.frame = CGRectMake(scrollView.frame.size.width + 2 , 0, scrollView.frame.size.width - 4, scrollView.frame.size.height);
[scrollView addSubview:view];

(This code is in iPad/iPhone controller). Still everything is OK. But I don't know how to set owners (in IB) of these subviews that are shown in ScrollView. These subviews are in ScrollView which is in a main view so I want to set owners of these subviews as iPad/iPhone controller. But as a owner can be only one class. Can you tell me how to set owners if I have two main controllers and I don't know which one will be loaded in runtime. Thank you.

EDIT: I have another question: I have ViewController_iPhone. It has a View property and this property is assigned to the "root" view in the main view in ViewController_iPhone (.xib). Can I assign this view property also to subview view? Because I got EXC_BAD_ACCESS error if I assign view property of ViewController_iPhone to a "root" view of subview in IB.

DanielH
  • 953
  • 10
  • 30
  • If you are loading the nib using loadNibNamed like you did already then there is no significance for the files owner – Anil Varghese May 22 '13 at 08:01
  • So it doesn't matter which controller I set as files owner in IB because using loadNibNamed method with owner:self parameter will "reset" this owner to controller where this code is situated? Won't be there a problem because for example owner is set to iPhone controller and iPad controller will be loading it? – DanielH May 22 '13 at 08:14
  • Ya thats what i said... you are loading custom view from the nib, you are accessing only the view object. So the files owner is not in the play. Remember do not connect the outlets to the files owner.. connect it to your view object – Anil Varghese May 22 '13 at 09:11
  • OK, thank you. But I got another problem. Please note EDIT part in a question above. – DanielH May 22 '13 at 09:17
  • i didnt get you what do you mean by root view here? – Anil Varghese May 22 '13 at 09:35
  • I mean view itsefl. If you put some subviews to the view, you create a view hierarchy. By "root" view I mean root view in this hierarchy so View itself. – DanielH May 22 '13 at 09:39
  • As far i know it is not possible. you can assign the view property only to a top level view. – Anil Varghese May 22 '13 at 09:47
  • That explains the error. But I need to assign subview to some view property of some controller right? – DanielH May 22 '13 at 09:51
  • I think in your case view is appearing fine. only you need to handle some properties or some actions in that subView right? – Anil Varghese May 22 '13 at 09:58
  • yes.I just finished a layout (appearing is OK) but now I want to connect it with a code (actions, outlets,..). – DanielH May 22 '13 at 10:01
  • wait i wil post an answer.. can you post an image of your subView xib? – Anil Varghese May 22 '13 at 10:03
  • can you post an image of your subView xib? – Anil Varghese May 22 '13 at 10:13

1 Answers1

2

Looks like you need to use a class cluster. This will abstract the iPhone/iPad instantiation, so you don't explicitly need to instantiate one of the two. You can read a bit about class clustering in the Apple documentation:

http://developer.apple.com/library/ios/#documentation/general/Conceptual/DevPedia-CocoaCore/ClassCluster.html

It boils down to creating a master view controller which will handle the allocation of iPhone or iPad subclasses based on the current device.

You should override the ViewController alloc class method:

   + (id)alloc {
       NSString *classString = NSStringFromClass([self class]);

       NSString *append = nil;

       if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
           append = @"_iPhone";
       } else {
           append = @"_iPad";
       }

       NSString *subClassString = [classString stringByAppendingString:append];

       id subClass =  NSClassFromString(subClassString);


       id object;

       if (subClass && ![self isKindOfClass:[subClass class]]) {
           object = [subClass alloc];
       } else {
           object = [super alloc];
       }

       return object;
   }

This way you can just allocate the ViewController class and at runtime the correct class definition will be used to instantiate your view controller. This will allow you to use the ViewController class as the owner in IB provided that you create an abstraction of iPhone and iPad interfaces and define it in their super class.

jansenmaarten
  • 1,953
  • 1
  • 11
  • 6