How to set background image of a view? - iphone

I am a beginner at Obj-C/Cocoa Touch/iPhone OS.
I wish to have a background for my app with different images everytime the the view is called.
Say I have 10 images. I 've used it like this:
//random image generation
NSString* imageName;
int aRandomNumber = arc4random() % 10;
imageName =[NSString stringWithFormat:#"g%d.jpg",aRandomNumber];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:imageName]]];
NSLog(#"aRandomNumber is %d", aRandomNumber);
//random image is generated
Its working fine
Now, say I have text labels on my view and the text isn't displaying correctly due to image colors.
How can I make it a little transparent? (I guess in Interface Builder its called alpha.)
Say my image isn't 320x480. How do I set it to fill the entire view?
How can I do it with UIView/UIImageView?
I found initWithHue:saturation:brightness:alpha: in the documentation but it's not working:
self.view.backgroundColor = [[UIColor alloc] initWithHue:0.0 saturation:1.0 brightness:1.0 alpha:1.0];
Please Help!
A friend suggested........
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:imageName]]];
..........he told it's more efficient because it doesn't save the image in the cache.

self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"imageName.png"]];
more info with example project

Besides all of the other responses here, I really don't think that using backgroundColor in this way is the proper way to do things. Personally, I would create a UIImageView and insert it into your view hierarchy. You can either insert it into your top view and push it all the way to the back with sendSubviewToBack: or you can make the UIImageView the parent view.
I wouldn't worry about things like how efficient each implementation is at this point because unless you actually see an issue, it really doesn't matter. Your first priority for now should be writing code that you can understand and can easily be changed. Creating a UIColor to use as your background image isn't the clearest method of doing this.

use this
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"Default"]];

simple way :
-(void) viewDidLoad {
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"background.png"]];
[super viewDidLoad];
}

It's a very bad idea to directly display any text on an irregular and ever changing background. No matter what you do, some of the time the text will be hard to read.
The best design would be to have the labels on a constant background with the images changing behind that.
You can set the labels background color from clear to white and set the from alpha to 50.0 you get a nice translucent effect. The only problem is that the label's background is a stark rectangle.
To get a label with a background with rounded corners you can use a button with user interaction disabled but the user might mistake that for a button.
The best method would be to create image of the label background you want and then put that in an imageview and put the label with the default transparent background onto of that.
Plain UIViews do not have an image background. Instead, you should make a UIImageView your main view and then rotate the images though its image property. If you set the UIImageView's mode to "Scale to fit" it will scale any image to fit the bounds of the view.

You want the background color of your main view to be semi-transparent? There's nothing behind it... so nothing will really happen however:
If you want to modify the alpha of any view, use the alpha property:
UIView *someView = [[UIView alloc] init];
...
someView.alpha = 0.8f; //Sets the opacity to 80%
...
Views themselves have the alpha transparency, not just UIColor.
But since your problem is that you can't read text on top of the images... either:
[DESIGN] Reconsider the design/placement of the images. Are they necessary as background images? What about the placement of the labels?
[CODE] It's not exactly the best solution, but what you could do is create a UIView whose frame takes up the entire page and add some alpha transparency to it. This will create an "overlay" of sorts.
UIView *overlay = [[[UIView alloc] init] autorelease];
overlay.frame = self.view.bounds;
overlay.alpha = 0.2f;
[self.view addSubview:overlay];
... Add the rest of the views

