Matt
Matt

Reputation: 1167

Why setNeedsDisplay required when initWithNibName used

I have custom UIViewController class called MSPageViewController with and associated nib file. I have an IBOutlet which is a UIImageView called pageImage.

Now, I want to use this view controller in another UIViewController which will display a series of my custom MSPageViewController in a UIPageViewController. So, I use the following code:

// alloc and init my custom view controller

MSPageViewController *page1 = [[MSPageViewController alloc] initWithNibName:@"MSPageViewController" bundle:nil];

// I must call this or, the image that I set below will always be null // why? I guess it's because the view hasn't been drawn yet because it hasn't been displayed, so I need to force the redraw - but this is my question. Is this is the right approach?

[page1.view setNeedsDisplay];

// set the image

page1.pageImage.image = [UIImage imageNamed:@"tutorialPage1.png"];

// make my array of view controllers, it expects an array because could be double-sided

NSArray *viewController = [NSArray page1];

// pass the array that contains my custom view controller

[self.pageController setViewControllers:viewController direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];

So am I doing this right? I have to force the redraw so that my outlets exist when I try to assign to them?

Upvotes: 0

Views: 114

Answers (3)

TomSwift
TomSwift

Reputation: 39502

As others have noted, pageImage (a UIImageView?) is likely not loaded from the nib yet when you're accessing it.

If you have a custom getter for pageImage, you could do the following:

- (UIImageView*) pageImage
{
    [self view];
    return _pageImage; // assuming the property backing ivar is synthesized as _pageImage.
}

But my personal preference would be to not expose the imageview itself and just expose a property for image. Then you can set the image to the viewcontroller regardless of it's loaded state, and internally set it to the imageView once the view loads:

- (void) setImage: (UIImage*) image
{
    _image = image;

    if ( self.isViewLoaded )
    {
         self.pageImage.image = image;
    }
}

- (void) viewDidLoad
{
    [super viewDidLoad];

    self.pageImage.image = self.image;
}

Upvotes: 2

DarkDust
DarkDust

Reputation: 92384

It's not the setNeedsDisplay part that you "need", it's the self.view part. By accessing the view property you are forcing the view controller to actually load the NIB. I guess that as a side effect of this, the pageImage property is populated as well (and was nil before you called self.view).

So, just calling self.view; instead of [self.view setNeedsDisplay]; should be enough.

Upvotes: 4

David Elliman
David Elliman

Reputation: 1399

If you moved some code to the viewDidLoad method you would be guaranteed that the view had been drawn.

Upvotes: 0

Related Questions