Dynamic cell height programmatically - swift

Is it possible to make a dynamic cell height programmatically and only using a frames?
Without constraints, autolayout and external libraries!
In this custom tableView cell, i set frame for label with calculating height for text label:
override func layoutSubviews() {
super.layoutSubviews()
makeLayout()
}
func makeLayout() {
let sizeLabel = descriptionLabel.sizeThatFits(bounds.size)
descriptionLabel.frame = CGRect(x: 0, y: 0, width: bounds.width, height: sizeLabel.height)
}
I have view controller with tableView, where i implement his delegate with return automaticDimension, but it doesn't work

Yes,
You will have to return the height programmatically by implementing the
UITableViewDelegate function

Related

UILabels and UICollectionView inside of UITableViewCell - need dynamic height

I have a custom UITableViewCell class that contains various UILabels, UIButtons, and a UITextField in the top and mid-sections, and then a UICollectionView at the bottom.
As a user enters more search terms into the UICollectionView, the collection view grows vertically, but I can't get my TableViewCell to adjust its height dynamically.
I have added constraints for every item in the TableViewCell so AutoLayout should work. I even set the heightForRowAt function to return UITableView.automaticDimension. But I'm apparently still missing something.
When the user adds/subtracts items to the collection view, how can I have the TableViewCell update its height dynamically?
I also tried the following block, but it doesn't work either.
override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize {
collectionView.layoutIfNeeded()
collectionView.frame = CGRect(x: 0, y: 0, width: targetSize.width, height: targetSize.height + titleLabel.frame.height + filterButton.frame.height + collectionView.frame.height)
return collectionView.frame.size
}

Swift text field border isn't the right width

I have a bottom border that I generated after following the answer here.
This works absolutely great except the border isn't the right width. It's set with constraints to match the width of the button below it but as you can see is coming up short.
What am I missing?
Code :
extension UITextField
{
func setBottomBorder(withColor color: UIColor)
{
self.borderStyle = UITextBorderStyle.none
self.backgroundColor = UIColor.clear
let width: CGFloat = 3.0
let borderLine = UIView(frame: CGRect(x: 0, y: self.frame.height - width, width: self.frame.width, height: width))
borderLine.backgroundColor = color
self.addSubview(borderLine)
}
}
then in the VC :
override func viewDidLoad() {
authorNameOutlet.setBottomBorder(withColor: UIColor.lightGray)
}
Then Xcode shows...
but the simulator shows...
I've tried this both setting the width of the text field to be 0.7 x the superview width (same as the button below it) and also setting the width of the text field to be equal width of the button but neither works.
This is because of AutoLayout.
You can add autoresizingMask to your line.
borderLine.autoresizingMask = [.flexibleWidth, .flexibleTopMargin]
You are working with with a static frame for the border line view. After viewDidLoad your view controller's view gets resized.
Option 1: (Fast and dirty)
Move your code from viewDidLoad() to viewWillAppear(_ animated: Bool). viewWillAppear gets called after the first layout of your view controller's view
Option 2:
Add constraint for your border line view. So that your border line view will resize automatically.
Importent hint:
Do not forget super calls in overrides or you will get strange bugs!
E.g:
override func viewDidLoad() {
super.viewDidLoad()
// your code
}

How add Size and Position to ImageView in UITableView Cell?

I added a image to my UITableView Cell:
cell.imageView!.image = UIImage(named: "Default.png")
Everything works, the image is displayed. Now I want to give a custom size and position for the image, so I try it with this code:
cell.imageView!.frame = CGRect(x: 29, y: 17, width: 14, height: 13)
But for any reason it doesn't work. Any advices?
If your position will not change You can create frame in your TableViewCell
class TableViewCell: UITableViewCell {
#IBOutlet weak var imageView: UIImageView!
override func layoutSubviews() {
super.layoutSubviews()
self.imageView?.frame = CGRect(x: 12, y: 23, width: 12, height: 100)
}
}
You can change frame in tableview(cellForRowAt) but If frame will not change its a bad because cellForRowAt run when scrolling up - down or loading cell . You can define in UITableViewCell once.
Add a custom class for this custom tableViewCell.
Create a custom tableViewCell inside the tableView through the storyboard.
Add image inside this custom tableViewCell.
Add constraints (top, bottom, leading, trailing) to this image.
This way, you won't have to do anything programmatically and the image size issues will be taken care of by these constraints.
It'd be better if you do that frame related things in storyboard or Xib files itself. if you want them with static frame.
RunTime:
You can use NSLayoutConstraints
You can change the frame in draw(_ rect: CGRect) method.

How to move or resize an NSView by setting the frame property?

I created the NSView in a storyboard. In this case, it is an NSTextField. In the NSViewController's viewDidLoad() method, I want to conditionally resize and reposition the NSTextField, but setting the frame has no effect.
For example:
class ViewController: NSViewController {
#IBOutlet var label: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
label.frame = NSRect(x: 0, y: 0, width: 200, height: 17)
label.setNeedsDisplay()
}
}
When the view loads, the label still has its original frame as set in interface builder, and not the newly set frame.
How does one programmatically move/resize the label?
The autolayout system is the culprit here. When you set the frame, the autolayout system overrides that to re-establish the implicit constraints set in the storyboard.
Set the translatesAutoresizingMaskIntoConstraints property of the label to true. This tells the autolayout system that it should create a new set of autolayout constraints that satisfy the new frame you've set:
class ViewController: NSViewController {
#IBOutlet var label: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
label.frame = NSRect(x: 0, y: 0, width: 200, height: 17)
label.translatesAutoresizingMaskIntoConstraints = true
label.setNeedsDisplay()
}
}

How to work properly with UIView and drawRect() to customize it in the playground?

Why in playground function drawRect() doesn't work when I want to override it and show view?
I try to do this:
class CustomView: UIView {
override func drawRect(rect: CGRect) {
//some code to change self properties
}
}
let rect = CGRect(x: 0.0, y: 0.0, width: 300.0, height: 300.0)
let view = CustomView(frame: rect)
view
Then I try to change some properties (for example: backgroundColor). But they aren't applied.
I discovered the next case:
To apply set backgroundColor in drawRect I need to call this:
view.setNeedsDisplay()
BUT: From documentation:
For example, you do not need to override this method if your view just
displays a background color or if your view sets its content directly
using the underlying layer object.