You can set multiple background image in every view using custom method as below.
make plist for every theam with background image name and other color
#import <Foundation/Foundation.h>
#interface ThemeManager : NSObject
#property (nonatomic,strong) NSDictionary*styles;
+ (ThemeManager *)sharedManager;
-(void)selectTheme;
#end
#import "ThemeManager.h"
#implementation ThemeManager
#synthesize styles;
+ (ThemeManager *)sharedManager
{
static ThemeManager *sharedManager = nil;
if (sharedManager == nil)
{
sharedManager = [[ThemeManager alloc] init];
}
[sharedManager selectTheme];
return sharedManager;
}
- (id)init
{
if ((self = [super init]))
{
}
return self;
}
-(void)selectTheme{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *themeName = [defaults objectForKey:#"AppTheme"] ?: #"DefaultTheam";
NSString *path = [[NSBundle mainBundle] pathForResource:themeName ofType:#"plist"];
self.styles = [NSDictionary dictionaryWithContentsOfFile:path];
}
#end
Can use this via
NSDictionary *styles = [ThemeManager sharedManager].styles;
NSString *imageName = [styles objectForKey:#"backgroundImage"];
[imgViewBackGround setImage:[UIImage imageNamed:imageName]];

Related

How do I move an existing image without Interface Builder

I created multiple images without the use of interface builder. I used this code:
for (Row* row in parser.rows) {
CGRect IphoneFrameImageRect;
IphoneFrameImageRect = CGRectMake(10, 10, 150.0f, 150.0f);
UIImageView *IphoneFrame = [[UIImageView alloc] initWithFrame:IphoneFrameImageRect];
NSString *IphoneFrameurl = [NSString stringWithFormat:#"http://some.url.com/iphone/IphoneFrame.png"];
[IphoneFrame setImage:[UIImage imageWithData: [NSData dataWithContentsOfURL: [NSURL URLWithString:IphoneFrameurl]]]];
[IphoneFrame setTag:(i)];
IphoneFrame.opaque = YES; // explicitly opaque for performance
[self.view addSubview:IphoneFrame];
[IphoneFrame release];
}
I need to move these images to a different location in landscape mode. I did tag each image and it looks I can select the images back using this tag. But how can I gave the image a new coordinate ? I have this code:
-(void)positionViews {
UIInterfaceOrientation destOrientation = self.interfaceOrientation;
int i=4; //Picture with tag=4 for example
UIImage *tempImage=(UIImage *)[self.view viewWithTag:(i)];
// HOW TO MOVE ??
}
I am able to do this with a button using this code:
UIButton *tempButton=(UIButton *)[self.view viewWithTag:i];
[temp setFrame:CGRectMake(x, y, X10ButtonWidth, X10ButtonHeight)];
You are mixing up two different things / classes :
UIImage that represent image data, with its pixels, in memory
UIImageView that represent a view to display an image onscreen.
If it's more clear to you, an UIImage is to UIImageView what NSString is for an UILabel. The object representing the data/content is different from the view that can display it on screen.
So when you want to retrieve your imageview using the tag you set, you retrieve a view, especially an UIImageView for what matters, not an UIImage.
Change your cast to UIImageView and you will be able to call setFrame: on it the same way you do for your UIButton (as setFrame: is a method of the UIView class, and both UIImageView and UIButton are subclasses of UIView).
UIImageView *tempImageView = (UIImageView *)[self.view viewWithTag:(i)];
[tempImageView setFrame:...];
Or don't even do any cast, as viewWithTag: returns a UIView and that's all you need if you just want to change the frame: whether it's a basic UIView or specifically a UIImageView or whatever kind of view does not matter if you just want to change the frame property, as this is a property of the generic UIView class and can be applied to any UIView, whatever specific subclass of UIView it is.
UIView *tempImageView = [self.view viewWithTag:(i)];
[tempImageView setFrame:...];

ImageView Scrolling along with the tableview

In my application,i created an imageview on the above the tabbar.I want to display some images here for displaying some adds there.
What my actual problem is...i added this on my table view and whenever i am scrolling the table view ,my imageview is also scrolling.Please help me in this
Thanks in advance.Here is my code
UIImageView *currentLocationImageView = [[UIImageView alloc] init];
NSURL *url1 = [NSURL URLWithString:#"http://imgsrv.995themountain.com/image/kqmt2/UserFiles/Image/SiteGraphics/MTNVideos360x80.jpg"];
UIImage *img1 = [UIImage imageWithData: [NSData dataWithContentsOfURL:url1]];
NSURL *url2 = [NSURL URLWithString:#"http://download.xbox.com/content/images/35f6c527-fb73-40d3-bcb9-bdea2680bc03/1033/banner.png"];
UIImage *img2 = [UIImage imageWithData: [NSData dataWithContentsOfURL:url2]];
NSArray *images = [NSArray arrayWithObjects:img1, img2, nil];
[currentLocationImageView setAnimationImages:images];
[currentLocationImageView setAnimationRepeatCount:0];
[currentLocationImageView setAnimationDuration:5.0];
currentLocationImageView.frame = CGRectMake(0.0, 340.0, 320.0, 30.0);
//self.tableView.tableFooterView = currentLocationImageView;
[currentLocationImageView startAnimating];
[self.view addSubview:currentLocationImageView];
Without seeing more code, it looks as though you may be using a UITableViewController instead of a UIViewController. The difference between the two is important in the case of your last line [self.view addSubview:currentLocationImageView]. What that does in a UIViewController is adds it to the view that would be containing the tableview and the imageview. However, in a UITableViewController the self.view property holds the tableview itself, therefor, it ads your image view as a subview of the tableview, subjecting it to the tableview's scrolling behaviour.
What you can do is change from using a UITableViewController (probably going to be trivial for your application, but may be less than trivial depending on why you opted to use it in the first place); and you'll also need to explicitly create the tableview, and add it to the backing view of the UIViewController subclass you're writing—akin to how you're adding the imageview above.
Hope this helps.

selectedBackgroundView on UITableViewCell gets applied to all views in cell

I have a table cell being displayed that shows a users image, name and some text. The user's image is 50x50, but I want a border around it so I set the view to center the image and set the frame to 52x52 and then set the background color of that view to my border color. That shows a 1 pixel border around the image.
I also want to show a 30 pixel wide border on the right of the cell when the cell is selected. I've tried to do that by creating a UIView the size of the cell's frame, then adding a subview to that view with a UIView the width and background color I would like. I then set that view to the selectedBackgroundView of the cell.
The problem here is that the cell's selectedBackgroundView gets applied to the background of all views inside the cell. So when I select a cell, the images "border" gets set to the cell's selected background color, the other 30px "border" I'm adding gets changed to that background color also.
Code inside my cellForRowAtIndexPath:
cell = (UserCellView *) currentObject;
UIView *c = [[UIView alloc ] initWithFrame:CGRectMake(0, 0, 30, cell.frame.size.height)];
c.backgroundColor = [[UIColor alloc] initWithRed:64/255.0 green:64/255.0 blue:64/255.0 alpha:1.0];
UIView *v = [[UIView alloc ] initWithFrame:cell.frame];
v.backgroundColor = [[UIColor alloc] initWithRed:35/255.0 green:35/255.0 blue:35/255.0 alpha:1.0];
[v addSubview:c];
cell.selectedBackgroundView = v;
[c release];
[v release];
I'll assume that you haven't actually tested what's going on to form your analysis that it "gets applied to the background of all views inside the cell".
I did something like this:
#interface TestView : UIView {
}
#end
#implementation TestView
-(void)setBackgroundColor:(UIColor*)c {
// Breakpoint here.
NSLog("setBackgroundColor: %#",c);
[super setBackgroundColor:c];
}
#end
...
UIView * v = [[[UIView alloc] initWithFrame:(CGRect){{0,0},{20,20}}] autorelease];
v.backgroundColor = [UIColor magentaColor];
UIView * v2 = [[[TestView alloc] initWithFrame:(CGRect){{5,5},{10,10}}] autorelease];
v2.backgroundColor = [UIColor yellowColor];
[v addSubview:v2];
cell.selectedBackgroundView = v;
The end result is that -setBackgroundColor: is called from -[UITableViewCell _setOpaque:forSubview:] when the view is selected, with something like UIDeviceWhiteColorSpace 0 0 (i.e. [UIColor clearColor]).
Or, in other words, the background colour of some of the subviews are set to [UIColor clearColor] while the cell is selected, allowing selectedBackgroundView to show through. I think this happens because a common optimization is to give textLabel/detailTextLabel the table's background colour (e.g. white) so it draws faster, but this means the background colour has to be reset when the cell is selected.
The easiest fix is to use an image instead: a 1-by-1-pixel image of the correct colour in a UIImageView will work, if a bit messy. (I had this problem when drawing custom separator lines with 1-pixel-high UIViews, so I just included the separator into the background image.)
An alternative fix is to use a CALayer instead: Add a 52x52 sublayer to the UIImageView's layer, and set the sublayer's background colour. I'm pretty sure UITableViewCell simply walks the view hierarchy, so it should ignore custom layers. (The big disadvantage with layers is that they don't auto-size, which made them unsuitable for my purposes, and means the 30px right border won't auto-size.)
A workaround is to subclass the relevant views and ignore -setBackgroundColor: if it's equal to [UIColor clearColor].
A simple but obnoxious-to-maintain solution is to override setSelected:animated: and setHighlighted:animated: with implementations re-setting the various backgrounds you want. Something along the lines of:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
self.childView.backgroundColor = [UIColor blueColor]; // whichever you want
}
First add this to your file
#import <QuartzCore/QuartzCore.h>
Then turn your view into an image with...
UIView *rowView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 1.0, 60.0)];
rowView.backgroundColor = [UIColor colorWithRed:35/255.0 green:35/255.0 blue:35/255.0 alpha:1.0];
UIGraphicsBeginImageContext(rowView.bounds.size);
[rowView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *yourImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Then instead of adding a UIView to your cell, just add a UIImageView with "yourImage".
A simple solution if the affected view can be a custom subclass is to override -setBackgroundColor:
- (void)setBackgroundColor:(UIColor *)color
{
// Ignore requests and do nothing
}
Thus UITableViewCell's attempt to set the colour will go ignored. Code in the custom view which really does want to set the background colour needs to call super:
- (void)setColor:(UIColor *)color
{
[super setBackgroundColor:color];
}
(or could probably message the underlying CALayer directly)
you will need to customize the contentView of the cells and handle the delegate tableView:cellForRowAtIndexPath
See Posting Here

subclassed UITableViewCell - backgroundView covers up anything I do in drawRect

I'm trying to make a subclassed UITableViewCell where I draw an image in the upper right corner. I have it working perfectly - except when I set self.backgroundView, my background image covers up the image drawn in drawRect.
There must be a way to be able to set a background image (and the selectedBackgroundView) without covering up what's being done in drawRect.
Am I going about this the wrong way?
EDIT: I've posted an example project with the problem.
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
// TODO: figure out why this covers up self.starImage that's drawn in drawRect
self.backgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cellBackground.png"]] autorelease];
}
return self;
}
- (void)drawRect:(CGRect)rect {
[self.starImage drawAtPoint:CGPointMake(self.bounds.size.width - self.starImage.size.width, 0.0)];
}
EDIT 2: at AWrightIV's request, here's how I got it working... which didn't require subclassing UITableViewCell at all. I'm just adding a subview to cell.backgroundView:
// create a UIImageView that contains the background image for the cell
UIImageView *bgImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cellBackground.png"]];
// create another UIImageView that contains the corner image
UIImage *starRedImage = [UIImage imageNamed:#"starcorner_red.png"];
UIImageView *starImageView = [[UIImageView alloc] initWithFrame:CGRectMake(297,
0,
starRedImage.size.width,
starRedImage.size.height)];
starImageView.image = starRedImage;
// add the corner UIImageView as a subview to the background UIImageView
[bgImageView addSubview:starImageView];
// set cell.background to use the background UIImageView
cell.backgroundView = bgImageView;
You are not really supposed to mix the drawing with your cell like that, you are operating at a lower-level than the UITableViewCell machinery is operating, and this is why you get this problem.
This is just one of the various problems you will end up running into. You will run into other problems as you go down that path, including problems with how the selection works.
The proper approach is to create a custom UIView that contains the code to draw, and then you can addSubView that into your cell's root view. That will take care of the rendering in the proper order, and wont interfere with the selection system, and will work correctly in this case.
You shouldn't override the -drawRect: of a tablecell. Instead, create a new custom view and add it to the cell's contentView, and draw in there.
Have you tried adding a [super drawRect:rect]; there?
Here's a solution that's a bit of a kludge, but it fits my requirements exactly... with one fatal flaw: when cells get reused, the star corner shows up when I don't want it to.
http://dl.dropbox.com/u/2349787/UIImage_Position_subclassed_cell2.zip
I'm still using drawRect here, but only because self.starImage is null if you access it within the initWithStyle method. Also, instead of adding the subview to self.contentView, I'm adding it to self.backgroundView to prevent the cell's delete button from interfering with it. The star corner is positioned correctly in both portrait and landscape mode, and works fine within edit mode as well.
With the cell reuse issue though, It's still a no go... so, maybe I'm back to trying to do it without subclassing UITableViewCell.
I'm open to any further suggestions. Thank you!
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
// Initialization code
self.backgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cellBackground.png"]] autorelease];
}
return self;
}
- (void) drawRect:(CGRect)rect {
UIImageView *imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(self.bounds.size.width - self.starImage.size.width, 0, self.starImage.size.width, self.starImage.size.height)] autorelease];
imageView.image = self.starImage;
imageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
[self.backgroundView addSubview:imageView];
}

