Setting background image programmatically?

Discussion in 'iPhone/iPad Programming' started by tsornin, Aug 31, 2008.

  1. macrumors newbie

    Joined:
    Jul 23, 2002
    #1
    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 :

    Code:
    - (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:
    Code:
    [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.
     
  2. macrumors member

    Joined:
    Jul 28, 2008
    #2
    That's correct. You can use the view's awakeFromNib method, or probably the controller's viewDidLoad method (and initWithNibName also sounds ok).


    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.
     
  3. thread starter macrumors newbie

    Joined:
    Jul 23, 2002
    #3
    Ah, thank you! That does seem obvious now. I've changed the setBackgroundImage method to this:
    Code:
    - (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:

    Code:
    - (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.
     
  4. macrumors member

    Joined:
    Jul 28, 2008
    #4
    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.
     
  5. macrumors 6502

    Joined:
    Nov 5, 2007
    #5
    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?
     

Share This Page