Swift: View not updating to programmatically set height constraint - swift

I have a calendarView from the CVCalendar pod (https://github.com/CVCalendar/CVCalendar/) and an issue with the custom View is it erratically sets the height of the view after rotation. To try and resolve this I have set a height constraint for it and am trying to set the height after the rotation to properly fit the view:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
print("Before height: \(calendarViewTestHeight.constant)")
calendarViewTestHeight.constant = 500
self.calendarView.layoutIfNeeded()
print("After height: \(calendarViewTestHeight.constant)")
}
When this code is called the height within the print statement changes as expected but the views height does not update.

Related

UIView fixed frame

I made a customView and I want the size of that view to be fixed.
Like UISwitch in which you can't even change the height and width value.
Or like UILabel. I want to add the view to storyboard without adding any height or width constraint with no missing constraint error.
I already override intrinsicContentSize but I still get the missing constraint error.
Is there any way to make height and width of a view constant that don't even get values?
Simple solution
You can override the intrinsicContentSize variable and return the fixed size of your view.
So something like this should work in your custom view class:
override var intrinsicContentSize: CGSize {
return CGSize(width: <Your width>, height: <Your height>)
}
More Advanced
Adding the intrinsicContentSize will work, but if a user adds a height constraint it can make the view confused or change the height of the view to match the constraint. If you Know the height of your custom view shouldn't change then you can manually change the height constraints from your view.
override func updateConstraints() {
super.updateConstraints()
if let constraint = self.constraints.first(where: { constraint in
return constraint.isActive && constraint.firstAttribute == .height
}) {
constraint.constant = <Height of View>
}
}
Ideally though, your best not adding this, but I'm just adding this here so it's an option if anyone needs it.

How to expand height of containing view as TextField expands vertically with a newline

I have an array of Views that expand vertically in a scrollView. The views are of equal width and lined up top to bottom. Each View has a multiline text field that begins at a fixed height, and gets taller as lines are added. How can I constrain the height of the parent view to the height of the text field? Is it possible to do something like this (constraining a view within itself)?
Class DocCell: NSView {
// removed unnecessary components
var textField: NSTextField!
override func updateConstraints() {
NSLayoutConstraint.activate([
heightAnchor.constraint(equalTo: textField.heightAnchor, constant: 10),
// ..other constraints
])
}
}
The goal is that I don't have to update the height of each view every time the textField adds a new line, and that the size of the containing view just expands with the textField.
The goal is that I don't have to update the height of each view every time the textField adds a new line, and that the size of the containing view just expands with the textField.
You have no choice. You need to update the height of the field each time a new line is added. You can, for example, override textDidChange: in the NSTextField subclass, and call invalidateInstrinsicContentSize (after calling super) and recalculate the size there:
override func textDidChange(_ note: Notification) {
super.textDidChange(note)
invalidateIntrinsicContentSize()
}
override var intrinsicContentSize: NSSize {
let cell = self.cell as! NSTextFieldCell
var boundingRect = frame
boundingRect.size.height = CGFloat.max
return cell.cellSize(for: boundingRect)
}
This will let your other existing constraints do the right thing as long as you have the hugging and compression resistance set to 1000.

Autolayout CollectionView

I am trying to use autolayout for a CollectionVIew, but when I run it in iPhone plus, a space is created between the cells.
iPhone 8 Plus
iPhone 8
I guess you already set the cell size from collection view's delegate method. One thing you need to do is to call invalidateLayout() whenever the collection view's frame changes, so it will re-render the cells.
IE:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView.collectionViewLayout.invalidateLayout()
}
I solved it by setting in ViewDidLoad the size of the cell (I just set the width, but you could set the height too)
let layout = YourCollectionView.collectionViewLayout as? UICollectionViewFlowLayout
layout?.estimatedItemSize = CGSize(width: view.bounds.width / 2 , height: 114)

Set UITableView header view height depends on its childviews

I have a headerview in my UITableView but I can't find a solution to make it dynamically height. In my headerview I have a UITextView which height depends on its content.
What I have tried so far.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
sizeHeaderToFit()
}
func sizeHeaderToFit() {
let headerView = mTabView.tableHeaderView!
mTxtViewDescription.sizeToFit()
mConDescriptionHeight.constant = mTxtViewDescription.frame.height
print(mContainerView.frame.maxY)
headerView.frame.size.height += mTxtViewDescription.frame.height
}
The green area is my headerview
Changing the height of the frame of a UITableView header that's already been set won't recalculate the height, meaning you can't just change the height of a tableHeaderView as its layout is managed by the tableView. You need to set the tableHeaderView again, setting the property triggers the new calculation.
There are a number of questions going into detail about this, several linked from this one.

Determine width of UIView in Swift

I have an autolayouted UIView and need to know the width of it. How do I find the width the easiest way in Swift?
You can find the width of any view by
let width = yourView.bounds.width
If you have applied a width constraint to the view and you have an outlet for that constraint then you can find it by.
let width = yourWidthConstraint.constant
The right place to get the UIScreen frame data is in viewDidLayoutSubviews as it is called after the subViews have been laid out in screen also it is called after every time your device changes orientation such as your width will be different when your user goes into landscape mode.This is called after viewWillAppear:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let viewWidth = self.myView.bounds.width
}
Inside implementation your view you can use
override func layoutSubviews() {
super.layoutSubviews()
// you can get width of view in this function
print(self.frame.size.width)
}