Adjust Auto-Layout inside UITableViewCell - swift

So I am creating a forum. When a post includes an image I would like to keep the aspect ratio of the downloaded image while making the image's width constant at 75% of the cell's width.
I created an outlet for the imageHeightConstraint in my custom cell class and tried the code below in the cellForRowAtIndexPath method.
let newHeight = (image!.size.height/image!.size.width)*cell.uploadedImageView.frame.width
cell.imageHeightConstraint.constant = newHeight//Calculate the new height
The code above doesn't adjust the image size at all.
Currently I have the constraint for image width to be 75% of cell's width and height equal 200.
I also already have all the code to adjust the tableviewcell automatically depending on content and that is working fine.
Thanks for any help.

Try
if let image = image {
cell.image.heightAnchor.constraint(equalTo:cell.image.widthAnchor, multiplier: image.size.height/image.size.width).isActive = true
}
If you want to also limit the height to 200, then you can also add
cell.image.heightAnchor.constraint(lessThanOrEqualToConstant:200).isActive=true

Related

NSGridView custom view intrinsic size

I'm building a simple NSGridView, and want to have a custom NSView as each element of the grid. Eventually, each NSView will be a xib based label (NSTextField) centered in the NSView.
The problem I am having is with the intrinsic size of the NSView. I want to define the size of the NSView and have auto layout work based on that. I added this code to the custom view (labelView):
override var intrinsicContentSize: NSSize {
return NSSize(width:100, height:100);
};
And it is indeed called; but apparently ignored. As a test, I have on the same row some other labels, and the height for the row is always set to the largest of the row text heights (including the label in the custom view); but the length is set to the longest of column text fields, ignoring the label in the custom view. And anyway, I want to arbitrarily make the NSView a certain height and length, as I tried (but failed) to do with the intrinsicContentSize.
NSStackview seems to do the right thing; but NSGridView does not.
I can force the width of a particular column with
grid.column(at:0).width = 400;
but want I really want to do is define the size of the NSView, and let autolayout use that as a building block.
This strikes me as a conceptual error on my part, so if someone could explain these NSGridView-autolayout-NSView subtleties, I think many might benefit.
I was having the exact same issue, tried to use custom NSView's inside a NSGridView and couldn't get them to draw correctly. What finally worked for me was setting the following:
let gridSize = 5
let cellSize: CGFloat = 50
gridView.xPlacement = .fill // this was key part of the solution
gridView.yPlacement = .fill
for i in 0 ..< gridSize {
gridView.row(at: i).height = cellSize
gridView.column(at: i).width = cellSize
}
Note that I'm setting the size of each cell with the row height and column width of the NSGridView, and not using the NSView size, but this is the only way I got it working.

how can i set a dynamic height to collection view cell in swift?

HI everyone i'm looking for a working method that allows to dynamically set the height in my collectionViewCell because I tried various other answers without success.
My situation is pretty simple, I have a cell with an image, a UIlabel that displays username and a UILabel which contains some text. It's a common Comment cell for a post. My Screen
I tried this method but it doesn't work precisely because the height is too much compared to what is necessary
private func estimatedFrameForText(text: String) -> CGRect {
let size = CGSize(width: 270, height: 80)
let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
return NSString(string: text).boundingRect(with: size, options: options, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 17)], context: nil)
}
so my question is: there is a correct way to implement dynamic size on collection view cell like layout attribute wrap_content for Android?
UPDATE
I solved my problem using constraints and Automatic Estimated Size on Collection View. Setting up all constraints I forced the width of LABEl to be equal to the cell width and for the height I set the top and bottom spacing for the UILabel (with lines 0) to be equal to its content view (the one standard for the UiCollectionViewCell)
IT'S also important to set the size of the collection view cell to automatic
VIEW IMAGE

Rotating a UICollectionView leads to error

When I rotate the device with a UICollectionView I get an error:
the item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values.
I think that this mistake is within my UICollectionViewDelegateFlowLayout where I try to set the height
if UIApplication.shared.statusBarOrientation.isLandscape {
height = min( Constants.screenWidth, Constants.screenHeight )
}
return CGSize(width: view.bounds.width, height: (height - 300) / 1 )
as you can see I've tried to alter the height for the orientation, but ultimately this does not change as I thought it should.
Complete code is in this GitHub link: https://github.com/stevencurtis/CollectionViewRotate
I want to stop getting this error, and ultimately because the height is incorrectly set when I rotate the device the image is larger than the bounds of the view.
How can I set up my flow layout so this doesn't happen.
The height of the screen is irrelevant. What you really care about is the height of the collectionView.
Use:
let height = collectionView.bounds.height
By using that value, the height will be correct when you rotate the phone without your having to check for it explicitly. You'll still want to adjust for insets if you have any.
You should also use collectionView.bounds.width for the width in place of view.bounds.width.

Swift shrink UIImageView according to what image it contains

I have an UIImageView which is as big as the whole view. When I insert an image, I would like for the image view to shrink itself in order for it to be as big as the image I insert itself. I cannot find a way to do it.
There are a number of ways you can approach this assuming you have a UIImageView declared like so:
#IBOutlet var dynamicImageView: UIImageView!
When changing your image, set the imageView size to that of the UIImage e.g:
func changeImage(){
if let image = UIImage(named: "Octocat"){
dynamicImageView.image = image
dynamicImageView.frame.size = image.size
print("Size Of ImageView = \(dynamicImageView.frame.size)")
}
}
Just use the .sizeToFit method e.g:
func changeImageAgain(){
if let image = UIImage(named: "Octocat"){
dynamicImageView.image = image
dynamicImageView.sizeToFit()
print("Size Of ImageView = \(dynamicImageView.frame.size)")
}
}
Running on an iPhone 7 Plus the UIImageView size is initially (375,647), and when applying either method the size changes to (800,665) which is the same size as the GitHub OctoCat:
I have created one demo app which will contains XIB with image view. Here I have written code to resize imageView as per image size. This code is working in my project, I shared link for demo app, you can download and test it.
In this project, I have implemented code to create imageView based on image size and vertically and horizontally centred aligned.
Also implemented code to zoom image.
https://app.box.com/s/sro2g7gdv5c67f9oj97gfhicjnpo2vqc
I hope this will work for you and as per your requirement.

Constraint View Inside Content Of Image View Swift

I have an image view that gets a dynamic image, and uses aspect fit to determine the frame of the image itself. I am trying to constraint a view inside of the image view, but when the image dynamically resizes, the view inside of it doesn't also dynamically resize when my constraints are just set to the borders of the image view.
Is there any way to set the constraint to the content size that the image is after it resizes, inside interface builder?
Thank you!
When you set the image view’s frame, pick an initial height or width—not both. Then, get image.size and calculate the proportional other dimension. For example:
let width = 100
let height = width * image.size.width / image.size.height *
imageView.frame.size = CGSize(width: width, height: height)
imageView.contentMode = .scaleAspectFit
imageView.image = image
Now your imageView is exactly the size of your image. You can do the same thing with a fixed height by simply replacing “height” with “width” and vice versa in the code above.
Hope this is what you’re looking for.