Positioning the imageView of a UITableViewCell
Asked Answered
O

7

17

In every UITableViewCell of a UITableView I'm placing an image in its imageView. However, if I increase the height of a cell using tableView:heightForRowAtIndexPath: to accomodate more text, I've found that:

  1. The image is center-aligned vertically.
  2. The left margin of the image increases. This pushes the text right so its left margin is no longer aligned with the text in the cells above and below.

I'd like the image to be top-aligned vertically, so that it is in the upper-left corner of the cell (like the first cell in the image below) and not have its left margin increased (so that the left margin of the text in the second cell aligns with the text in the first cell).

Altering the frame, center, etc. of the imageView seems to have no affect. Any ideas? Thanks...

(I have an image of the problem, but SO won't let me post an image yet because I'm a noob with less than 10 reputation. Grrr...)

Overweight answered 17/11, 2010 at 20:20 Comment(0)
H
46

You need to subclass UITableViewCell and override layoutSubviews, as follows:

- (void) layoutSubviews
{   
    [super layoutSubviews];

    self.imageView.frame = CGRectMake( 10, 10, 50, 50 ); // your positioning here
}

In your cellForRowAtIndexPath: method, be sure to return an instance of your new cell type.

Husking answered 17/11, 2010 at 20:51 Comment(3)
Can you explain where this approach is explained in the Apple docs? For instance, why can't you do imageView.frame = CGRectMake(10,10,50,50)? (this doesn't work, but I can't figure out why it doesn't work. It seems like it should)Culicid
It doesn't work because the superclass does the layout in its implementation of layoutSubviews. By calling [super layoutSubviews] the superclas will position the imaveView and any other labels/icons, and then you can reposition them.Husking
It might help to understand that a UITableViewCell is just a UIView, that also manages & positions these subview labels and images for you "for free". You could easily take over drawing the entire cell and do anything you want (e.g. bounce around a ball). At some point in the customization curve, that's just what you should do. The kind of subclassing Tom suggests is a small step along that path.Webfoot
A
6

The moment you think you need to adjust sizes or positions of items in the default styles, is the time you need to think about creating a custom cell with your own items sized and positioned the way you want them to be. This is why you can create custom cells. :)

Arise answered 17/11, 2010 at 20:36 Comment(2)
Right, you should mess with the cell's "built-in" properties appearance.Dexamyl
Rivera: You should?Czardom
L
4

Another way (works in iOS 6) is to create a UIImageView and add it to the cell as a subview

 UIImageView *yourImageView = [[UIImageView alloc] initWithFrame:CGRectMake(x,y,20,20)];

[yourImageView setImage:[UIImage imageNamed:[imagesArray objectAtIndex:indexPath.row]]]; //You can have an Array with the name of 

[yourcell.contentView addSubview:yourImageView]; //add the imageView as a subview
Lifeless answered 21/3, 2013 at 22:21 Comment(1)
Do not add custom view on UITableViewCell directly. Instead, place them under contentView object. This is how the cell class is designed. (see Apple documentation) If you place view directly on the cell, it may cause unexpected result.Hyksos
V
1

A really useful function you might not have tried (in UITableViewDelegate) is tableView:willDisplayCell:forRowAtIndexPath:. It is called immediately before a cell is displayed and its purpose is to enable you to do things to the layout without the OS modifying it again before display. Effectively you have total control. I've used it for changing fonts in cells but you can iterate the cell's subviews and modify their frames too.

Still I agree you are at the point where it is time to look into custom cells and stop fighting the OS. It isn't hard to do and Apple gives a good example in Table View Programming Guide for iOS.

Vassalage answered 17/11, 2010 at 21:16 Comment(1)
I tried to do this but it did still reposition the image in the middle of my table view cell: cell.imageView.frame = CGRectMake( 10, 10, 50, 50 );. Do you maybe have an idea why?Almira
F
1

Swift 4 variation of TomSwift's solution (which worked for me nicely):

override public func layoutSubviews() {
        super.layoutSubviews()
        imageView?.frame = CGRect( x: 16, y: 9, width: imageView!.intrinsicContentSize.width, height:  imageView!.intrinsicContentSize.height)
    }
Freese answered 11/1, 2019 at 7:36 Comment(0)
T
0

You can create a custom cell and place the objects where you need them to be as well as setting the auto mask values.

Theseus answered 17/11, 2010 at 20:28 Comment(0)
S
0
class CustomCell: UITableViewCell {
    override public func layoutSubviews() {
        super.layoutSubviews()
        imageView?.frame = CGRect( x: 20, y: 10, width: imageView!.intrinsicContentSize.width, height:  imageView!.intrinsicContentSize.height)
    }
}

Use CustomCell in your storyboard insted of UITableViewCell.

enter image description here

Also return CustomCell instance from datasource as

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell: CustomCell = tableView.dequeueReusableCell(withIdentifier: "revcell", for: indexPath) as? CustomCell
        {
            //code
            return cell
        }
        return UITableViewCell()
    } 
Sig answered 21/10, 2021 at 4:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.