I have a scrollview contains all views on the viewcontroller including a tableview. all views are scrolled like this :
but I want that the tableview stay at buttom of page and just increase its height like this :
I changed all constrains and googled but I couldnot find solution to this.How and Where I can increase table height when scrollview scrolls?
You can increase table size with respect to scrollView contantSize in viewDidLayoutSubView() method
Provide a fixed height constraint to UITableView in storyboard or xib. Make an outlet for that constraint
override func viewDidLayoutSubviews() {
super .viewDidLayoutSubviews()
self.constraintTableViewHeight.constant = self.scrollView.ContentSize.height
}
Hope it help. Happy codding:)
Related
I'm trying to create layout that it structured like this:
- View
-- ScrollView
--- ContentView
---- CustomView
---- CustomView
---- TableView
---- CustomView
The tableView itself is auto-resizable using "invalidateIntrinsicContentSize" and when I add items - the height of the tableview changes, pushing the custom view below it further down.
Once enough items are added I the bottom custom view is hidden and the scroll doesn't work.
important fact - the bottom custom view doesn't have a bottom constraint. It is pushed down by the it's top constraint to the tableView.
If I do set a bottom constraint - the table view will no longer be dynamically resized.
The intended behaviour:
When a user adds items to the list and the list gets too big the ContentView will be scrollable so the user can scroll to see the bottom view.
The actual behaviour:
When a user adds items to the list and the list gets too big, the bottom view is pushed down and outside of sight and content is not scrollable.
What is happening and how can I fix it?
Below is what I think what is happening.
Since you are using UITableView, it has its own scroll view. So when the UITableView list gets too big, UITableView itself becomes scrollable rather than ScrollView's contentView becoming scrollable.
To achieve what you need, you would have to make the UITableView not scrollable and use the intrinsicHeight of the UITableView to get the actual height of UITableView along with all the items. If you have items with varying heights, it will be a problem because you won't know the height before rendering. With same height for all the rows, you can get the total height of the UITableView and set the height constraint to that value. This will increase the contentSize of the outer ScrollView, making it scrollable.
Apart from UITableView, you can also use UIStackView. This is because you are not using the reusing capabilities of UITableView anyways. Managing the datasource and delegates should not be a big problem.
You can create a constraint for tableview height, And take its reference to your swift file, by dragging it as you take other views. Now in your code, Just do this
tableViewHeightConstraint.constant = tableViewNoOfItems * tableViewCellHeight;
if you have set other constraints perfectly inside scrollview, It should work perfectly. Means TableView should have top, bottom, left, right margined constraints from the ScrollView.
try this code
tblViewHeight.constant = CGFloat( tableview row count * 45 )
var size = contentView.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
if size.height < scrollView.frame.size.height
{
size = scrollView.frame.size
}
contenViewHeight.constant = size.height - scrollView.frame.size.height
scrollView.contentSize.height = contenViewHeight.constant
What I think you could do is:
Disable tableView's scroll tableView.isScrollEnabled = false
Every time a user adds items to the list, reload the tableView
Also using UIStackView with vertical axis and .fillEqually distribution as a Content View would be much more convenient as you won't need to set any positional constraints to your views, but may need to set height constraints if intrinsic content size can't be determined by the engine
I am creating a collection view full of menu items. The collection view is supposed to be tall enough so that it fits perfectly in the size of view.
I can set the UICollectionView with a fixed height constraint, but if there are 20 items then that height might be too small or if there are 5 cells the height would be too big.
Is there a way to change the frames of the main view and the Collection view based off how many cells the view will have? Possibly in the viewDidLoad() function?
set the height constraint of the collection view in storyboard with any value , and hook it as IBOutlet say collectionHCon
override func viewDidLayoutSubviews() {
self.collectionHCon.constant = numberOfItems * itemHeight
super.viewDidLayoutSubviews()
}
having issues with UIScrollView. I have a setup like so:
I have a scrollview pinned in the first image, trailing, leading, top and bottom constraints. In the second image I have place a UIView of the same dimensions inside the scroll view (I plan to add content to this). This is pinned to the scroll view and also centred horizontally and vertically. It seems no touches are registered at all when I try to scroll now. I have set a large content size:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
print("The scroll views height is \(scrollView.frame.size.height)")
scrollView.contentSize = CGSize(width: scrollView.frame.size.width, height: 1000)
print("The scroll view content height is: \(scrollView.contentSize.height)")
}
I have also enabled user interaction everywhere I can. I am using the delegate method scrollViewDidScroll(scrollView: UIScrollView) to check if touches are being registered and they aren't at all. What am I doing wrong here?
Hope this will help you,Many facing this problem i hope my solution will provide relief to Devs.
your view Hierarchy should be like this :-
View (main view of my UIViewController) – with
-ContainerScrl
--Scroll View (UIScrollView)
---ViewInsideScrl
----Content1
----Content2 (etc)
As, the ScrollView only Scroll When its Content Size will be greater then the frame of Scrollview.
Now Comes the imp. part the constraint Should be like:-
Give constraint to the ContainerScrl and then Scroll View Should be pinned from all the direction to the ContainerScrl and ViewInsideScrl should be pinned to Scroll View. Now it will be giving warning like scrollable content size Ambiguity.
Look, if u give constraint like width and height of ViewInsideScrl should be equal to ContainerScrl, all the constraint error msg will be vanished but it will not scroll as frame getting equal to content size,, let suppose u want it to scroll in horizontal dirction then just give equal height constraint to both the view and give proportional constraint to ViewInsideScrl width constraint w.r.t ContainerScrl like
ViewInsideScrl = 2* ContainerScrl ;
it will make the content of scroll bigger then the frame.
Lets try this, if problem not get solved we will look further to it.
I have a UIScrollView, inside this UIScrollView I have a UIView and inside the UIView I have some UITextField's, some UILabel's and at the bottom there is a UITableView.
I want the UITableView to fit it's content height, the UIView to fit it's content height and the UIScrollView to fit it's content height.
The UITableView height might change as I add / remove cells from it during usage.
What is the best way to handle it using AutoLayout?
- UIViewController
-- UIView
--- UIScrollView
---- UIView
----- UILabel
----- UITextField
----- UITextView
----- UITableView (at the bottom of the superview)
or as in the xib:
The best way to implement this is to scrap the hierarchy that you have now and do the following...
- UIViewController (or UITableViewController)
--- UITableView
----- UIView (as the tableView.tableHeaderView)
------- UILabel
------- UITextField
------- UITextView
----- Rest of the cells for the table view.
The tableView.tableHeaderView is a single (not reusable, concrete) view that is placed at the top of the content of the table view and scrolls with the content of the table view. It doesn't stick to the top of the screen like a section header view does.
This will allow you to delete the scroll view and place everything inside the table view and still doesn't change the methods that you are using to populate the cells as that remains untouched.
#Jan Greve is correct. But if you still want to do it
Set Bottom Space to Container constraint between the Table View and its super view to 0
Increase/decrease the height constraint of the Table View with each insert/delete (You will have to do this programmatically)
Set the content offset of the scrollview to the new view height
The best part of AutoLayout is now you don't have to worry about UIScrollView content size.
If you set all constraints properly(without any warnings) AutoLayout manage content size for scrollView itself.
Set all subview's constraints but don't add height and width constraints.
And for contentSize add bottom constraint of inner view (subview of scrollview) to UIScrollView. This will increaser scrollView content size and height as per inner view expand or shrink.
For more details: I asked question for same, you can check it. You can find code in question itself.
You can set a fixed height to the tableView and link the constraint to an outlet. Then you'd need to override viewDidLayoutSubviews() in order to set the height dynamically based on the contentSize of the table:
#IBOutlet weak var dynamicTVHeight: NSLayoutConstraint!
internal override func viewDidLayoutSubviews() {
let height = min(self.view.bounds.size.height, self.tableView.contentSize.height)
self.dynamicTVHeight.constant = height
self.view.layoutIfNeeded()
}
I'm hiding rows that are completed in a collectionView.
I call cell.hidden = isCellHidden in cellForItemAtIndexPath when needed.
After I hide 10 rows there is plenty of empty space left and I'd like to trim down the size of the collectionView to only fit the rows that are not hidden.
The collectionView's design is kind of like a tableView.
I know with the tableView all I had to do to achieve this is set:
func section1VisibilityButton(sender: UIButton){
isCellHidden = !isCellHidden
self.tableView.reloadData()
self.tableView.contentSize.height = CGFloat(500)
}
with a collectionView when I try this it will resize it correctly but as soon as I try to scroll down it resizes itself back to the original height including the cells hidden (the cells layer is still hidden but there's tons of empty space bellow the last visible row as if they were visible)
For your issue, there are two options to change the frame of your collectionView/tableView.
If you are using autolayout, you need to create IBOutlet of bottom constraint or IBOutlet of constant height constraint of your tableView (anyone of these constraints, which you are using).
After reload tableView data you need to update constraint by calculating its height.
Suppose you are using constant height constraint and your calculated height is 150(e.g. 3 rows and 50 height of each row).
constraintTableViewHeight.constant = 150;//this will change height
self.view.layoutIfneed(); // this will apply updated constraints to whole view
If you are not using autolayout, you can manually change the height by changing tableView.frame property.