Fixing wrong constraints when UITableViewCell is first loaded - swift

I have a tableview which I am loading images in, and setting constraints on the imageview in cellForRowAt via the following function:
func setImageConstraints(height: Double, width: Double) {
if (width > height) {
let ratio = self.photoView.frame.width / width
let newHeight = height * ratio
let newWidth = self.maxWidth
self.photoWidthConstraint.constant = newWidth
self.photoHeightConstraint.constant = newHeight
self.photoWidthConstraint.isActive = true
self.photoHeightConstraint.isActive = true
}
else {
let ratio = self.photoView.frame.height / height
let newHeight = self.maxHeight
let newWidth = width * ratio
self.photoWidthConstraint.constant = newWidth
self.photoHeightConstraint.constant = newHeight
self.photoWidthConstraint.isActive = true
self.photoHeightConstraint.isActive = true
}
}
The problem is, when the cell is first loaded the images are not the right heights/width, until the cell is scrolled out of view, and then back into view. I can't seem to figure out how to get this working when the cell is initially loaded though.

Set the constraints for the cell in the tableView:willDisplayCell:forRowAtIndexPath: method.
In the cellForRowAtIndexPath: method, the cell's frame isn't setup yet and the cell isn't yet added to the table view.

Related

Change Image view frame depending on picked image (from image picker) frame SWIFT

I have an image view where there is a set frame but when the user clicks it and changes the image (UIImagePickerController) then I somehow need the frame of the image view to change to the frame of the image.
When they click the choose button for their image, this is the code that I run.
itemImage.contentMode = .scaleAspectFit
self.itemImage.image = pickedImage as? UIImage
So the image comes out in the image view but i need some help finding a way to get the image view frame to change to the picked images frame.
This is what I mean by the frame not changing.
Thanks
first you should get AspectFitSize with these method :
public func getAspectFitFrame(from: CGSize, to: CGSize) -> (CGRect, CGFloat) {
let (hfactor, vfactor, factor) = getFactor(from: from, to: to)
let newWidth = to.width / factor
let newHeight = to.height / factor
var x: CGFloat = 0.0
var y: CGFloat = 0.0
if hfactor > vfactor {
y = (from.height - newHeight) / 2
} else {
x = (from.width - newWidth) / 2
}
return (CGRect(x: x, y: y, width: newWidth, height: newHeight), factor)
}
public func getFactor(from: CGSize, to: CGSize) -> (CGFloat, CGFloat, CGFloat) {
let hfactor = to.width / from.width
let vfactor = to.height / from.height
return (hfactor, vfactor, max(hfactor, vfactor))
}
after that you should modify your imageViewSize with newSize :
let (imageFitSize , _) = getAspectFitFrame(from : self.itemImage.frame.size , to : self.itemImage.image.size)
self.image.frame.size = imageFitSize.size
It looks to me that your imageView already has some constraints applied to it. I'd suggest applying size constraints to it.
// declare these at the top of the file so that the constraints can be removed when new images are selected
private var widthConstraint: NSLayoutConstraint?
private var heightConstraint: NSLayoutConstraint?
// remove old constraint
widthConstraint?.isActive = false
// fix the imageview width to that of the picked image
widthConstraint = itemImage.widthAnchor.constraint(equalToConstant: pickedImage.size.width)
widthConstraint?.isActive = true
heightConstraint?.isActive = false
heightConstraint = itemImage.heightAnchor.constraint(equalToConstant: pickedImage.size.height)
heightConstraint?.isActive = true

Adding UIButtons dynamically in UICollectionViewCell - Swift

Trying to show buttons dynamically in a UICollectionViewCell depends on data coming in array from api. Below is what trying to achieve:
This is so far what i have achieved using button, but i need multiple buttons means button next to "About us" then next until space there then move to next line and setting height of cell as per height of view in cell. Please guide how it can be achieved.
Below is my code:
var xPosition = cell.btnOptions.frame.origin.x
var yPosition = cell.btnOptions.frame.origin.y
var width = cell.btnOptions.frame.size.width
var height = cell.btnOptions.frame.size.height
if((arrOptions?.count ?? 0) > 0)
{
for i in 0..<arrOptions!.count
{
//
cell.btnOptions.tag = i
cell.btnOptions.layer.cornerRadius = 3.0
cell.btnOptions.frame = CGRect.init(x: xPosition, y: yPosition, width: width, height: height)
//
cell.btnOptions.setTitle(arrOptions?.objectAt(i).object(forKey: "title") as? String, for: .normal)
xPosition = width + width + 8
yPosition = height
}

How to set dynamic height of imageview in table cell based on downloaded image from url

I am using Kingfisher library to download image
cell.doseImg.kf.setImage(with: URL(string: imgUrl))
1.Set top,bottom and trilling constraints for the image.
2.add below code in viewDidLoad().
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 140
Add this line in heightForRowAt index table delegate after image download
if let image = doseImg.image {
let ratio = image.size.width / image.size.height
newHeight = (self.view.frame.width / ratio) + 107
}
return newHeight

UITableview with dynamic height cells & filling footer view

I am trying to make a UITableview with a footer view that fills the remaining empty space of the UITableview. However, the catch is that the cells have varying heights.
I am aware that, if the cells were all a static height, I could simply count how many cells there are and multiply that by the static height. Unfortunately, that won't work in this case.
Current solution:
Works for static height cells.
Does not work for dynamic height cells.
private func adjustFooterHeight() {
if data.count == 0 {
footerView.frame.size.height = tableView.bounds.height
}
else {
//I use data.count instead of (data.count - 1) as I have the extra hidden cell, as pictured in image 2.
let bottomFrame = tableView.rectForRow(at: IndexPath(row: data.count, section: 0))
let height = tableView.bounds.height - (bottomFrame.origin.y + bottomFrame.height - rowHeight)
footerView.frame.size.height = height < 0 ? 0 : height
tableView.reloadData()
}
}
Diagram of Intentions:
So I figured it out...
Here is the solution.
private func adjustFooterHeight() {
//Get content height & calculate new footer height.
let cells = self.tableView.visibleCells
var height: CGFloat = 0
for i in 0..<cells.count {
height += cells[i].frame.height
}
height = self.tableView.bounds.height - ceil(height)
//If the footer's new height is negative, we make it 0, since we don't need footer anymore.
height = height > 0 ? height : 0
//Create the footer
let footerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: height))
self.tableView.tableFooterView = footerView
}

How to reload/update UITableView after resizing a cell containing web view dynamically?

I have few sections in table view. One section has only one cell containing a UIWebView. When it got loaded with html, I update cell with correct height as follows:
func webViewDidFinishLoad(webView: UIWebView) {
var frame = webView.frame
frame.size.height = 1
webView.frame = frame
var fittingSize = webView.sizeThatFits(CGSizeZero)
fittingSize = fittingSize.height > CGFloat(100) ? fittingSize : CGSize(width: fittingSize.width, height: CGFloat(100))
frame.size = fittingSize
webView.frame = frame
let cellSize = fittingSize.height;
print(cellSize)
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, fittingSize.width + 7, fittingSize.height + 7)
parent?.reloadTable()
}
In Parent,
func reloadTable() {
//let t = self.numberOfSectionsInTableView(self.tableView)
//self.tableView.reloadData()
self.tableView.setNeedsLayout()
self.tableView.layoutIfNeeded()
//self.tableView.reloadSections(NSIndexSet(index: 4), withRowAnimation: .None)
}
There is an another section under the cell. I tried several ways to update body cell. It got updated but following section header doesn't got moved below with body cells adjusted height.
Now any suggestion please?
Thanks