UITableViewCell background image and selection problem - iphone

It's my first iphone app, and i have trouble with styling my tableView.
I have two images (png), one for standard cell state, and one for selected state.
In my subclassed cell, I tried the following :
1) setting up front the backgroundView and selectedBackgroundView
UIImage *ib = [UIImage imageNamed:#"tab.png"];
UIImageView *back = [[UIImageView alloc] initWithImage:ib];
self.backgroundView = back;
[back release];
UIImage *is = [UIImage imageNamed:#"selected_tab.png"];
UIImageView *selected = [[UIImageView alloc] initWithImage:is];
self.selectedBackgroundView = selected;
[selected release];
The standard cell is fine, but when selected, the two images are shown.
2) just playing with background view on selection :
// storing the 2 uiviews in class attributes
UIImage *ib = [UIImage imageNamed:#"tab.png"];
UIImageView *back = [[UIImageView alloc] initWithImage:ib];
self.storedStandard = back;
[back release];
UIImage *is = [UIImage imageNamed:#"selected_tab.png"];
UIImageView *selected = [[UIImageView alloc] initWithImage:is];
self.storedSelected = selected;
[selected release];
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
if (selected) {
self.backgroundView = self.storedSelected;
}
else {
self.backgroundView = self.storedStandard;
}
}
It nearly works, but the images don't fit the cell, i don't know to stretch them to the size of the cell.
For me, the first solution should have been the one, based on the properties' names, and the second solution seems like a hack (like 90% of the tutorials i seen btw), so i'm a bit frustrated.
To sum up : why the first one doesn't work, and how could i force images to take all the cell space ?
Thanks a lot :)

if you have a UITableViewDelegate, you should be able to just change the backgroundView's image in the willSelectRowAtIndexPath: method and then change it back in the didSelectRowAtIndexPath: method. This is a bit of a hack however.

Related

Animate iphone tableviewCell background image with two images

i want to animate tableviewcell background image with two blinking images on didSelectRowAtIndexPath. We can use following code, but it will show one image in background. However I want gif like image which blinks.
cell.backgroundView = [ [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"correctAnswer.png"]]autorelease];
UIImageView has the ability to do animation with the animationImages property.
UIImageView* imgView = [[[UIImageView alloc] init] autorelease];
imgView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"correctAnswer1.png"],
[UIImage imageNamed:#"correctAnswer2.png"], nil];
imgView.animationDuration = 0.5;
cell.backgroundView = imgView;
[imgView startAnimating];
You need to have each frame of the animation included in your project, correctAnswer1.png, correctAnswer2.png, etc...
Also, wouldn't it be better to use UITableViewCell's imageView property? That way you would get your animation in the left of the cell and it wouldn't interfere with the text or any other parts of the cell...

Add a white background to a .png UIImage file with HSImageSidebarView

How can I add a white background to a .png UIImage file with HSImageSidebarView?
I have tried creating a UIImageView then showing that on the sidebar, but unfortunately the app crashes with an NSException. Any ideas on how to add a white background to the image files on the sidebar if they are a UIImage instead of a UIImageView.
You will try this code add one scrollview on nib and set its contentsize on viewdidload
CGFloat x = 20;
for (int i = 0;i<[playerScores count];i++) {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(x, 10, 60, 60)];
view.backgroundColor=[UIColor blueColor];
NSString *text = [NSString stringWithFormat:[playerScores objectAtIndex:i]];
[view setText:text];
[yardsScrollView addSubview:view];
[myLabel release];
x = x+125;
}
PlayersScore is a NSMutable array which have many text like how much view You want.
#objc-obsessive
You will need to loop through the subviews to find whether it is of kind UIImage or UIImageView by this:
id object;
if([object isKindOfClass:[UIImage Class]]) {
//Do whatever u want to here by creating a new imageView on the top of this image
//Something like this:
UIImage *image =(UIImage*)object;
UIImageView *imgView=[[uiimageview alloc]initwithimage:image];
//Now perform the background view operations on imgView i.e. instance of UIImageView.
}
//Hope it works.

check which image has been set to imageview