How to set the background of a UITableView to an image?

I am using a UITableViewController which uploads a table. I have a Nib File with UITableView in it.Now I want to set the background of the tableView either from interface builder or from the TableViewController to an image.
How to do that.
OK so I created an UIImage in my controller. Now when I add where do I need to add it.
When I try adding it and set the color of tableView to clearColor, it just shows me the Image and not the table although I make sure that image is being sent to back of all views.
Guys Please note that I am not dealing a UIView and adding a tableView as its subview But I am dealing with a UITableView .
Place a UIImageView behind the UITableView, then do this:
tableView.backgroundColor = [UIColor clearColor];
Somehow playing around I was able to find out a way.
self.tableView.backgroundColor = [UIColor clearColor];
self.parentViewController.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithData:imageData]];
self.tableView.backgroundColor = [UIColor clearColor];
self.parentViewController.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"parentViewBackground.png"]];
the image size should be
2x - 640*960
1x - 320*480
the size smaller than above, it will be tiled.
The backgroundColor = [UIColor colorWithPatternImage: image] method rkbang outlines works great. Here is another method to achieve the same effect by adding a new view to the parentViewController. This would be useful if you want to mask other contents the parentViewController might have.
In your UITableViewController subclass, in -viewDidLoad insert:
//make a cool background image
self.tableView.backgroundColor = [UIColor clearColor];
UIImage *patternImage = [UIImage imageNamed:#"backgroundImage.png"];
UIImageView * backgroundImageView = [[UIImageView alloc] initWithImage:patternImage];
[self.parentViewController.view addSubview:backgroundImageView];
[self.parentViewController.view sendSubviewToBack:backgroundImageView];
//release the background image and image view (the backgroundImageView is still retained by the parentViewController)
[patternImage release];
[backgroundImageView release];
You may wish to keep track of the backgroundImageView so you can remove it or replace it. The code example above leaves it to the parentViewController to manage the new view. If you're loading and unloading this UITableView, you'll be leaking these UIImageViews with every load unless the parentViewController is releasing them at the same rate somehow.
What you can do is set the backgroundColor property of the tableview to [UIColor clearColor] and have a UIImageView of the same size and position underneath your TableView to show your background.
TableView properties include background color. Set this to clearColor; and put the image behind it. (In IB I think you'll have to delete the tableview add an image and then add your tableview back again)
if you're subclassing UITableViewController you get a tableview for free, no ivar or nib required, however since you're using a background I would stick with IB.
You can use the table-view's backgroundView. This worked for me.
[self.tableView setBackgroundView: [[UIImageView alloc] initWithImage: [UIImage imageNamed:#"????.png"]]];
where ????.png is your background image.