I have a custom UIView. So myView class extend UIView. In initWithFrame:(CGRect)frame method I set UIImageView for my UIView as a background image.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.bgImage = [[[UIImageView alloc] initWithFrame:
CGRectMake(0, 0, frame.size.width , frame.size.height)] autorelease];
int stretchableCap = 20;
UIImage *bg = [UIImage imageNamed:#"myImage.png"];
UIImage *stretchIcon = [bg
stretchableImageWithLeftCapWidth:stretchableCap topCapHeight:0];
[self.bgImage setImage:stretchIcon];
}
return self;
}
So when I create my view everything is fine.
MyCustomView *customView = [[MyCustomView alloc] initWithFrame:CGRectMake(10, 10, 100, 50)];
But if I want to change my view size to bigger or smaller:
customView.frame = CGRectMake(10, 10, 50, 50)];
then I have the problem with my background image. Because it's size didn't changed. What to do ? Ho to change bg image size together with view frame ?
Try setting the autoresizing mask of the UIImageView, it will resize according to the size changes of the super view.
My suggestion is use update function to update your custom view when you want to change the frame:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self UpdateViewWithFrame:frame];
}
return self;
}
- (void)UpdateViewWithFrame:(CGRect)frame
{
self.frame = frame;//set frame
if(!self.bgImage)
{
//initialize your imageview
self.bgImage = [[[UIImageView alloc] initWithFrame:
CGRectMake(0, 0, frame.size.width , frame.size.height)] autorelease];
}
int stretchableCap = 20;
UIImage *bg = [UIImage imageNamed:#"myImage.png"];
UIImage *stretchIcon = [bg
stretchableImageWithLeftCapWidth:stretchableCap topCapHeight:0];
[self.bgImage setImage:stretchIcon];
}
When you want change frame , just call this function.Have a try man.
Set the required Autoresizingmask property attributes for the imageview correctly as it must be adjusted along with the view frames.
So the suggestions was right. I should add autoresizing mask. Now my initWithFrame looks like that:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.bgImage = [[[UIImageView alloc] initWithFrame:
CGRectMake(0, 0, frame.size.width , frame.size.height)] autorelease];
int stretchableCap = 20;
UIImage *bg = [UIImage imageNamed:#"myImage.png"];
UIImage *stretchIcon = [bg
stretchableImageWithLeftCapWidth:stretchableCap topCapHeight:0];
[self.bgImage setImage:stretchIcon];
self.bgImage.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.autoresizesSubviews = YES;
}
return self;
}
Related
I have a background coming from Default-568h#2x.png. I want to display a shrunk PNG over part of the background, but calling:
[[CJSHCardView alloc] initWithScale:.1];
turns the display white. This does not happen if I comment this line, but in the function call, even if I make it return immediately it turns the display white after half a second:
- (id)initWithScale:(float)scale
{
UIImage *img = [UIImage imageNamed:#"note.png"];
self = [super initWithImage:img];
if (self != nil)
{
self.frame = CGRectMake(0, 0, img.size.width * scale, img.size.height * scale);
UIImageView *myImage = [[UIImageView alloc] initWithFrame:self.frame];
myImage.opaque = NO;
[self addSubview:myImage];
}
return self;
}
Moving/copying the return statement to be the first in initWithScale makes no discernible change from how it is with the return statement properly at the end: a brief view of the background, followed by a white screen. note.png is in "Supporting Files".
Do you see any gotchas where I can change things so that a shrunken version of the note (maintaining aspect ratio) displays? The note.jpg image does not have a pixel of white.
Thanks,
--EDIT--
Regarding the first comment:
#implementation CJSHCardView : UIImageView
- (id)initWithFrame:(CGRect)frame
{
NSAssert(NO, #"Call initWithHeight instead.");
return self;
}
Does that answer your question?
--SECOND EDIT--
Thank you for your response and your code, Nick. I have slightly altered it to fit ARC and to initially set a fixed-width scale, but I was a little unsure of what method to put it in. I tried the ViewController's viewDidLoad() method, but that resulted in the background being shown without hide or hair of the note. My present viewDidLoad() method reads:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIImage *backgroundImage = [UIImage imageNamed:#"Default-568h"];
CGRect containerRect = CGRectZero;
containerRect.size = [backgroundImage size];
UIView *containerView = [[UIView alloc] initWithFrame:containerRect];
float scale=.1;
UIImageView *backgroundView = [[UIImageView alloc] initWithImage:backgroundImage];
[containerView addSubview:backgroundView];
[backgroundView sizeToFit];
// [backgroundView release];
UIImage *noteImage = [UIImage imageNamed:#"note"];
CGSize noteSize = [noteImage size];
UIImageView *noteView = [[UIImageView alloc] initWithImage:noteImage];
[noteView setContentMode:UIViewContentModeScaleAspectFit];
[noteView setFrame:CGRectMake(0, 0, noteSize.width * scale, noteSize.height * scale)];
[containerView addSubview:noteView];
// [noteView release];
}
Thanks,
Subclassing UIImageView is not necessary. Just create a container UIView and add 2 UIImageView subviews.
Edit - this should work for your implementation:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIImage *backgroundImage = [UIImage imageNamed:#"Default-568h"];
CGRect containerRect = CGRectZero;
containerRect.size = [backgroundImage size];
UIView *containerView = [[UIView alloc] initWithFrame:containerRect];
[[self view] addSubview:containerView];
float scale=.1;
UIImageView *backgroundView = [[UIImageView alloc] initWithImage:backgroundImage];
[containerView addSubview:backgroundView];
[backgroundView sizeToFit];
UIImage *noteImage = [UIImage imageNamed:#"note"];
CGSize noteSize = [noteImage size];
UIImageView *noteView = [[UIImageView alloc] initWithImage:noteImage];
[noteView setContentMode:UIViewContentModeScaleAspectFit];
[noteView setFrame:CGRectMake(0, 0, noteSize.width * scale, noteSize.height * scale)];
[containerView addSubview:noteView];
}
I want to give a background image to my UITableView, so I tried this method:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
UIImageView *v = [[UIImageView alloc] initWithFrame:self.view.bounds];
[v setImage:[UIImage imageNamed:#"Background.png"]];
[self.view addSubview:v];
[self.view sendSubviewToBack: v];
...
}
This works fine. However, after pushViewController, this method doesn't work anymore (why?). So I changed a method:
- (void)viewDidLoad
{
[super loadView];
// Do any additional setup after loading the view from its nib.
self.tableView.backgroundView = nil;
self.tableView.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:#"Background.png"]];
...
}
This can work, but the result is not what I expected. Somehow the background picture changes its size (like a partial enlargement), and the background of cells is darker than the previous one.
Anyone knows the reason? I've been stuck with this problem for a long time.
Thanks a lot!
Use this:
UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"TableBackground.jpg"]];
self.tableView.backgroundColor = background;
[background release];
Edit:
UIImage *myImage = [[UIImage alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
myImage.image = [UIImage imageNamed:#"TableBackground.jpg"];
UIColor *background = [[UIColor alloc] initWithPatternImage:myImage];
self.tableView.backgroundColor = background;
[background release];
Try This Code i am sure it'll work
UIImage * targetImage = [UIImage imageNamed:#"coloured_flower.jpg"];
UIGraphicsBeginImageContextWithOptions(tableView.frame.size, NO, 0.f);
[targetImage drawInRect:CGRectMake(0.f, 0.f, tableView.frame.size.width, tableView.frame.size.height)];
UIImage * resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
tableView.backgroundColor = [UIColor colorWithPatternImage:resultImage];
UITableView *tblView=[[UITableView alloc] init];
[tblView setFrame:CGRectMake(0, 0, 320, 300)];
UIImageView *imgView=[[UIImageView alloc] initWithFrame:tblView.frame];
[imgView setImage:[UIImage imageNamed:#"cinemax.jpg"]];
tblView.backgroundView=imgView;
[self.view addSubview:tblView];
- (void)viewDidLoad
{
[super viewDidLoad];
[self setTitle:#"myTitle"];
UIImageView *titleLabel = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"myImage.PNG"]];
titleLabel.frame = CGRectMake(0, 0, 120, 40);
self.navigationItem.titleView = titleLabel;
}
UIImageView *titleLabel = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"nature.jpeg"]];
titleLabel.frame = CGRectMake(0, 0, 120, 40);
titleLabel.contentMode = UIViewContentModeRight;
self.navigationItem.titleView = titleLabel;
I think the best is to use UIImageView contentMode property.
You can use like this:
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,480)];
imageView.contentMode = UIViewContentModeLeft;
It should be ok.
We are using a base class where we set the background picture. That code looks like:
UIImage* image = [UIImage imageNamed:#"App_Background.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.contentMode = UIViewContentModeScaleAspectFill;
CGRect bounds = self.view.bounds;
int offset = 0;
imageView.frame = CGRectMake(0, bounds.size.height - image.size.height + offset, image.size.width, image.size.height);
imageView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
imageView.tag = BACKGROUND_TAG;
[self.view insertSubview:imageView atIndex:0]; // insert it behind all other views in NIB
self.background = [imageView autorelease]; // cleanup
If I want to use this as my superclass for another UIViewController but do not want to use the backgound, how do I do that? I thought I could do this in my subclass' viewDidLoad:
UIView *theBackgroundView = [self.view viewWithTag:BACKGROUND_TAG ];
theBackgroundView = nil;
But that doesn't work. Any thoughts? thanks.
Make sure you call [super viewDidLoad] first. Then do [[self.view viewWithTag: BACKGROUND_TAG] removeFromSuperview].
I'm having trouble setting the background image on my tabbar. I've upgraded to iOS5 and Xcode 4.2, and the tabbar background image just stopped working.
The tabbar is only present on my RootViewController.
I managed to use the Interface Builder and applied a background colour which is not exactly what I wanted but will do for now. This only works for iOS5 for some reason. Ideally I would like to do it programmatically. I'm trying to get the following code working:
RootViewController.h
#interface RootViewController : UIViewController {
IBOutlet UITabBar *mainTabBar;
IBOutlet UITabBarItem *settingsBarItem;
IBOutlet UITabBarItem *infoBarItem;
IBOutlet UITabBarItem *aboutBarItem;
}
#property (retain,nonatomic) UITabBar *mainTabBar;
#end
RootViewController.m
-(void)viewDidLoad {
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"smallMenuBackground.png"]];
if ([mainTabBar respondsToSelect:#selector(setBackgroundImage:)]){
mainTabBar.backgroundImage = imageView;
}
else{
CGRect frame = CGRectMake(0, 0, 480, 49);
UIView *v = [[UIView alloc] initWithFrame:frame];
UIImage *i = [UIImage imageNamed:#"smallMenuBackground.png"];
UIColor *c = [[UIColor alloc] initWithPatternImage:i];
v.backgroundColor = c;
[c release];
[mainTabBar insertSubview:v atIndex:0];
[v release];
}
}
This code is just not working for me, I must be doing something wrong, so any help appreciated.
I'm getting a couple of warning messages aswell:
1) Instance method '-respondToSelect:' not found (return type defaults to 'id')
2) Incompatible pointer types assigning to 'UIImage *' from 'UIImageView *'
EDIT
The entire code is too large to paste here, the RootViewController.h is http://pastie.org/3249124 and the RootViewController.m is http://pastie.org/3249137
this line, shouldn't it be
if ([mainTabBar respondsToSelector:#selector(setBackgroundImage:)])
respondsToSelector: not respondsToSelect:
also, just as it said exactly,
mainTabBar.backgroundImage = imageView;
should be
mainTabBar.backgroundImage = [UIImage imageNamed:#"smallMenuBackground.png"];
because backgroundImage is UIImage while your imageView is UIImageView
Edit
also, I find that the code in your else statement is kind of weird, try if this is working.
else
{
UIImage *i = [UIImage imageNamed:#"smallMenuBackground.png"];
UIImageView* imageView = [UIImageView alloc] initWithImage:i];
[mainTabBar insertSubview:imageView atIndex:0];
[imageView release];
}
EDIT 2:
if ([mainTabBar respondsToSelect:#selector(setTintColor:)])
{
UIImage *i = [UIImage imageNamed:#"smallMenuBackground.png"];
UIColor* c = [[UIColor alloc] initWithPatternImage:i];
mainTabBar.tintColor = c;
}
else
{
CGRect frame = CGRectMake(0, 0, 480, 49);
UIView *v = [[UIView alloc] initWithFrame:frame];
UIImage *i = [UIImage imageNamed:#"smallMenuBackground.png"];
UIColor *c = [[UIColor alloc] initWithPatternImage:i];
v.backgroundColor = c;
[c release];
[mainTabBar insertSubview:v atIndex:0];
[v release];
}
you have minor problem you pass imageview in mainTabBar.backgroundImage it's worng , you will pass UIImage ... please check this code
-(void)viewDidLoad {
if ([mainTabBar respondsToSelect:#selector(setBackgroundImage:)]){
mainTabBar.backgroundImage = [UIImage imageNamed:#"smallMenuBackground.png"] ;
}
else{
CGRect frame = CGRectMake(0, 0, 480, 49);
UIView *v = [[UIView alloc] initWithFrame:frame];
UIImage *i = [UIImage imageNamed:#"smallMenuBackground.png"];
UIColor *c = [[UIColor alloc] initWithPatternImage:i];
v.backgroundColor = c;
[c release];
[mainTabBar insertSubview:v atIndex:0];
[v release];
}
}