Limit the size of an UIImage which is set programmatically - iphone

I'm dynamically loading images from a web service. The images will be loaded (with [UIImage imageWithData:data];) and be placed in a in an UIImageView in my custom UITableViewCell using the setImage message
. I gave the imageView a width and height of 27 by 19 in the interface builder and told him to "Aspect fit" (tried all the others too btw), but the image doesn't do that. It just scales (in aspect, I think) to fill the view cell.
I tried a lot of things, like resizing the image (does the job, but I can count the pixels on my retina display), resizing the UIImageView... But I just don't get is... Someone got an idea what I'm doing wrong?
The code that changes the cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"NewsTableViewCell" owner:self options:nil];
cell = self.tableCell;
self.tableCell = nil;
}
viArticle *article = [self.viData.articles objectAtIndex:indexPath.row];
UILabel *label;
label = (UILabel *)[cell viewWithTag:1];
label.text = article.title;
label = (UILabel *)[cell viewWithTag:2];
label.text = [NSString stringWithFormat:#"%# %#", article.time, article.type];
if (article.image != nil) {
UIImageView *imageView;
imageView = (UIImageView *)[cell viewWithTag:0];
[imageView setImage:article.image];
}
return cell;
}
This is the view:
And the settings:

What happens if you untick "Autoresize Subviews"?

#GuidoH hey sorry for the late reply..
Here is the code that will add the image to the table view cell.
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *SimpleTableIdentifier = #" SimpleTableIdentifier ";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier] autorelease];
}
UIImage *image = [UIImage imageNamed:#"star.png"];
cell.imageView.image = image;
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
return cell;
}
//use this delegate it will increase the row size and thus your imagesize will get increased too.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 80; //value can be changed
}
I would suggest scaling the images will surely lead to slow performance by your app.

I just posted a "solution" earlier today, but that seem to work, but was a wrong assumption. After asking on IRC I found the real solution. I was using the tag 0, that one shouldn't be used. Changing it to an higher value really solved my problem. Sometimes it can be thát easy. :)
Thanks y'all.

If you want to resize the UIImageView you can use the frame property.
suppose you have a UIImageView declare in .h file(lets take UIImageView *myImage;) and it is linked to the interface builder too.
you have synthesis it in .m class etc.
then when you want to resize the UIImageView, use
myImage.frame = CGRect(x,y,width,height);
Note: by declaring the width and height in the code, the width and height declared in the IB will be override.
then dont forget to add it to subview,
i.e [self.view addSubview:myImage];
and its done, you can see the changes.

Related

UILabels within a UITableView cell are overlaying each other in iOS7

