Why are the button background images strecthing? - ios

I have an app in which I have a side menu. In the side menu, the rest of the buttons appear fine but two buttons are stretching weirdly. screenshot attached.
This is how I am setting button images.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
RearViewTableViewCell *cell = [self.tableViewSideMenu dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if(cell == nil)
{
NSArray *cellView = [[NSBundle mainBundle] loadNibNamed:#"RearViewTableViewCell" owner:nil options:nil];
cell = (RearViewTableViewCell *)[cellView objectAtIndex:0];
cell.btnItemSelector.tag = indexPath.row;
[cell.btnItemSelector setBackgroundImage:[UIImage imageNamed:[buttonUnselect objectAtIndex:indexPath.row]] forState:UIControlStateNormal];
[cell.btnItemSelector setBackgroundImage:[UIImage imageNamed:[buttonSelect objectAtIndex:indexPath.row]] forState:UIControlStateHighlighted];
[cell.btnItemSelector addTarget:self action:#selector(btnMenuItemTapped:) forControlEvents:UIControlEventTouchUpInside];
cell.selectionStyle =UITableViewCellSelectionStyleNone;
}
return cell;
}
I am new to adaptive layout. Is it causing issues? On iphone 5s it runs fine but on iphone 6 it is depicting this behaviour. I have added only one constraint (width) to the tableview. The uitableviewcell (custom) i am using here has all the regular constraints of leading space, vertical space, center alignment etc. Any thoughts?
Update: i set the bg color to red and it turns out the two buttons in questions are being resized to much smaller & probably wider view. Why would that happen?

I would recommend you, to use button.image instead of button.backgroundImage. It looks like setting a backgroundImage to a UIButton can't handle the contentMode of your image because it always stretches the UIImage to the same size as the UIButton.
If you add the UIImage just on the property image you can change position of the image inside the UIButton by changing the contentEdgeInsets manually or inside the Interface Builder.
Just in case you want to set an UIImage as well as a NSString for your UIButton, I would create an own class of type UIButton with an UILabel and UIImage and layout them inside the Interface Builder.

According to the "UIKit User Interface Catalog", "Buttons" chapter, "Images" section:
The Background (currentBackgroundImage) field allows you to specify an image to appear behind button content and fill the entire frame of the button. The image you specify will stretch to fill the button if it is too small. It will be cropped if it is too large.
Thus, you need to set size of all background images to be equal to button's size.
Update Or make sure that your constraints are configured so that button size is correct.

Alright guys I don't quite why this solved the problem but it did and here goes.
1) I used setImage rather than setBackgroundImage.
2) I removed the suffix .png from the images name.
3) I cleaned the project and reset the simulator.
4) It worked.
It was probably the cache still had previous images containing just ? and i symbol which made the button resize as per size of the image but I can't be sure. If anyone else can post a better explanation of this I'd mark it as Answer

Related

iOS Images display abnormally in UITableView

