I made a UICollectionView with a vertical scroll.
The width of the cell is more than than the screen width, so I created a customFlowLayout based on UICollectionViewFlow layout returning the right calculated content size.
However, this doesn't work. When the width of the cell is less than the screen width it works. Does it mean that we can't have width more than than screen width in vertical scroll?
It is the same for horizontal scroll, but then the height of the CollectionView is limited to screen height.
Is there any way to make it work?
As others have already said, the UICollectionView can only scroll one direction using a flow layout. However you can accomplish this very easily without creating a custom layout or using a third party library.
When you lay your view out in story board, you can put your UICollectionView embedded in a UIScrollView. Have the scrollview set up to scroll horizontally and the UICollectionView to scroll Vertically. Then set the UICollectionView.delaysContentTouchesto true so touches will pass through to the UIScrollView and not think you are trying to scroll the collectionview.
When you set up the UICollectionView, set it's size and the size of the cells to be what you actually want them to be (Wider than the actual screen) and lay them out accordingly.
Now in the containing UIViewController put this code in the view lifecycle
- (void)viewDidLayoutSubviews {
self.myScrollView.contentSize = self.myCollectionView.frame.size;
}
That's literally all you have to do to accomplish what you are describing. Now your scrollview should allow you to scroll horizontally to view your entire cell and your collectionView should scroll vertically through your cells.
Happy programming.
I'm not sure I've understood your problem.
But if you have made a custom layout, make sure you have implemented :
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
and that your layout attributes frame and size are set with correct values for your "large cell" index path.
Also make sure you have implemented :
- (CGSize) collectionViewContentSize;
This method returns the contentSize of the collection View. If contentSize.width > youAppFrame.width you should have horizontal scrolling. Same for height and vertical scrolling.
Also make sure your collectionView allows scrolling and that your layout is prepared correctly using :
- (void)prepareLayout
By the way, for your layout have you overloaded UICollectionViewLayout or UICollectionViewFlowLayout ?
Before you can do that you MUST use a different type of layout. The flow layout represents its items as a list and it spans these items in cells based on the available width.
If you want to have both horizontal and vertical scrolling you need to somehow specify the number of columns for your grid. the FlowLayout doesn't have that. A simple sollution is to make a subclass of UICollectionViewLayout and override collectionViewContentSize to make it retun a width = to the added sum of the cells widths of one row (this is where knowing how many collumns you want is necessary), plus any additional spacing between them. This will work fine if your cells have the same size per column, similar to a grid.
You should embed a UITableView into a UIScrollView.
ScrollView and TableView will have the same height but different widths.
This way UITableView will scroll vertical and UIScrollView will scroll horizontal.
Xcode 11+, Swift 5.
I solved my issue, I prepared video and code
Related
I have Viewcontroller in which I set the scrollview. In the scrollview I have tableview which is in the Container and just below the container I have an textview and some other UIViews when I set the tableview frame size equal to content size and tableview scroll property false so that only scrollview scrolls when the content size increase the textview goes up to tableview and I want that when tableview content increase then textview also goes down and parent view frame size increase and decrease as the content size
This look like a job for a UICollectionViewController. If you want to take a look here
you can get a better understanding of what they are and how to use them.
Basically you want to put each of those UITableViews, UILabels and the UIButtons in it's own cell(buttons need to be arranged) of the collectionView then the cell with the buttons try to use a stack view with the image. This will automatically set the different sections apart from each other. I know the idea of a collectionViewCell containing a tableView may seem weird but check this out
Another solution is to get crazy with constraints and autoLayout. I don't recommend this route because autoLayout will make decisions on it's own if the exact layout is not explicitly declared. Basically you'll set the constraints by pinning the tableView and labels to each other and the container they are in.
Checkout Apple's docs here
Good luck and let me know how it goes
I would recommend using a xib (if storyboards is your preference) or programmatically embed a tableview in the Scrollview Controller. Set a default cell height and then calculate the height of the Tableview by grabbing the amount of cells (which you'll normally get from .count in an array).
Afterwards, constrain the top, left, and right constraints of the tableview to its parent. You can imbed these in a scroll view for ease. Then if you want default text underneath it, all you have to do is constrain the top of the textview to the bottom of the tableview.
Do the cell for the button's. As the post above said, buttons might be best done in a CollectionView, so you can either create a default cell (xib again is useful) or use a prototype cell in storyboard. Collection views are the same principle as tableviews when it comes to populating data, they are just formatted differently and insets/spacing between cells.
This should help!
I am looking for a way to build a UICollectionView with a vertical flow layout that is embedded in a UIView. the UIView acts as the datasource/delegate for the containing collectionview. The behavior I am looking for is that the collectionview itself has its scroll disabled and the containing UIView grows as you add more rows to the collectionview. How can this be achieved?
I think you can achieve this by following steps,
Embed the UIView which you currently have into a UIScrollView(Make its constraint respective to its super view).
Then add height constraint to your UIView and create an outlet for that height constraint in our view controller, so as of now when the height of UIView gets increased the scrollView content size will also get increased.
Then place the UICollectionView inside the UIView and make its top, bottom, left & right constraints to UIView.
Now increase the height constraint constant value based on the number of collection view cells in the collection view.
I hope this will work for your scenario.
But if in case you are free to explain why you need to achieve this kind of behaviour it would be nice, because I cannot able to figure out the need for it.
This kind of scenario could be achieved. Here is rule of the thumb:
You should not specify height of you view, that will be contains unscrollable collection, pinned to it, and it should be embedded in UIScrollView using equals width, and pinned to all sides with margin. Auto layout makes things work.
Otherwise, is there any important reason to disable scrolling and make UIView delegate / data source for collection?
I'm trying to implement an iOS collection view which basically should work similar to a table view, but the cells' widths being integer multiples of the collection view's width (eg. 4 times the width). the collection view should scroll vertically (like a regular tableview does), but it should page horizontally across the content.
I do have the custom layout working except for the paging. Currently, the collectionView will just scroll horizontally. I'm unsure how to implement the paging correctly.
If I just set pagingEnabled on the collectionView, it has no effect. I suspect that the scrollview needs to be told what the width of a page is..?
Or do I have to do anything weird because there is only one cell/column per row, instead of multiple cells?
See the image; the grey bars are the cells, the blue rect is the collection view frame.
thanks!
I believe if the collection view item widths are less than or equal to the width of the collection view, then the horizontal paging should work via the pagingEnabled property. Otherwise, you need to create the paging effect yourself using the UIScrollView delegate methods and animating to offsets yourself after a certain threshold
Looks like iOS makes our life difficult for simple things that should be accomplished in seconds with auto layout.
Anyway I want to place a UITableView inside a UIScrollView (I know that tableview contains scrollview but this is not what I want). The View ierarchy is
OuterView
ScrollView
ContainerView
View 1
TableView
The expected result is to disable tableview functionality and the scrollview to scroll view1 and tableview together.
The problem is that the height of the scrollview is the devices height whatever the device orientation. If i change the tableview frame and content size to the one calculated by all rows it does not adapt to the scrollview content size. Why? What's auto layout doing then?
I have set constaints like Trailing-Leading-Top-Bottom spacing to all view as well as width and height equality between outer and container view.
I cannot find a SIMPLE tutorial for scenarios like this one.
The Apple documentation discourages embedding UITableView within a UIScrollView because it can cause unexpected behaviour:
You should not embed UIWebView or UITableView objects in UIScrollView objects. If you do so, unexpected behavior can result because touch events for the two objects can be mixed up and wrongly handled.
This is likely why you are having trouble finding a tutorial. Why do you want to embed a table inside a UIScrollView? It may be more effective to designate rows in the UITableView to act as the content you wish to put in the UIScrollView.
I use a table view which has got the cells with varied set of information and which can not be contained with in the frame of the tableView. So I do need to have a horizontal scrolling capacity in the table view.
Since horizontal scrolling is not possible with tableview,I planned to use a scrollView with horizontal scroll. I added the tableView on top of the scrollView.
The problem I face is irrespective of the content size property of the scrollview, the scrollview never scrolls beyond the contentOffset value X of 256-320 pixels.
I am planning to achieve the effect as it is in the below screen shot
Try two things,
First Set the TableView height as total numberOfRows :
tableView.frame.size.y = numberOfRows * 44;
now disable the tableView Scrolling
and set he scrollView contentSize as per your need;
scollerView.contentSize = numberOfRowsintableView
Surely it will solve your problem
Set proper ContentSize for ScrollView in ViewDidLoad.
scollerView.contentSize = CGSizeMake(Width,Height);
Calculate the Width as Per Requirement And Height (you are using Tableview So You can take Height same as View Height)
Then it will Surely Scroll.
I implemented the entire functionality using code without using interface builder. It works as expected now. I did not know why it did not work when used with interface builder.