views:

274

answers:

3

I have a UIViewController with a XIB and want to add programmatically another subview.

During the initialization of the subview (initWithFrame) i want to set some attributes to values according to attributes that belong to another Object which holds data (actually a ViewControllers Child-Object, but not a view).

-(id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {

        // The following is kind of what i want
        self.myAttribute = [self.viewController.otherObject otherValue]; 
    }
    return self;

}

I want to conform to the Model-View-Controller paradigm and try to seperate my data from the subview and don't know how to access the data from within the subview.

Thanks in advance for any answers and comments how to improve the question.

EDIT: All three answers are useful for me to understand that my design is somehow the wrong way of doing the thing. As far as i understand the subview properties should be modified by the controller instead of trying the subview making to get the information. I will accept Jasons answer for his effort explaining this to me.

+1  A: 

Getting data passed around a view hierarchy can be tricky. You have a few options for global-like data:

  1. Actual global variables (hosted in one .m file and declared in a shared .h file). Not recommended, except in rare cases where you have e.g. static data that the following approaches seem silly to use with.

  2. A shared (singleton) controller object that owns the shared data. Then you could do, say, [[AppController sharedController] otherValue] and access it from anywhere in your application. This is good for what you might call overall properties or settings across your application. You wouldn't use this to pass around view-specific information, generally.

  3. If the data is view-specific, you might have it "ride along" with your view controller hierarchy, by passing it from one view controller into the next as you create and push the controllers. Then when you create the views themselves, as above, don't look for the property in the initWithFrame method, but set up a property on the view that you can set to push in the data immediately after creating the view.

quixoto
Number 2 sounds promising to me. Actually i want the view redraw itself according to the data-object which will constantly changed by the ViewController.
Frank Martin
+1  A: 

If you put this view in place using something like a UINavigationViewController you can use the parentViewController property. If not--and really, just in general--you can create properties that need to be set on your new view controller, and just set them in the parent or whoever else might create it.

Jason Coco
Unfortunately it's a UIViewController. It has an UIView to which i add another subview.
Frank Martin
Is it in a navigation view controller or something tho? Every UIViewController has the parentViewController property.
Jason Coco
It's in the application window. I edited the question, to (hopefully) clarify my situation.
Frank Martin
In that case, the best way is to make them properties on the view and have the view controller set them in viewDidLoad or whenever they should change.
Jason Coco
Also, if you are using a NIB from IB, your view's initWithFrame will never get called, so it's a bad place to do initialization. Instead, make them properties and set them in the view controller.
Jason Coco
Properties exist already, and i understand that the view controller can set them. I thought it would be more elegant if the view takes care for himself and gets the data it needs on its own, rather than pushing the data from the view controller.Thanks for your patience.
Frank Martin
Well, it is less elegant actually because then the view is tightly coupled. In theory, the view exposes whatever properties it wants/needs then, whoever is using that view can set them as necessary. If the new knows too much about its surroundings, then if those surroundings change, you need to change the view too.
Jason Coco
+1  A: 

A simple solution for the general problem of initializing a subview with attributes is to write a custom initializer in your subclass.

-(id) initWithFrame:(NSRect) aFrame andAttribute:(SomeClass *) anAttribute{
    if (self=[super initWithFrame:aFrame]) {
        self.attribute=anAttribute;
    }
    return self;
}

You would initialize the object like so:

MySubviewClass *msc=[[MySubviewClass alloc] initWithFrame:frame andAttribute:[self.viewController.otherObject otherValue]];

This will work fine if your talking about a subview controlled by the the same controller i.e. it is a subview of the controllers.view. If you loading another view, then you need to go the data-model/navigation-controller route.

TechZen