How to resize images in UITableViewCell? - ios

I am trying to make an Xcode app that has a list that loads data from a JSON file. It basically has a title, subtitle, and a thumbnail image. When the app loads up, the images are exactly as big as the cells. I would either like to resize the images to a set size, or make some extra room in-between the cells. Here is my current code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary *tempDictionary= [self.googlePlacesArrayFromAFNetworking objectAtIndex:indexPath.row];
NSURL *url = [NSURL URLWithString:[tempDictionary objectForKey:#"icon"]];
NSData *data = [NSData dataWithContentsOfURL:url];
cell.imageView.image = [UIImage imageWithData:data];
CALayer * l = [cell.imageView layer];
[l setCornerRadius:13];
[l setBorderWidth:0.5];
[l setBorderColor:[[UIColor lightGrayColor] CGColor]];
cell.imageView.layer.masksToBounds = YES;
...}
Thanks for your help.
Update: I have discovered this:
UIImage *thumbnail = [UIImage imageWithData: [NSData dataWithContentsOfURL :url]];
CGSize itemSize = CGSizeMake(30, 30);
UIGraphicsBeginImageContext(itemSize);
CGRect imageRect = CGRectMake(30.0, 30.0, itemSize.width, itemSize.height);
[thumbnail drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
The image resizes, but it is just blank.

I was facing same problem with image re-sizing. After searching on internet I found a useful method:
+(UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
This will return the image size.
In my case I made a Helper class and in Helper.h I declared this method as a class method so that I can call it in my UITableView. An than in Helper.m I implemented this method.
In cellForRowAtIndexPath method:
cell.imageView.image = [Helper imageWithImage:***Your Image here*** scaledToSize:CGSizeMake(ImageWidth,ImageHeight)];
Don't forget to import Helper.h in your TableView class.
You can also use this class in your way.
Hope it works.

Try this:
cell.imageView.contentMode = UIViewContentModeScaleAspectFit;
Or:
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
Or, you could scale the images that you get from the url.
CGFloat scale = 10.0f; // adjust this number
UIImage *image = [UIImage imageWithData:
[NSData dataWithContentsOfURL:url]
scale:scale];
cell.imageView.image = image;

Related

How to scale UIImage in tableview?

This is my code:
UIImage *image1 = [UIImage imageNamed:#"AllMyFiles-1 (dragged).tiff"];
cell.imageView.image = image1;
cell.textLabel.text = self.greekLetters[indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.imageView.contentMode = UIViewContentModeScaleAspectFit;
And this is is what it looks like:
tableview with image
And I want the UIImage to be a bit smaller much like this:
tableview with smaller image
There are some options to solve that...
1) You can put transparency in your image,
getting something like that: image centered with transparency
2) You can draw your custom cells prototype on your StoryBoard or Xib file
3) You can resize your image programmatically:
Add this method on your class or a extension of UIImage:
- (UIImage *) reziseImage:(UIImage*) image withSize:(CGSize) newSize {
UIGraphicsBeginImageContext(newSize);
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
And call it on your method:
UIImage *image1 = [UIImage imageNamed:#"AllMyFiles-1 (dragged).tiff"];
cell.imageView.image = image1;
CGSize newSize = CGSizeMake(25, 25);
image1 = [self reziseImage:image1 withSize:newSize];
cell.imageView.image = image1;
cell.textLabel.text = self.greekLetters[indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.imageView.contentMode = UIViewContentModeScaleAspectFit;

May I know why the tableview cell getting lazy while I'm scrolling?

if (cell.tag == indexPath.row) {
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:[enclosureUrlArray objectAtIndex:indexPath.row]]
placeholderImage:[UIImage imageNamed:#"placeholder"] options:indexPath.row == 0 ? SDWebImageRefreshCached : 0];
CGSize itemSize = CGSizeMake(50, 50);
UIGraphicsBeginImageContext(itemSize);
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
[cell.imageView.layer setMasksToBounds:YES];
[cell.imageView.layer setCornerRadius:2.5f];
[cell.imageView.image drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
cell.imageView.autoresizingMask = UIViewAutoresizingNone;
}
return cell;
I used SDWebImage only. While I'm scrolling my UITableView cells are stuck - it's not scrolling smoothly. I am retrieving images from a web service. Can you let me know why this is happening?
In your code you will face a problem while scrolling the table view, because after downloading the image you're changing the image shape, like applying Bounds, Radius. So that image shape is changing every time. It'd be better not to use any 3rd party library but use apple APIs instead.
The code below might help:
cell.imageView.image = nil;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:parsedData[#"imageLR"]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
if (cell.tag == indexPath.row) {
cell.imageView.image = image;
CGSize itemSize = CGSizeMake(50, 50);
UIGraphicsBeginImageContext(itemSize);
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
[cell.imageView.layer setMasksToBounds:YES];
[cell.imageView.layer setCornerRadius:2.5f];
[cell.imageView.image drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
cell.imageView.autoresizingMask = UIViewAutoresizingNone;
[cell setNeedsLayout];
}
});
}
});
If you want your table view to scroll buttery-smooth, I suggest you watch Session 211 of WWDC 2012, Building Concurrent User Interfaces and apply the concepts there. This features cells whose contents are independently queried and rendered.
The basic concept is as follows:
1. In tableView:cellForRowAtIndexPath, a cell is instantiated.
2. In the same method, an operation for retrieving the data to populate the cell is created and stored into a dictionary. A reference to the cell is passed to the operation. The operation has a completion handler that populates the cell and removes the operation from the dictionary.
3. Before the cell is returned from the method, the operation is added to an operation queue.
4. In tableView:didEndDisplayingCell:forRowAtIndexPath, operations for cells that have moved off-screen are cancelled and removed from the dictionary.

Download image through AFNetworking & edit it

I'm trying to download some image files from a remote server through the AFNetworking (UIImageView+AFNetworking.h) & retrieve the UIImage from it, edit that image. Editing means add that image(downloaded image) on top of another png file.( background image - UIImage )
I have tried several code blocks finally I'm stuck in here . I'm getting a black box only. Can't see the actual server image .
-(UIImage *)downloadImages:(NSString *)url{
UIImageView *downloadedImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0,0,40,40)];
[downloadedImageView setImageWithURL:[NSURL URLWithString:url]
placeholderImage:[UIImage imageNamed:#"Loading_image"]];
UIGraphicsBeginImageContextWithOptions(downloadedImageView.bounds.size, downloadedImageView.opaque, 0.0);
[downloadedImageView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
Then I'm calling through that function in a for loop.
for( int i=0;i<[Images count];i++){
NSString *image_Url = [NSString stringWithFormat:#"%#%#",imageURL, imagename];
UIImage *downloadimage =[[UIImage alloc]init];
downloadimage = [self downloadImages:image_Url];
UIImage *bottomImage = [UIImage imageNamed:#"map_marker_black"];
CGSize newSize = CGSizeMake(60, 60);
UIGraphicsBeginImageContext( newSize );
[backgroundImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
[downloadimage drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:0.7];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
Where am I doing wrong ? Your help is highly appreciated. Thanks a lot
A few issues. Lets start with the download code. There is no reason to deal with an image view and drawing it to create an image. Just use the actual image:
- (UIImage *)downloadImage:(NSString *)url{
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
UIImage *image = [UIImage imageWithData:imageData];
return image;
}
The big issue with your original code is that the AFNetworking method you used runs in the background. So you were always trying to draw the "loading" image.
Now the drawing code:
// Only need to load this once
UIImage *backgroundImage = [UIImage imageNamed:#"map_marker_black"];
// What is the loop used for?
for (NSUInteger i = 0; i < [Images count]; i++){
// Where does imageURL and imagename come from?
NSString *imageURL = [NSString stringWithFormat:#"%#%#",imageURL, imagename];
UIImage *downloadImage = [self downloadImage:imageURL];
CGRect newRect = CGRectMake(0, 0, 60, 60);
UIGraphicsBeginImageContextWithOptions(newRect.size, NO, 0.0);
[backgroundImage drawInRect:newRect];
[downloadimage drawInRect:newRect blendMode:kCGBlendModeNormal alpha:0.7];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
// Do something here with newImage
UIGraphicsEndImageContext();
}
Note the comments in the code.

merge multiple UIImages on iOS

I want to merge multiple UIImages in iOS.
To do this, I tried to do as below:
UIImage *imageLeft = [UIImage imageNamed:#"ico-left"];
UIImage *imageRight = [UIImage imageNamed:#"ico-right"];
CGSize size = CGSizeMake(imageLeft.size.width + imageRight.size.width, imageLeft.size.height);
UIGraphicsBeginImageContext(size);
[imageLeft drawInRect:CGRectMake(0, 0, imageLeft.size.width, imageLeft.size.height)];
[imageRight drawInRect:CGRectMake(imageLeft.size.width, 0, imageRight.size.width, imageRight.size.height)];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, finalImage.size.width, finalImage.size.height)];
imageView.image = finalImage;
[cell.contentView addSubview:imageView];
But I cannot get any image. How can I fix it?
Thanks.
I think you are not adding extension of image (.png) so change your upper two lines by these
UIImage *imageLeft = [UIImage imageNamed:#"ico-left.png"];
UIImage *imageRight = [UIImage imageNamed:#"ico-right.png"];
I am not sure whether this is your problem but you can give it a try. Sometimes it worked for me
NSString *path1 = [[NSBundle mainBundle] pathForResource:#"ico-left" ofType:#"png"];
NSString *path2 = [[NSBundle mainBundle] pathForResource:#"ico-right" ofType:#"png"];
UIImage *imageLeft = [[UIImage alloc] initWithContentsOfFile:path1];
UIImage *imageRight = [[UIImage alloc] initWithContentsOfFile:path2];
Here's the code I use to merge images. (I think I found all or part of it online at some point). Put it in a UIImage category.
// NOTE! this method should only be called from the main thread because of
// UIGraphicsGetImageFromCurrentImageContext();
- (UIImage *)merge:(UIImage *)image atRect:(CGRect)pos overlay:(BOOL)overlay fillColor:(UIColor *)fill
{
UIGraphicsBeginImageContext(self.size);
UIImage *bottom = (overlay)?self:image;
UIImage *top = (overlay)?image:self;
CGRect lf = CGRectMake(0, 0, self.size.width, self.size.height);
CGRect bottomRect = (overlay)?lf:pos;
CGRect topRect = (overlay)?pos:lf;
if (fill){
[fill setFill];
CGContextFillRect (UIGraphicsGetCurrentContext(), topRect);
}
[bottom drawInRect:bottomRect];
[top drawInRect:topRect];
UIImage *destImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return destImage;
}

Image inside another image

I'm based on this code:Custom MKAnnotationView with frame,icon and image
And I'm trying to do it a little different...I have an image non-transparent, and I want put an image inside.
My problem is that the background image cover my image. So it looks something like: http://cl.ly/image/0E0S00072G1n
My code is so:
annotationImageView.image = [UIImage imageNamed:#"marker_fb"];
UIImage *frame = [UIImage imageNamed:#"marker_fb"];
ImagePin *imagePinImage = annotation;
NSString *urlStringForImage = [NSString stringWithFormat:#"%#", imagePinImage.image];
NSURL *urlForImage = [NSURL URLWithString:urlStringForImage];
UIImageView *imageView = [[UIImageView alloc] init];
[imageView setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#", urlForImage]] placeholderImage:[UIImage imageNamed:#"avatar-placeholder.png"]];
UIGraphicsBeginImageContext(CGSizeMake(annotationImageView.image.size.width, annotationImageView.image.size.height));
[frame drawInRect:CGRectMake(0, 0, frame.size.width, frame.size.height)];
[imageView.image drawInRect:CGRectMake(2, 2, 48, 38)]; // the frame your inner image
annotationImageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Does z-indez exist in object-c? or how should I do??
Thanks.
EDIT: I tried also with:
UIGraphicsBeginImageContextWithOptions(CGSizeMake(annotationImageView.image.size.width, annotationImageView.image.size.height), NO, 0);

Resources