UIImageView is not auto height in StackView with TableViewCell - swift

This is the view hierarchy
I want the PhotoImgView auto height depends on the Image size
The image is download from server
I use KingFisher to download the image
when download finished, I set PhotoImgView's height constraint, and do layoutIfNeeded() in the cell class
but it's not update UI immediately
when I scroll to another cell, and let the cell invisible, and then scroll back, the cell would be right
How can I do this?
Same issue with the collectionView, I set collectionview's height constraint after collectionview.reloaData and get collectionview.contentSize.height

Try this:
Replace your current layoutIfNeeded() with this:
DispatchQueue.main.async {
self.layoutIfNeeded()
}

Try to call setNeedsLayout() before layoutIfNeeded().
To get right result for collection view height you can try:
collectionView.reloadData()
collectionView.setNeedsLayout()
collectionView.layoutIfNeeded()
collectionView.collectionViewLayout.invalidateLayout()

Related

Automatic height for TextView using autolayout in cell for tableView

I want to set the height of the TextView as per content in a cell for tableview.
i pinned the top of text view to the job title UILabel and bottom to the content view (parent) but it does not working. is there any tutorial for this kind of layout positioning ?
How i add constraint to fix the automatic height issue?
Current constraints
As I can see you have some other setup as well in the cell. to support dynamic height
you can give fix height constraint to UITextView.
take outlet of that constraint.
update it before you return the cell from cellForRowAt method.
so, your cellForRowAt method will end up like
tableCell.textViewHeightConstraint = textView.contentSize.height
tableCell.setNeedsUpdateConstraints()
tableCell.setNeedsLayout()
return tableCell
Solved this way.
Change the TextView to UILabel, Then set Lines property in the attribute inspector to 0.
on viewDidLoad
tableview.rowHeight = UITableView.automaticDimension
tableview.estimatedRowHeight = 229.0
It works.
More https://www.raywenderlich.com/8549-self-sizing-table-view-cells
You can apply Self-Sizing Table View Cells by adding two lines:
tableView.estimatedRowHeight = 85.0
tableView.rowHeight = UITableViewAutomaticDimension
You should read this document from Apple:
https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithSelf-SizingTableViewCells.html

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)

UIScrollView scrollable area not updating with scrollView frame constraint update

I'm updating a frame constraint
scrollView.top Equal container.top
by subtracting from the constant, then calling layoutIfNeeded()
The scrollview's frame updates fine, and the content comes with it, but in the new area that the scrollview has acquired (above the scrollview) it does not fire scroll events when dragging. The old area works.
I've tried updating the contentOffset, but that effectively scrolls the content up inside the scrollview instead of expanding the scrollable area
I'm updating the contentSize, but it seems like problem is where the contentSize starts from
I've tried updating the contentInset, that still just moves the content around without updating the scrollable area
Maybe there is a property that needs to be updated but I can't find it
The end goal here is to programmatically increase the size of a scrollView
here is scrollViewDidScroll, where I'm updating the constraint
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let newVal:CGFloat = -120.0
DispatchQueue.main.async { [unowned self] in
self.feedTableViewTopConstraint.constant = newVal
self.view.layoutIfNeeded()
}
}
You should call
setNeedsLayout()
instead and if you want the layoutIfNeeded() to happen in the same loop then you can call it immediately after you called setNeedsLayout()

unable to scroll the textview in Swift

I have a TextView as shown below
I am not able to scroll the text view , I have added UITextViewDelegate in UIViewController class as well as set isUserInteractionEnabled property in textViewDidBeginEditing
func textViewDidBeginEditing(_ textView: UITextView) {
textView.backgroundColor = UIColor.lightGray
textView.isEditable = false
textView.isUserInteractionEnabled = true
textView.isScrollEnabled = true
}
What did I need to do?
Also, the scrolling is enabled in attribute inspector
This issue has occurred because the actual UITextView's size was more than screen size as shown below
The real answer is that the UITextView needs its content frame height inferior to its content size height to be able to scroll.
In your case, the content frame height is equal to the content size, so it doesn't scroll.
You just have to set the leading left, trailing, top space and bottom space to the View, but first make sure the Text View is smaller than the actual View (parent).
It starts to get complicated when you have a UITextView on a UIView which is either a view on a UIScrollView or directly on a UIScrollview.
The best thing to do, is to give each of them their own actions when scrolling.
Firstly, make sure you have all of your delegates for EVERYTHING set.
Make sure your UITextViews are not user restricted for what they don't need to be.
What I have to do in one of my published apps is this👇
func scrollViewWillBeginDragging(_ scrollView: UIScrollView)
{
if scrollView == textView1
{
// Do something if you actually want to, or just let textView1 scroll as intended
}
else if scrollView == textView2
{
// Do something if you actually want to, or just let textView2 scroll as intended
}
else if scrollView == zoomingScroll
{
// Do something if you need to or leave it
}
else
{
// Do something with all the other scrollable views if you need to
}
}

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.