I have used the animated images on image view concept. It is working fine.Now whenever when I touch that image view I want to check which image is placed on that image view. How should I do this. I have used the following code to make the images animated.
addimage.animationImages=[NSArray arrayWithObjects:
[UIImage imageNamed:#"Softindia.png"],
[UIImage imageNamed:#"images.png"],
nil];
addimage.animationDuration=25.0;
addimage.animationRepeatCount=0;
[addimage startAnimating];
[self.view addSubview:addimage];
Now what should I do on the touch event of image view. Please provide me some solution to resolve this.
Thanks in advance.
UITapGestureRecognizer *tapGesture =
[[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imagetap)] autorelease];
[imgview addGestureRecognizer:tapGesture];
-(void)imagetap
{
// your code what ever you want on touch
}
I am affraid that there is no such property inside UIImage which help you to find image name.
you can use this tricky method for solving your problem.
create an property
#property(nonatomic, retain) NSMutableArray * imageArray;
and then synthesis in .m file
#synthesis imageArray
afterward perform following action
self.imageArray = [[NSMutableArray alloc] init];
UIImage *myImage1 = [UIImage imageNamed:#"Softindia.png"];
[imageArray addObject:myImage1];
//Add Second Image
UIImage *myImage2 = [UIImage imageNamed:#"images.png"];
[imageArray addObject:myImage2];
addimage.animationImages= imageArray;
and where ever you are getting your image check do following action
UIImage image = addimage.image;
index = [imageArray indexOfObject:image];
if(index == 0){
//Do action for softindia.png
}
else {
//Do action for images.png;
}

Put small images on the top of UIImageView?

I've got a UIImageView in a page that gets its image from the Interface builder and I'm trying to put small icons on the top of it (it's a small map and I want to put icons on it). I know it's probably very simple but I tried to look it up in the documentation but it pretty much got me more confused.
Using Interface Builder, can't you just drag a UIImageView into an existing UIImageView? In effect, you end up with one UIImageView embedded within another.
You should also be able to easily set the hidden property of the "small map" UIImageView in code, depending on if that UIImageView is needed or not.
Hope this helps. Good Luck.
Let It Be Known
you could compose your own UIView by adding both the large and small UIViewImage views.
I have illustrated my approach below with the Pseudocode .
-(id) initwithFrame:(CGRect) frame
{
if(self = [super initWithFrame:frame])
{
iContainer = [[UIView alloc] initWithFrame:frame];
[iContainer addSubViews:iLargerUIImageView];
[iContainer addSubViews:iSmallUIImageView];
[self.view addSubViews:iContainer];
}
return self;
}
-(void) layoutSubviews
{
CGRect myRect = self.frame;
iContainer.frame = myRect;
//Give the location to iLargerUIImageView as per your requirement.
iLargerUIImageView.frame = CGRectMake(...,...,...,...);
//Give the location to iSmallUIImageViewas per your requirement.
iSmallUIImageView.frame = CGRectMake(...,...,...,...);
}
-(void) dealloc
{
[iContainer release];
[iLargerUIImageView release];
[iSmallUIImageView release];
}
try this code:
UIImageView *backgroundImageView = (UIImageView *)[self viewWithTag:kBckGndImag];
if(!backgroundImageView){
UIImage *imageName = [UIImage imageNamed:kpointsChartBig];
backgroundImageView = [[UIImageView alloc] initWithFrame:CGRectMake(15, 15, imageName.size.width, imageName.size.height)];
backgroundImageView.image=imageName;
[backgroundImageView setTag:kBckGndImag];
[pointImageView addSubview:backgroundImageView];
[backgroundImageView release];
}
UIImageView *foregroundImageView = (UIImageView *)[self viewWithTag:kForGndImage];
if(!foregroundImageView){
foregroundImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:kpointsColoredChartBig]];
foregroundImageView.contentMode = UIViewContentModeLeft;
foregroundImageView.clipsToBounds = YES;
[pointImageView addSubview:foregroundImageView];
[foregroundImageView release];
}

Changing bounds of imageView of UITableViewCell

I'm trying to place various size images inside imageView of UITableViewCell. I get the image data asynch'ly, create the image, set the content mode of imageView and finally set bounds of imageView. But the code seems insensitive to any changes I made. I want the images to be centered in a 75x75 area. I wrote the below code for this purpose
UIImage* image = [UIImage imageWithData:data];
[holder.imageView setContentMode:UIViewContentModeCenter || UIViewContentModeRedraw];
[holder.imageView setImage:image];
[holder.imageView setBounds:CGRectMake(0,0,75,75)];
[holder.imageView setFrame:CGRectMake(0,0,75,75)];
[holder setNeedsLayout];
Where holder is the UITableViewCell. The result I get is always the same. All images have 75px height and different widths. Can someone help me solve this problem?
I have realized that setting contentMode and bounds properties does not have any effect in that code. I have added an NSLog after the last line and got the results as below:
NSLog(#"imageview:%# bounds and contentMode:%# %#",[holder imageView],[holder.imageView bounds],[holder.imageView contentMode]);
imageview:<UIImageView: 0x39ab8a0;
frame = (0 0; 75 75); opaque = NO;
userInteractionEnabled = NO; layer =
<CALayer: 0x39a92b0>> bounds and
contentMode:(null) (null)
Still no solution
Done, I finally found the solution, it cost me 3 hours though =)
The solution is to change properties like bound,frame,contentMode in -(void)layoutSubviews method of the custom UITableViewCell class. The "trick" is to write layout code in this method, otherwise the code does not have any effect.
Below code did the work for me. It makes rows of the table vertically aligned.
- (void)layoutSubviews {
[super layoutSubviews];
self.imageView.bounds = CGRectMake(0,0,75,75);
self.imageView.frame = CGRectMake(0,0,75,75);
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
CGRect tmpFrame = self.textLabel.frame;
tmpFrame.origin.x = 77;
self.textLabel.frame = tmpFrame;
tmpFrame = self.detailTextLabel.frame;
tmpFrame.origin.x = 77;
self.detailTextLabel.frame = tmpFrame;
}
So the problem with UITableViewCell's is that you have no control over the size of the built-in objects (namely imageView, contentView, accessoryView, backgroundView). When the table changes, your customizations get trampled over.
You can, as Behlul pointed out, force the sizes to be correct by using layoutSubviews, but the problem with that is that layoutSubviews is called every time the table scrolls. That is a lot of unnecessary re-layout calls.
An alternate, method is to add all of your content to the contentView. Similarly if you are customizing the background, you can create a transparent backgroundView and add your custom background view (eg myBackgroundView) as a subview of backgroundView.
This way you can place and size your items how you want them.
The down side is the stock messages are no longer received from the accessory or image views. You just have to create you own.
Hope that helps!
// This code is not tested
// MyCustomTableViewCell
- (id) init{
self = [super initWithStyle: UITableViewCellStyleDefault reuseIdentifier:#"MyReuseIdentifier"];
if(self){
//image view
my_image_view = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"default_image.png"]] retain];
[my_image_view setFrame:CGRectMake(10,10,30,30)];
[self.contentView addSubview:my_image_view];
//labels
my_text_label = [[[UILabel alloc] initWithFrame:CGRectMake(50,10,100,15)] retain];
[self.contentView addSubview:my_text_label];
//set font, etc
//detail label
my_detail_label = [[[UILabel alloc] initWithFrame:CGRectMake(50,25,100,15)] retain];
[self.contentView addSubview:my_detail_label];
//set font, etc
//accessory view
//Whatever you want to do here
//attach "accessoryButtonTapped" selector to button action
//background view
UIView* background_view = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 50)] autorelease];
[background_view setBackgroundColor:[UIColor greenColor]];
background_view.layer.cornerRadius = 17;
background_view.layer.borderWidth = 3;
background_view.layer.borderColor = [UIColor whiteColor].CGColor;
[self setBackgroundView:[[[UIView alloc] init] autorelease]];
[self.backgroundView addSubview:background_view];
}
return self;
}
- (void) setLabelText: (NSString*) label_text{
[my_text_label setText:label_text];
}
- (void) setDetailText: (NSString*) detail_text{
[my_detail_label setText: detail_text];
}
- (void) accessoryButtonTapped{
//call table view delegate's accessoryButtonTappedForRowWithIndexPath method
}
"UIViewContentModeCenter || UIViewContentModeRedraw" is equivalent to 1. It's also not a bitfield. You want UIViewContentModeCenter.
UITableViewCell.imageView is managed by the cell. If you want custom layout, try adding a view to contentView (I'm guessing what you mean by "centered in a 75x75 area"):
UIImageView * iv = [[[UIImageView alloc] initWithImage:image] autorelease];
iv.frame = (CGRect){{0,0},{75,75}};
iv.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin| UIViewAutoresizingFlexibleRightMargin;
iv.contentMode = UIViewContentModeScaleAspectFit;
[holder.contentView addSubview:iv];
try changing the "contentMode" property of imageView to 'UIViewContentModeScaleAspectFit' or 'UIViewContentModeScaleAspectFill'
Create subclass of UITableViewCell:
#interface UITableViewCellSubClass : UITableViewCell
#end
#implementation UITableViewCellSubClass
- (void)layoutSubviews {
[super layoutSubviews];
self.imageView.frame = CGRectMake(0,4,32,32);
self.textLabel.frame = CGRectMake(42,4,300,32);
}
#end