I'm trying to download an image and place it in a custom cell, which contains the UIImage and 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. 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
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.
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.
you should also set the height of the row to be correct
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
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. 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 class:
Controller class:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.