views:

490

answers:

5

Why can't i just set self.mySubView = anoterhView; like one can set self.view = anotherView; ?

## .h
@interface TestController : UIViewController {
    IBOutlet UIView *mySubView;
}

@property (nonatomic, retain) IBOutlet UIView *mySubView;

##.m

@implements TestController

@synthesize mySubView;

- (void)viewDidLoad { 

    AnotherController *anotherController = [[AnotherController alloc] initWithNibName:nil bundle:nil];
    anotherView = anotherController.view;

    // if i do
    self.view = anotherView;
    // result: replaces whole view with anotherView

    // if i instead do
    self.mySubView = anotherView;
    // result: no change at all

    // or if i instead do:
    [self.mySubView addSubview:anotherView];
    // result: mySubView is now displaying anotherView

}

NOTE: I'm using interfacebuilder. I'm sure everything is hooked up allright because self.view, and self.mySubView addSubview: is working allright..

+2  A: 

To make it automatically appear on your self.view you need to overwrite your setter method, e.g.:

- (void)setMySubView:(UIView *)view {
    [mySubView removeFromSuperview];  // removing previous view from self.view
    [mySubView autorelease];
    mySubView = [view retain];
    [self.view addSubview: mySubView]; // adding new view to self.view
}
beefon
Smart, but not what i had in mind. I want to set a specific subview which self.view is holding.
Fossli
Do you mean that you have drop some View on your UIViewController's view, and you want to replace that view (from IB) with different view from code? As I can understand, your need to do: 1. save current view.frame: CGRect mySubViewFrame = [mySubView frame];2. remove and put new subview - I have wrote how to do it3. set new frame for new view: [mySubView setFrame:mySubViewFrame];
beefon
lots of juggling, but acceptable. i'm not clicking "accept" as i hope for an explanation on why or easier solution, but gonna stick with yours for now. thanks
Fossli
Please have a look at my try http://stackoverflow.com/questions/2199737/setting-a-subview-in-uiviewcontroller/#answer-2208087
Fossli
A: 

Your instance variable needs to be a property in order to use the dot. syntax, use:

@Property (nonatomic, retain) IBOutlet UIView* subview;

in the header, and use:

@synthesize subview;

in the main file.

In order to set a UIView using the dot. syntax you need to make it a property. This also allows you to set the subview's properties outside the class.

Jaba
i can't really see the difference between what you wrote and what i wrote.. if difference, could you explain?
Fossli
Well I was elaborating with my own twist. If he accepts yours then I will delete my answer
Jaba
A: 

As a response to what @beefon said. This works kind of as expected, but background-color is transparent. It doesen't respond either... buttons do not get pressed etc..

- (void)setCurrentView:(UIView *)newView {
    /*      1. save current view.frame: CGRect mySubViewFrame = [mySubView frame]; 
            2. remove and put new subview - I have wrote how to do it 
            3. set new frame for new view: [mySubView setFrame:mySubViewFrame];      */ 
    CGRect currentViewFrame = [currentView frame];
    [currentView removeFromSuperview];
    [currentView autorelease];
    currentView = [newView retain];
    [self.view addSubview:currentView];
    [currentView setFrame:currentViewFrame]; 
}
Fossli
A: 

This works perfectly for me.

- (void)switchMySubview:(UIView*)newView {
    for (UIView *subView in self.mySubView.subviews) {
        NSLog(@"removes subviews");
        [subView removeFromSuperview];
    }
    newView.frame = CGRectMake(0, 0, mySubView.frame.size.width, mySubView.frame.size.height);
    [mySubView addSubview:newView];
}
Fossli
Technically you are not replacing your subview here just adding a subview to your subview. And the -removeFromSuperview loop is pointless if you have no subviews prior to the assignment.
Deepak
allright. i'm building a viewswitcher much like a tab-thing. So the idea here was to let the subviews hold subsubviews and add and remove them from that.. it does what i want, but you're right. it's technically not setting the subview..
Fossli
+1  A: 

mySubview is a property which is a reference to an UIView object. So when you assign an UIView object to it, you are merely changing what mySubview is referring to and no more as in this case,

self.mySubview = anotherView;

The original UIView object that mySubview was referring to is still referred to within view's subviews property. Nothing changes.

But when you add anotherView as a subview of mySubview, anotherView belongs to the view hierarchy and is displayed on screen. So this works.

view (parent of) mySubview (parent of) anotherView

However when you assign anotherView directly to the view, You not only change the UIView object view was referring to but it also adds itself to the parentView. This is handled by UIViewController.

self.view = anotherView;



Your setCurrentView should be more or so like this,

- (void) replaceSubview:(UIView *)newView {
  CGRect frame = mySubview.frame;

  [mySubview removeFromSuperview];
  self.mySubview = newView;

  [self.view addSubview:newView];
  newView.frame = frame;
}



Deepak
i'l give it a spin on monday. thanks a lot! looks like a proper solution.
Fossli
And what the difference between this solution and mine?
beefon