2

I am creating an instance of a view controller and then presenting it modally on another view as such:

[viewController receiveNumber1:number1 andNumber2:number2];
[viewController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentModalViewController:viewController animated:YES];

What I would like to do is set two properties within this new view controller upon initialization.

I can do this by calling a custom method like (somethings are int variables here):

[viewController methodProperty1:something1 andProperty2:something2];

However, I really need to set those properties right upon initialization because the content of the new view is dependent on those numbers.

Is there a way to pass on information to a new view while it is being initialized? Something like:

[[UIViewController alloc] initWithValue1:something1 andValue2:something2];

Also, I do not understand why

CustomViewController *view = [[CustomViewController alloc] init];
view.property = newValue; / [view setProperty:newValue];

does not work in this configuration, meaning the properties' values do not change. I can call methods within the new view and set its properties that way but not set the properties directly?

I'm sorry if these are lame questions, but I am sort of a beginner.

Thanks a bunch!

Gergely Kovacs
  • 1,045
  • 2
  • 10
  • 28
  • Firstly, "XYZ does not work in this configuration." - Precisely? Compiler error? Runtime error? Unexpected result/behavior? Two. "Something like `initWithBlah:`" - what prevents you from implementing that method in your subclass? –  Dec 30 '12 at 23:06
  • the two should be equivalent. But again, why don't you just go ahead and write that custom initialization method? (Sorry for the English, I'm Hungarian as well, but it's SO policy.) –  Dec 30 '12 at 23:13
  • The way you are setting those properties should work. You are missing something else. How are you presenting the viewController? Code or segue? – Levi Dec 30 '12 at 23:19
  • Code, I don't use IB. I added the code to my question. – Gergely Kovacs Dec 30 '12 at 23:28
  • 1
    @GergelyKovacs "I don't use IB" - you rock. Really. (You're going to be asked several times why don't you. Be prepared.) –  Dec 30 '12 at 23:48

2 Answers2

3
  1. view.property = newValue and [view setProperty:newValue] are equivalent terminology.
  2. You can implement one or multiple custom initialization methods for your view controller there is nothing that should stop from doing so. Have a look to the official doc to make sure you respect a couple of rules of how you should implement your custom initializer.

Your code snippet:

-(id)initWithValue1:(NSInteger)value1 andValue2:(NSInteger)value2
{
    if (self = [super init])
    {
        _firstValue = value1;
        _secondValue = value2;
        return self;
    }
    else return nil; // or handle the error
}
tiguero
  • 11,477
  • 5
  • 43
  • 61
2

In your CustomViewController.h, define two properties you want set and an initialization method, for example:

@property (nonatomic, assign) NSInteger firstValue;
@property (nonatomic, assign) NSInteger secondValue;

-(id)initWithFirstValue:(NSInteger)value1 andSecondValue:(NSInteger)value2;

Then, in your CustomViewController.m, implement the method you have declared earlier:

-(id)initWithFirstValue:(NSInteger)value1 andSecondValue:(NSInteger)value2
{
    self = [super init];
    if (self)
    {
        // Supposing you haven't synthesized your property and you are using
        // latest Xcode build, instance variable are automatically created
        _firstValue = value1;
        _secondValue = value2;
    }
    return self;
}

Finally, you can allocate your controller using this line of code:

CustomViewController *controller = [[CustomViewController alloc] initWithFirstValue:value1ToSet andSecondValue:value2ToSet];

Some final advice
When you implement your custom initialization method, you should properly choose which init has to be called on super.
For instance, I prefer calling self = [super initWithFrame:CGRectZero]; if my controller is a subclass of UIViewController, or self = [super initWithStyle:UITableViewStylePlain]; if it is a subclass of UITableViewController.
There are other custom init method but you can find other information reading documentation about your custom controller superclass.

matteodv
  • 3,992
  • 5
  • 39
  • 73
  • 2
    using property in constructor methods is a bad practice. Set the ivar instead. [More on the subject](http://stackoverflow.com/a/5932733/846273). – Gabriele Petronella Dec 30 '12 at 23:25
  • Thanks man, that seems to be just the thing I needed. I give it a try and pick you as the right answer once I confirmed that it works (although, by the looks of it, I don't see why wouldn't it... :). – Gergely Kovacs Dec 30 '12 at 23:26
  • @GabrielePetronella you're right even if I some times use property in init methods without having problems... However, I've edited the answer. Thanks! – matteodv Dec 30 '12 at 23:28
  • 1
    GabrielePetronella this is correct because you don't know the state of your property at the initialization stage – tiguero Dec 30 '12 at 23:30
  • It will work flawlessly in the 90% of the cases, still is a bad practice and can lead to unexpected behavior ;) – Gabriele Petronella Dec 30 '12 at 23:34
  • more on the subject: http://stackoverflow.com/questions/8056188/should-i-refer-to-self-property-in-the-init-method-with-arc – tiguero Dec 30 '12 at 23:36
  • @matteodv Another thing: you say "you should properly choose which init has to be called on super". Actually you are required to call the **designed initializer** (there can be more than one) as a standard convention. [Official doc](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/Articles/FrameworkImpl.html) – Gabriele Petronella Dec 30 '12 at 23:52
  • @GabrielePetronella yes, I wanted to say that but when I was writing I forgot that its name was designed initializer... Sorry for that! – matteodv Dec 31 '12 at 00:03