I didn't have this problem with iOS6, but am currently having it with iOS7. I have a UITableView and you can see 8 cells at the time the view is loaded. Each populated with different names from and array. If you scroll down, the next two cells look good, but everything past that gets text laid on top of it; That text being the contents of what was in the previous cells. So the 10th cell will have what was in the first cell, as well as what is supposed to be in the 10th cell laid on top of it.
Code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
//Create Label for Name inside cell
UILabel *name = [[UILabel alloc] initWithFrame:CGRectMake( 7.0, 5.0, 300.0, 30.0 )];
[name setText:[self.entriesArray objectAtIndex:indexPath.row]];
//Check to see if current person is a Parent or Child
NSString *class = [self.database getCellDataWithMembership:[self.MembershipArray objectAtIndex:indexPath.row] andColIndex:4];
if([class isEqualToString:#"CHILD"])
{
name.textColor = [UIColor colorWithRed:25.0f/255.0f green:111.0f/255.0f blue:45.0f/255.0f alpha:1.0f];
name.font = [UIFont fontWithName:#"Helvetica-Bold" size:17.0];
}
[cell.contentView addSubview:name];
return cell;
}
My skill with Table views is makeshift at best. I've been reading lots of documentation and researching solutions, but was not able to come up with a solution. I just find it odd that it works perfect for iOS6, but not for iOS7.
So it fetches a person's name from an array and I want to populate the cells with those names. I was able to originally accomplish this using:
cell.textLabel.text = [self.entriesArray objectAtIndex:indexPath.row];
if([class isEqualToString:#"CHILD"])
{
cell.textLabel.textColor = [UIColor colorWithRed:25.0f/255.0f green:111.0f/255.0f blue:45.0f/255.0f alpha:1.0f];
cell.textLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:17.0];
If I use that instead of the "name" UILabel actions from the first code block, then it displays the names perfectly with no text overlay, but what becomes an issue is the text color. If they are labeled as a CHILD then they should be green text and bold. However, after scrolling down, every person becomes green when they shouldn't be.
Sorry for the lengthy question. I've been working on this and racking my brain around it and I just can't seem to figure it out. Any help would be greatly appreciated.
I'm dynamically adding UI objects to cells. As "caglar" notes, adding and then removing is probs not the best-practice. But, I am doing this also. The way I get around adding loads of UI objects to the cell, each time it's displayed, is by removing all my subviews first. The willDisplayCell delegate then adds them back. Clearly, if you want to remove only certain views, you'll have to tag the view and be more selective with your removal. But you can remove all with the following.
-(void)tableView:(UITableView *)tableView
willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath {
[[cell.contentView subviews] makeObjectsPerformSelector:#selector(removeFromSuperview)];
}
Just ensure you're adding / removing your labels to the cell's contentView. In iOS7, you'll remove that too, if you're not careful.
Hope it helps you out.
In your code, labels are added to cell whenever cellForRowAtIndexPath: method is called. I mean you add labels many times. You can remove the label which was added before.
//If label was added with tag = 500, remove it
for (UIView *sv in cell.contentView.subviews)
{
if (sv.tag == 500)
{
[sv removeFromSuperview];
}
}
//Create Label for Name inside cell
UILabel *name = [[UILabel alloc] initWithFrame:CGRectMake( 7.0, 5.0, 300.0, 30.0 )];
[name setText:[self.entriesArray objectAtIndex:indexPath.row]];
name.tag = 500;
However, this solution is not a good solution. I think creating a custom UITableViewCell is the right thing to do.
You can try this method, when the cell is nil, you need to creare the UILabel* name, then you set the name label with a tag name.tag = 1000, then you can access this label with this method UILabel* name = (UILabel*)[cell.contentView viewWithTag:1000];.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
//Create Label for Name inside cell
UILabel *name = [[UILabel alloc] initWithFrame:CGRectMake( 7.0, 5.0, 300.0, 30.0 )];
name.tag = 1000;
[cell.contentView addSubview:name];
}
UILabel* name = (UILabel*)[cell.contentView viewWithTag:1000];
[name setText:[self.entriesArray objectAtIndex:indexPath.row]];
//Check to see if current person is a Parent or Child
NSString *class = [self.database getCellDataWithMembership:[self.MembershipArray objectAtIndex:indexPath.row] andColIndex:4];
if([class isEqualToString:#"CHILD"])
{
name.textColor = [UIColor colorWithRed:25.0f/255.0f green:111.0f/255.0f blue:45.0f/255.0f alpha:1.0f];
name.font = [UIFont fontWithName:#"Helvetica-Bold" size:17.0];
}
return cell;
}
You can set uilabels by using ios6/7 delta shown is size inspector .firstly set your total view for ios7 by changing values x,y,width,height and then change value in ios6/7 delta to make it for ios6 .Hope you get
you may change the this code.
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; -> UITableViewCell *cell = nil;

UITableView not scrolling smooth due to removeFromSuperview

What makes scrolling so choppy on the UITableView? In my mind following code is a culprit. I am having very hard time to replace this logic with something other.
for (UIView *view in cell.contentView.subviews) {
[view removeFromSuperview]; }
This is what I am doing.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
for (UIView *view in cell.contentView.subviews) {
[view removeFromSuperview];
}
BGMArticleAbstract *articleAbstract = [self.section.articleAbstracts objectAtIndex:indexPath.row];
[cell.contentView addSubview:[self getHedlineFromArticleAbstract:articleAbstract]];
[cell.contentView addSubview:[self getThumbnailImageFromArticleAbstract:articleAbstract]];
[cell.contentView addSubview:[self getAbstractParaFromArticleAbstract:articleAbstract]];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell; }
I am doing, addSubview to contentview because I am creating a dynamic cell height. Is there any way I can make this scroll view work smooth ? Thank you for your help.
You should design your cell as you need it. Add labels and whatever you need to the cell, and then change the content of these already available subviews.
If you need to display an image, add once an UIImageView to the cell and only change the image property of it. Same for text fields and so on.
The way you do it makes the built-in cache useless, because you regenerate all subviews again and again..
To boost the performance even more, you can do the drawing of the cell by yourself.
Apple has a quite nice example project:
http://developer.apple.com/library/ios/#samplecode/AdvancedTableViewCells/Introduction/Intro.html
You are right that the problem is caused by how you return cells. The correct pattern is as follows...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// see if cell contains our image views. A reused cell will, but a new cell won't
UIImageView *imageViewA = (UIImageView *)[cell viewWithTag:32];
UIImageView *imageViewB = (UIImageView *)[cell viewWithTag:33];
UIImageView *imageViewC = (UIImageView *)[cell viewWithTag:34];
if (!imageViewA) {
// the cell must be new, so create it's image views
// you should be able to borrow most of this code from your getHeadline/thumbnail/etc methods.
// the good news is that this relatively expensive code runs only for new
// cells and there are only a few of those - only enough to fill the visible frame
imageViewA = [[UIImageView alloc] initWithFrame:CGRectMake(/* frame it here */)];
[cell.contentView addSubview:imageViewA];
imageViewA.tag = 32;
imageViewB = [[UIImageView alloc] initWithFrame:CGRectMake(/* frame it here */)];
[cell.contentView addSubview:imageViewB];
imageViewB.tag = 33;
imageViewC = [[UIImageView alloc] initWithFrame:CGRectMake(/* frame it here */)];
[cell.contentView addSubview:imageViewC;
imageViewC.tag = 34;
// this too, need only be done upon creation
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
// now, whether it's a new cell or a reused cell, we have image views
BGMArticleAbstract *articleAbstract = [self.section.articleAbstracts objectAtIndex:indexPath.row];
// change your methods getHeadline... getThumbnail... etc to answer UIImages
// not UIImageViews, which are setup only for new cells
imageViewA.image = [self getHedlineFromArticleAbstract:articleAbstract]];
imageViewB.image = [self getThumbnailImageFromArticleAbstract:articleAbstract]];
imageViewC.image = [self getAbstractParaFromArticleAbstract:articleAbstract]];
// as a side note, once you get these methods returning images (more like model objects)
// rather than image views (view objects) they might be more appropriately placed
// in the BGMArticleAbstract class rather than the view controller
return cell;
}

UITableViewCell image alignment to the right, possible?

when adding an image to table cell, as default it goes to left:
cell.imageView.image = [UIImage imageNamed:[arrImages objectAtIndex:indexPath.row]];
how can I change it that every image in the UITableViewCell will go automaticlly to the right and the textLabel will be 10px to the left of the image.
Thanks alot!
Another way is to create a custom cell and override layoutSubviews method.
#interface CustomCell : UITableViewCell
#end
#implementation CustomCell
- (void)layoutSubviews
{
[super layoutSubviews];
// grab bound for contentView
CGRect contentViewBound = self.contentView.bounds;
// grab the frame for the imageView
CGRect imageViewFrame = self.imageView.frame;
// change x position
imageViewFrame.origin.x = contentViewBound.size.width - imageViewFrame.size.width;
// assign the new frame
self.imageView.frame = imageViewFrame;
}
#end
Rembember that in cellForRowAtIndexPath you need to create and reuse CustomCell and not UITableViewCell.
Hope it helps.
Edit
#import "CustomCell.h"
// other code here...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomCell";
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
return cell;
}
Find the solution here code.
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"foo.png"]];
cell.accessoryView = imageView;
For your reference.
UITableViewCell with image on the right?
try this:
cell.imageView.frame = CGRectMake(cell.frame.size.width - cell.imageView.frame.size.width, cell.imageView.frame.origin.y, cell.imageView.frame.size.width, cell.imageView.frame.size.height);
[cell.yourTexLabel sizeToFit];
cell.yourTexLabel.frame = CGRectMake(cell.imageView.origin.x - cell.yourTexLabel.frame.size.width - 10, cell.yourTexLabel.frame.origin.y, cell.yourTexLabel.frame.size.width, cell.yourTexLabel.frame.size.height);
Found a better answer from #TomSwift here https://stackoverflow.com/a/31616694/1884707
cell.contentView.transform = CGAffineTransformMakeScale(-1,1);
cell.imageView.transform = CGAffineTransformMakeScale(-1,1);
cell.textLabel.transform = CGAffineTransformMakeScale(-1,1);
cell.textLabel.textAlignment = NSTextAlignmentRight;
By applying a transform on the contentView you can place the imageView on the right.
in swift3 and swift4, we can use this:
cell.accessoryView = UIImageView(image:UIImage(named:"imageNmae")!)
One solution is to use a custom UITableViewCell. The steps are:
Create a new objective-C class that is a subclass of UITableViewCell, for example LabeledImageTableViewCell. Declare ivars and properties for a UILabel and a UIImageView.
In Interface Builder, set the content of the UITableView to Dynamic Prototypes. Drag a UIImageView and a UILabel to a table view cell and position them. Set the cell's class to LabeledImageTableViewCell. Connect the outlets of the cell to the UILabel & UIImageView objects of LabeledImageTableViewCell.
In the delegate for UITableView (usually a UITableViewController, sometimes a UIViewController) implement the datasource methods, for example:
//#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return (NSInteger)[rowData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"tvcLabeledImage";
LabeledImageTableViewCell *cell = (LabeledImageTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[LNCCorrelationInfoTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.myImage = [UIImage imageNamed:#"imageForThisRow.png"];
cell.myLabel = "imageForThisRow";
return cell;
}
Also, check out the Apple videos from WWDC 2011, UITableView Changes, Tips & Tricks and Introducing Interface Builder Storyboarding (Login required: https://developer.apple.com/videos/wwdc/2011/.)

iOS 4.2: Subview in Tableview acting weird

I'm semi new to developing for iOS.
And when i try to customize a tableview cell to put an image under the description text, it works, until i scroll, then it gets all messed up.
When i scroll down, then back up, the image is in a cell it shouldn't be in. :/
I deleted the code because it wasn't working. But what i was doing was creating a UIView with a frame, with a UIImageView inside it. Then i add it to cell.contentView.
Which works, until i scroll.
So could someone please help :/
Edit: here is what it looks like for anyone interested, i got it working. (Thanks Jonathan)
#define LEVEL_TAG 1
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UIImageView *showLevel;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
showLevel = [[[UIImageView alloc] initWithFrame: CGRectMake(65, 50, 0, 11)] autorelease];
showLevel.tag = LEVEL_TAG;
[cell.contentView addSubview: showLevel];
} else {
showLevel = (UIImageView *)[cell.contentView viewWithTag:LEVEL_TAG];
}
NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
NSArray *levelArray = [dictionary objectForKey:#"Levels"];
NSString *levelValue = [levelArray objectAtIndex:indexPath.row];
UIImage *levelImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource: levelValue ofType:#"png"]];
CGImageRef starImage = levelImage.CGImage;
NSUInteger levelWidth = CGImageGetWidth(starImage);
showLevel.frame = CGRectMake(65, 50, levelWidth, 11);
showLevel.image = levelImage;
return cell;
}
It's because of the way the tableView reuses old cells, rather than creating new ones every time the user scrolls, which would make everything slower, and less efficient.
Have a look at Listing 5-3 on the Apple Documentation about customizing UITableViewCells, it shows you how to set up the cell, within the if statement where the cell is actually created, and not where the cell could have been reused.

Fixing image-view in UITableViewCell in iPhone?

I have a table-cell which has all default settings. And I put an image on the ImageView on the left, and I put some random text on TextLabel.
and I adjust cell's height using below method.
(CGFloat)tableView:(UITableView *) tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath
The problem is the left ImageView's frame size is different depend on the cell's height.
See the below image, the 4th cell's height is bigger than others and it's image is slightly right compare to other images.
What causes this and how can I solve this probelm??
-- added
This is my cellForRowAtIndexPath method.
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefaultt reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.numberOfLines = 0;
cell.textLabel.text = [self GetSelectionForRowAtIndexPath:indexPath];
NSString *path = [[NSBundle mainBundle] pathForResource:#"icon_notSelected" ofType:#"png"];
UIImage *theImage = [UIImage imageWithContentsOfFile:path];
cell.imageView.image = theImage;
This shows the imageView does not get bigger even if I put more height on the cell.
UIImage *image = [UIImage imageNamed:#"your_image.png"];
cell.imageView.image = image;
put this code in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
If will show the image in each cell of the table in same line.
You can do it only by Code. No need of IB for this.
Give the imageview a fixed frame and then center it vertically in the cell.
Something along these lines:
imageview.frame = CGRectMake(5, floor(cellHeight/2)-20, 40, 40);
Or just use the imageview property of UITableViewCell.