I'm trying to put some images into a UITableView, so I put an Image View into the UITableViewCell and set it aspect fit.
After starting the simulator, it appears to be right, but when I click at one cell or scroll out the originally hidden cells(may be the reused ones), the image breaks the limit of the image view's setting and destroys the layout.
the middle picture is normal, but the upper or lower one is out of shape.
cellForRowAtIndexPath function as follow:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ShangbaoOriginCell";
ShangbaoOriginCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.newsSampleLabel.text = [NSString stringWithFormat:NSLocalizedString(#"Cell %d",), indexPath.row];
cell.cellView.contentMode = UIViewContentModeScaleAspectFit;
cell.imageView.contentMode = UIViewContentModeScaleAspectFit;
cell.imageView.image = self.tableItems[indexPath.row];
return cell;
}
whether cell.imageView.contentMode is set or not, this problem exists.
I've added bg color, ImageView is black, Content View is blue, Cell is green.
So I saw incredible thing, the (table view) cells become not wide enough (you can see from the narrow gap between two pictures). Which is set properly in story board that the cell's width cover the whole screen.
I forgot to say that this table view is in a tabbed application, but I think this doesn't matter . And this time I have added constraints to the image view, but in vain.

Difficulty changing the size of image in UITableViewCell

Problem:
I use the following code inside the method cellForRowAtIndexPath to set the size of the image for the cell, yet at runtime the image gets blown up to the maximum height and width that the table row will allow.
UIImage *_image = [imageDictionary objectForKey:#"image"]; // Get image data
[_image drawInRect:CGRectMake(0,0,50,50)]; // set size
[cell.imageView setImage: _image]; // assign image to cell
cell.imageView.frame = CGRectMake(cell.imageView.frame.origin.x,cell.imageView.frame.origin.y,50,50);
return cell;
Question: Is there a more robust method of controlling the size of the image in a UITableViewCell? The approach I'm taking comes from several other posts but for some reason its being ignored in my code.
Side-note: I'm using Xcode 5 and developing on an iOS 7 platform.
Use UITableViewCell contentView .
The content view of a UITableViewCell object is the default superview for content displayed by the cell. If you want to customize cells by simply adding additional views, you should add them to the content view so they will be positioned appropriately as the cell transitions into and out of editing mode.
Example:
UIImage *_image = [imageDictionary objectForKey:#"image"]; // Get image data
[_image drawInRect:CGRectMake(0,0,50,50)]; // set size
UIImageView *imageView = [[UIImageView alloc] initWithImage: _image];
[imageView setFrame:yourFrame];
[cell.contentView addSubview:imageView];
This doesn't answer the question but your underlying problem is your approach. You should be customizing your cells by subclassing UITableViewCell. To add to that it's a lot easier to manipulate cell contents as views than to play around with the default picture and text label they give you. To carify, the contents of the cell sit on a view known as contentView accessible as cell.contentView. You can add text labels, buttons, and images as subviews to any location with any size you want the same way you would do with any view added as a subview.

What is the best way to do a page like the album page of iTunes?

I am trying to imitate the album page of iTunes using uitableviewcontroller, but then I think I might have been going in a wrong direction.
My plan is to do something in tableView: cellForRowAtIndexPath:. When indexPath.row == 0, I do the description of album (i.e. the upper part), else I do the description of songs (i.e. the lower part).
Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (indexPath.row == 0 ){
CGRect imageFrame = CGRectMake(5, 5, 69, 69);
UIImageView *coverFram = [[UIImageView alloc] initWithFrame:imageFrame];
NSString *imagePath = [[NSBundle mainBundle] pathForResource:#"cover" ofType:#"jpg"];
coverFram.image = [[UIImage alloc] initWithContentsOfFile:imagePath];
[cell.contentView addSubview:coverFram];
}else{
NSInteger adjustedIndexPathRow = indexPath.row - 1;
cell.textLabel.text = [self.cellRow objectAtIndex:adjustedIndexPathRow];
}
return cell;
}
There are two places That I don't have simple idea to implement it:
Firstly, in the album page of iTunes, there is a segmented control (see the image). When I press other segment, say "review", the upper part remains there while the whole lower parts has been changed.
Secondly, I don't know how to close the gap show in the image (circle in red).
So, I think may be there are some other smarter(or easier) way to do it. Like, is it possible to divide the page into two part: then the do the upper part by a view; and do the lower part by a table view? (just my guess)
Please advice. Thank you.
Your assumption is perfectly right. That is the way to go in your case. Refer to the following image.
Construct the top part of the view containing the album cover, it's details and the segmented control. The bottom part of the view will be reserved for views which will be loaded by instantiating other view controllers based on selected segment.
You can remove this white space by two way,
in ios 7 set separatorInset in UITableView
1) set by Pragmatically
table.separatorInset=UIEdgeInsetsZero;
2) Or u can do this way
Your guess is right. The easier way(probably the right way) is to divide the entire view into two parts. The upper part consist of an image view, segmented control whatever else. and bottom part can have a table view. Now depending upon the selection of a segment in the segmented control you can easly reload the table view with appropraite content

Why does a UIImageView get resized when assigning a new image in iOS 6?

An application contains a UITableView containing a custom UITableViewCell. The cell in turn contains a UIImageView.
The problem is that setting the image in cellForRowAtIndexPath makes the image take up the entire UITableViewCell area:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"CustomCell"];
NSString *path = [[NSBundle mainBundle] pathForResource:#"bigrect" ofType:#"png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:path];
cell.imageView.image = image;
return cell;
}
In IB, 'Aspect Fit' has been selected as the mode, but changing this field has no apparent effect on the result.
However, when the image is set from IB, with no call to cell.imageView.image = image in my code, the result is exactly what I'd like to see. The image stays within the bounds I've defined for the UIImageView in IB and does not attempt to scale to fit the entire vertical height of the UITableViewCell:
The image I'm using is 1307x309 pixels, in case that's important. Tests were run on iOS 6.1 simulator.
I noticed this from the UIIMageView Documentation:
In iOS 6 and later, if you assign a value to this view’s restorationIdentifier property, it attempts to preserve the frame of the displayed image. Specifically, the class preserves the values of the bounds, center, and transform properties of the view and the anchorPoint property of the underlying layer. During restoration, the image view restores these values so that the image appears exactly as before. For more information about how state preservation and restoration works, see iOS App Programming Guide.
However, nothing here or elsewhere in the documentation I could find solved the problem. Adding a "Restoration ID" of "Foo" to the UIImageView in IB under 'Identity' did not change the behavior. Unchecking 'Use Autolayout' also did not change the behavior.
How can I prevent iOS from resizing the UIImageView in a UITableViewCell when setting the image?
It turns out that UITableViewCell apparently already has a property called "imageView" that covers the entire background of the cell. Setting the image property of this imageView object sets the background image, not the image I was interested in.
Changing my method to the following while ensuring that CustomCell has a "myImageView" property fixed the problem:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"CustomCell"];
NSString *path = [[NSBundle mainBundle] pathForResource:#"bigrect" ofType:#"png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:path];
cell.myImageView.image = image;
return cell;
}
This SO answer to a slightly different question pointed me in the right direction.

I'm trying to center Image in custom UITableViewCell but it sticks to left side no matter what

I've created a cell prototype in the Xcode 4.2 storyboard that consists of an image view in the center of the cell and some text below it but when I run the app the image is always moved to the left side. I've made the cell extra tall to ensure it wasn't a height issue. I also played with the autosize settings.
So far nothing I've tried will make the image move to the center of the tableViewCell when the code is actually running.
Note, this is done purely in the StoryBoard. The only code I've written is code to create a list of objects with a "name" and "image" and the minimum table view source/delegate code so I can fill in two entries in the table.
I suppose you use something like :
static NSString *identifier = #"ImageRecordCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
UILabel *label = (UILabel*)[cell viewWithTag:1];
UIImageView *pic = (UIImageView*)[cell viewWithTag:2];
label.text = #"test";
pic.image = [UIImage imageNamed:#"Default.png"];
return cell;
be sure not to set tag to zero
I had something that works just fine in iOS 4.x, but was doing something similar to what you describe in the iOS 5 simulator, moving a UIImageView down by about 120px for no apparent reason. Setting the Autosizing settings to have the top position outside the box frozen (if that makes sense) fixed the issue—though it was not at all clear to me why this behavior had changed in iOS 5 vs. previously.

Resources