简体   繁体   English

如何在自定义单元格中使UIImage的宽度等于视图的宽度和比例高度

[英]How to make UIImage width be equal to view's width and proportional height inside a custom cell

I'm trying to download an image and place it in a custom cell, which contains the UIImage and UITextView. 我正在尝试下载图像并将其放在自定义单元格中,该单元格包含UIImage和UITextView。 I need it to equal to the width of the screen and have the height proportional, similar to this question but I am not sure how to use this convert the answer to use custom table cells. 我需要它等于屏幕的宽度并与高度成比例,类似于此问题,但是我不确定如何使用此转换答案以使用自定义表格单元格。 While trying to set the image width and height in tableView:cellForRowAt calling the cell.storedImage.frame.width and height Xcode says it is only a get-only property. 尝试在tableView:cellForRowAt设置图像的宽度和高度时,调用cell.storedImage.frame.widthheight Xcode表示这只是一个仅get-only属性。 This is what I thought would work 我认为这是可行的

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if tableData[indexPath.row]["Image"] != nil {
        let cell = tableView.dequeueReusableCell(withIdentifier: "imageNotesData", for: indexPath) as! ImageNotesCell
        cell.notes.delegate = self
        cell.notes.tag = indexPath.row
        cell.notes.text = tableData[indexPath.row]["Notes"] as! String
        guard let imageFirebasePath = tableData[indexPath.row]["Image"] else {
            return cell }
        let pathReference = Storage.storage().reference(withPath: imageFirebasePath as! String)
        pathReference.getData(maxSize: 1 * 1614 * 1614) { data, error in
            if let error = error {
                print(error)
            } else {
                //let image = UIImage(data: data!)
                //cell.storedImage.image = image


                let containerView = UIView(frame: CGRect(x:0,y:0,width:self.view.frame.width
                    ,height:500))
                let imageView = UIImageView()
                if let image = UIImage(data:data!) {
                    let ratio = image.size.width / image.size.height
                    if containerView.frame.width > containerView.frame.height {
                        let newHeight = containerView.frame.width / ratio
                        imageView.frame.size = CGSize(width: containerView.frame.width, height: newHeight)
                        cell.storedImage.frame.height = newHeight
                    }
                    else{
                        let newWidth = containerView.frame.height * ratio
                        imageView.frame.size = CGSize(width: newWidth, height: containerView.frame.height)
                        cell.storedImage.frame.width = newWidth
                    }
                }
                let image = UIImage(data: data!)
                cell.storedImage.image = image
            }
        }
        return cell
    }
    else {
        let cell = tableView.dequeueReusableCell(withIdentifier: "notesData", for: indexPath) as! NotesCell
        //let noteString = tableData[indexPath.row]["Notes"] as! String
        cell.notes.text = tableData[indexPath.row]["Notes"] as! String
        cell.notes.delegate = self
        cell.notes.tag = indexPath.row
        return cell
    }
}

I have also tried using auto layout to fix the problem by having the a text view below it have two different bottom margin constraints but it still doesn't look right. 我还尝试过使用自动布局来解决此问题,方法是在其下方的文本视图具有两个不同的底部边距约束,但看起来仍然不合适。 This is the closet I gotten with auto layout constraints. 这是我在自动布局限制条件下获得的壁橱。 Currently the image view has 0 space constraints on every side to super view 当前,图像视图的每一侧都具有0个空间限制以进行超级视图

在此处输入图片说明

I assume that the code snippet is the path I should go with but I am not sure how to make the image to look right. 我假定代码段是我应该使用的路径,但是我不确定如何使图像看起来正确。

You could still use dynamic constraints, once you get your image you set the aspect ratio constraint for your uiimageview, but it would probably end up being more of a hassle to do. 您仍然可以使用动态约束,一旦获得图像,就为uiimageview设置了宽高比约束,但最终可能会很麻烦。

you can also do this with the frame directly, but you'll need to make a new CGRect for the frame, you can't simply edit it's width or height directly. 您也可以直接对框架执行此操作,但是您需要为框架创建一个新的CGRect,不能简单地直接编辑其宽度或高度。

