Nested UICollectionViews scroll issue (iOS) - ios

I have a UICollectionView, called parentCollectionView, and it scrolls horizontally. Inside each parentCollectionView's cell, is another UICollectionView, called childCollectionView, which scrolls vertically. In addition, parentCollectionView is set to paging (pagingEnabled = true).
Thus, you can scroll left/right to the next parentCollectionView, and you can scroll up/down in the childCollectionView.
There is an issue, however, regarding conflicting gestures. On the first horizontal swipe, the childCollectionView scrolling gesture is recognized. It fails to swipe horizontally, and doesnt scroll down in the child collectionview. But on the second swipe horizontally, it will page to the next horizontal cell as so.
How do I prevent the child collectionview from registering the first horizontal swipe? When I set isScrollEnabled = false on the childCollectionView, it fixes the issue, but I still would like to scroll down in my child collectionViews.
Is this something that is accomplished via gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:? Ive tried subclassing the scrollView the top answer in this stack overflow question, but was unsuccessful.
Cheers

It appears as the problem was that the childCollectionView's content size was larger than the frame. Thus, the childCollectionView was given the impression that it was scrolling right within the childCV. I made sure the content size was identical to the CV frames.
//In my case, the childCV's width is exactly UIScreen.main.bounds.width - 30
let scrollSize = CGSize(width: UIScreen.main.bounds.width - 30, height: self.listCollectionView.contentSize.height)
listCollectionView.contentSize = scrollSize

Related

How should I set constraint of UICollectionView in iOS

Hi I want to put CollectionView in fullScreen
So I set it's constraint all top, buttom, left, right zero with SafeArea
But in iPhone 11, When I put many Items, CollectionView Cover the SafeArea with scroll
And I can't see last Item fully
I can see the Item when I scroll, but it bounce up immediately
When I set HeightConstraint with Constant, same height with SafeArea, It looks perfect
So I guess the reason of problem is that Height of SafeArea be changed when CollectionView require Scroll
Any Suggestion for this?
If I can, I want to solve it with StroyBoard
First screen is Auto Layout that I set on Storyboard
And Second One is current Work
I can't see the bottom of Last Cell , I can see if I scroll down, But It Bounce up like that
In your view hierarchy, I noticed a header view is residing for your collection view. Have your tried defining it's height using referenceSizeForHeaderInSection method? You will find that method in collectionViewLayout. Here's reference link :- https://developer.apple.com/documentation/uikit/uicollectionviewdelegateflowlayout/1617702-collectionview

With Storyboards only, how do I create a UITableViewCell that can scroll left and right using UIScrollView?

Similar to Mail.app where you can scroll the cells side to side, I want to be able to do it in my app using Storyboards and UIScrollView with my UITableViewCell.
I add some buttons to the contentView of my cell, and then UIScrollView with an embedded UIView on top of that to contain the main portion of the cell. I then add a label to that.
I understand that scroll views in Storyboard work by specifying constraints to show what the contentSize of the scroll view should be.
So I position the UIView in the UIScrollView to be the same width and height of the scroll view, but give it a trailing constraint of say 50pt to allow the scroll view to scroll. When I run it I can then move the cell to the left to reveal the buttons.
But to get it work in the other direction I have no idea. If I add a leading constraint it actually moves the cell to begin with away from the left, offsetting the cell to begin with when it should be left to the user to scroll it. It works fine other than initially being pushed over.
I created a sample project showing it here: http://cl.ly/2i3m1W2T0i3C
Like I said I just can't seem to figure out how to get it to scroll in both directions.
Try setting the contentView of the scrollView with width higher than the scrollView itself.
Something like:
Assuming your scrollView.frame is (0,0,100,100)
[scrollView setContentSize:CGSizeMake(300,100)];
place your table view, let a part of your view out of the screen and check that case:

Scrolling to next cell in UICollectionView

I have a UICollectionView in a container View. It is sized in such a way that I see only one cell at a time. I have disabled vertical scrolling so only horizontal scrolling takes place.
Everything works just peachy where I scroll horizontally across cells. The disadvantage of this scrolling is I can scroll and get to a position where I see half portion of two cells with a gap in between.
What I want to achieve is to show only one cell at a time and never show two half cells. So the scrolling should take me to the next cell one at a time.
Hope this makes sense.
Please let me know if anyone has tried or can help me to achieve the same. Thanks.
You can scroll one cell at a time by setting pagingEnabled = YES. Or for regular scrolling, you can adjust where the deceleration ends by overriding targetContentOffsetForProposedContentOffset:withScrollingVelocity: of UICollectionViewLayout. When using the later method, you would typically do the following:
Determine the nearest index path to proposedContentOffset. If there are no gaps between your cells, you can use [UICollectionView indexPathForItemAtPoint:]. Otherwise, you may have to inspect your layout in some way to determine which index path you want to scroll to.
Determine the frame of the index path you want to scroll to by getting the layout attributes for that index path
Determine the content offset that will position the given frame where you want it.
Make sure your padding between cells is set to zero as well. Paging enabled will stop on multiples of the view bounds.
// Set up flow layout
var flowLayout:UICollectionViewFlowLayout = UICollectionViewFlowLayout();
flowLayout.minimumInteritemSpacing = 0
flowLayout.minimumLineSpacing = 0
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: flowLayout)
collectionView!.pagingEnabled = true
Check out my answer over here: ScrollView or CollectionView?
It sounds like you have paging enable but the page size doesn't match you cell size plus the insets left and right of the cell.
Swift 5:
collectionView.isPagingEnabled = true

UITableView inside the UIScrollView for horizontal scrolling does not work as expected

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.

UICollectionView scrolling in both directions

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

Resources