How do I make UITableViewCell's ImageView a fixed size even when the image is smaller

后端 未结 16 2534
不思量自难忘°
不思量自难忘° 2020-11-27 10:27

I have a bunch of images I am using for cell\'s image views, they are all no bigger than 50x50. e.g. 40x50, 50x32, 20x37 .....

When I load the table view, the tex

16条回答
  •  感动是毒
    2020-11-27 10:51

    I had the same problem. Thank you to everyone else who answered - I was able to get a solution together using parts of several of these answers.

    My solution is using swift 5

    The problem that we are trying to solve is that we may have images with different aspect ratios in our TableViewCells but we want them to render with consistent widths. The images should, of course, render with no distortion and fill the entire space. In my case, I was fine with some "cropping" of tall, skinny images, so I used the content mode .scaleAspectFill

    To do this, I created a custom subclass of UITableViewCell. In my case, I named it StoryTableViewCell. The entire class is pasted below, with comments inline.

    This approach worked for me when also using a custom Accessory View and long text labels. Here's an image of the final result:

    Rendered Table View with consistent image width

    class StoryTableViewCell: UITableViewCell {
    
        override func layoutSubviews() {
            super.layoutSubviews()
    
            // ==== Step 1 ====
            // ensure we have an image
            guard let imageView = self.imageView else {return}
    
            // create a variable for the desired image width
            let desiredWidth:CGFloat = 70;
    
            // get the width of the image currently rendered in the cell
            let currentImageWidth = imageView.frame.size.width;
    
            // grab the width of the entire cell's contents, to be used later
            let contentWidth = self.contentView.bounds.width
    
            // ==== Step 2 ====
            // only update the image's width if the current image width isn't what we want it to be
            if (currentImageWidth != desiredWidth) {
                //calculate the difference in width
                let widthDifference = currentImageWidth - desiredWidth;
    
                // ==== Step 3 ====
                // Update the image's frame,
                // maintaining it's original x and y values, but with a new width
                self.imageView?.frame = CGRect(imageView.frame.origin.x,
                                               imageView.frame.origin.y,
                                               desiredWidth,
                                               imageView.frame.size.height);
    
                // ==== Step 4 ====
                // If there is a texst label, we want to move it's x position to
                // ensure it isn't overlapping with the image, and that it has proper spacing with the image
                if let textLabel = self.textLabel
                {
                    let originalFrame = self.textLabel?.frame
    
                    // the new X position for the label is just the original position,
                    // minus the difference in the image's width
                    let newX = textLabel.frame.origin.x - widthDifference
                    self.textLabel?.frame = CGRect(newX,
                                                   textLabel.frame.origin.y,
                                                   contentWidth - newX,
                                                   textLabel.frame.size.height);
                    print("textLabel info: Original =\(originalFrame!)", "updated=\(self.textLabel!.frame)")
                }
    
                // ==== Step 4 ====
                // If there is a detail text label, do the same as step 3
                if let detailTextLabel = self.detailTextLabel {
                    let originalFrame = self.detailTextLabel?.frame
                    let newX = detailTextLabel.frame.origin.x-widthDifference
                    self.detailTextLabel?.frame = CGRect(x: newX,
                                                         y: detailTextLabel.frame.origin.y,
                                                         width: contentWidth - newX,
                                                         height: detailTextLabel.frame.size.height);
                    print("detailLabel info: Original =\(originalFrame!)", "updated=\(self.detailTextLabel!.frame)")
                }
    
                // ==== Step 5 ====
                // Set the image's content modoe to scaleAspectFill so it takes up the entire view, but doesn't get distorted
                self.imageView?.contentMode = .scaleAspectFill;
            }
        }
    }
    

提交回复
热议问题