you should also set the height of the row to be correct 您还应该将行的高度设置为正确的

tableView(_:heightForRowAt:) 的tableView(_:heightForRowAt :)

I'm assuming you've got your ImageNotesCell has it's default size set in the initialiser with notes some kind of uitextfield/uitextview inherited class and storedImage simply an image 我假设您已经在初始化程序中设置了ImageNotesCell的默认大小,并注意到了某种uitextfield / uitextview继承的类,而storedImage只是一个图像

class ImageNotesCell: UITableViewCell {
  func setImage(_ image: UIImage) {
    let previousNotesFrame = notes.frame
    let ratio = image.size.height / image.size.width
    storedImage.image = image
    let newImageFrame = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.width * ratio)
    let newNotesFrame = CGRect(x: 0, y: newImageFrame.size.height + your_spacing_here, width: frame.size.width, height: previousNotesFrame.size.height)
    frame = CGRect(x: 0, y: 0, width: frame.size.width, height: newImageFrame.size.height + your_spacing_here + newNotesFrame.size.height)
    storedImage.frame = newImageFrame
    notes.frame = newNotesFrame
  }
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if tableData[indexPath.row]["Image"] != nil {
        let cell = tableView.dequeueReusableCell(withIdentifier: "imageNotesData", for: indexPath) as! ImageNotesCell
        cell.notes.delegate = self
        cell.notes.tag = indexPath.row
        cell.notes.text = tableData[indexPath.row]["Notes"] as! String
        guard let imageFirebasePath = tableData[indexPath.row]["Image"] else {
            return cell }
        let pathReference = Storage.storage().reference(withPath: imageFirebasePath as! String)
        pathReference.getData(maxSize: 1 * 1614 * 1614) { data, error in
            if let error = error {
                print(error)
            } else {
                let image = UIImage(data: data!)
                cell.setImage(image)
            }
        }
        return cell
    }
    else {
        let cell = tableView.dequeueReusableCell(withIdentifier: "notesData", for: indexPath) as! NotesCell
        //let noteString = tableData[indexPath.row]["Notes"] as! String
        cell.notes.text = tableData[indexPath.row]["Notes"] as! String
        cell.notes.delegate = self
        cell.notes.tag = indexPath.row
        return cell
    }
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if tableData[indexPath.row]["Image"] != nil {
        guard let imageFirebasePath = tableData[indexPath.row]["Image"] else {
            return your_default_height_here }
        let pathReference = Storage.storage().reference(withPath: imageFirebasePath as! String)
        pathReference.getData(maxSize: 1 * 1614 * 1614) { data, error in
            if let error = error {
                print(error)
            } else {
                let image = UIImage(data: data!)
                let ratio = image.size.height / image.size.width
                return (tableView.frame.size.width * ratio) + your_spacing_value_here + your_notes_height_here
            }
        }
    } else {
        return your_notes_cell_height_here
    }
}

I tested the logic on a custom UITableViewCell I made and with 3 different image dimensions and notes. 我在制作的自定义UITableViewCell上测试了逻辑,并使用了3种不同的图像尺寸和注释。 it fills up the screen. 它填满了屏幕。 but since I don't know you ImageNotesCell class among other things I'll leave it to you to adapt but here's the gist of it: 但是由于我不认识您ImageNotesCell类,因此我将让您适应它,但这是要点:

ImageNotesCell class: ImageNotesCell类:

  • add a function to set an image to the cell which will in turn update the cell, the note and image's frames 添加一个功能以将图像设置到单元格,这将依次更新单元格,注释和图像的框架

Controller class: 控制器类:

  • cellForRow: initialise your cell, set it up as usual for the notes part and for when there aren't any images, call the setImage method, return your cell cellForRow:初始化您的单元格,照常将其设置为注释部分,如果没有图像,则调用setImage方法,返回您的单元格
  • heightForRow: return the usual height for when there isn't an image to load, get your image, calculate it's height/width ratio, multiply that by the tableView width, add the value for your spacing, add the height of your notes heightForRow:返回没有图像加载时的常规高度,获取图像,计算其高/宽比,将其乘以tableView宽度,添加间距值,添加便笺的高度

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM