PDA

View Full Version : Setting background image programmatically?




tsornin
Aug 31, 2008, 12:52 PM
I'm trying to figure out how to set a background image programmatically. I've created a Utility application in xcode, so it has a main view and a flipside view, plus a root view controller. The main view consists of the view class (MainView) and the view controller (MainViewController). The view itself is created in Interface Builder.

Now, I've written a fairly simple method on MainView.m :

- (void)setBackgroundImage {
UIImageView *customBackground = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.jpg"]];
background = customBackground;
[customBackground release];

[self addSubview:background];
NSLog(@"Added background subview %@", background);
[self sendSubviewToBack:background];
}

However, I can't figure out how to call this. The initWithFrame method on MainView.m is never called (I guess because the view is created in Interface Builder). I've tried adding this line to the MainViewController's initWithNibName function:
[self.view setBackgroundImage];

but that just results in a crash, saying "objc[34787]: FREED(id): message superview sent to freed object=0x453910".

How can I call custom methods on MainView.m from the view controller object?

I'm guessing maybe I need to create an instance of MainView, but isn't that what self.view is supposed to be?

Thanks,
-j.



Taum
Sep 1, 2008, 04:30 AM
The initWithFrame method on MainView.m is never called (I guess because the view is created in Interface Builder).That's correct. You can use the view's awakeFromNib method, or probably the controller's viewDidLoad method (and initWithNibName also sounds ok).


that just results in a crash, saying "objc[34787]: FREED(id): message superview sent to freed object=0x453910"
You alloc an object and release it before using it. You should add it as a subview and *then* release it.
background = customBackground does not retain you object. Perhaps you meant self.background = customBackground, with background being a synthesized property flagged as retain ?
If you don't understand why your code dealloc the object when you call release on line 3, you should get more familiar with the retain-release model used through the iPhone SDK.

tsornin
Sep 1, 2008, 09:59 AM
Ah, thank you! That does seem obvious now. I've changed the setBackgroundImage method to this:

- (void)setBackgroundImage {
NSLog(@"setting bg image");
UIImageView *customBackground = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.jpg"]];
self.background = customBackground;
[customBackground release];

[self addSubview:background];
NSLog(@"Added background subview %@", background);
[self sendSubviewToBack:background];
}

Then added the call to it in the MainViewController's initWithNibName method:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Custom initialization
[(MainView *)self.view setBackgroundImage];
}
NSLog(@"initWithNibName - view=%@", self.view);
return self;
}

Also noticed that while [self.view setBackgroundImage]; works, it raises a compiler warning in Xcode, "Messages without a matching method signature will be assumed to return 'id' and accept '...' as arguments." I ended up changing it to [(MainView *)self.view setBackgroundImage]. Not sure if that's really the right way to do it, but it does work.

Taum
Sep 1, 2008, 12:23 PM
It is the right way to do it : view is a UIView for any UIViewController, but in your case you can guarrantee that it will always be a MainView. You can safely cast it into a MainView to call methods specific to MainView on it.

I'm a Mac
Feb 17, 2009, 12:08 AM
Now how would you change how the image displays without IB? For example, in interface builder, I would set the image to display as "bottom". How would I do this programmatically?