Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Sections, Different Scroll Directions and Sticky Headers #304

Closed
otymartin opened this issue Dec 8, 2016 · 13 comments
Closed

Multiple Sections, Different Scroll Directions and Sticky Headers #304

otymartin opened this issue Dec 8, 2016 · 13 comments
Labels

Comments

@otymartin
Copy link

otymartin commented Dec 8, 2016

This is a Question/Discussion.

At hand, I'm trying to implement this layout using IGListKit. So the purpose of this issue/question/discussion is more to curate information on how this can be achieved with the current capabilities of this library. Hope it helps everyone.

I'm selflessly and selfishly providing the layout I'm attempting(struggling) to implement as a framework. Its similar to Instagram's current layout except Instagram got rid of the sticky headers, sad!

screen shot 2016-12-08 at 3 55 53 pm

PROBLEMS

1. How to create the Horizontal and Vertical scroll sections within the same CollectionView

According to @rnystrom && @bonzoq in #66, Their method is to create an IGListCollectionView with Vertical Flow Layout and imbed a CollectionView with a Horizontal Flow in the first cell of the IGListCollectionView. Then I guess the Vertical Scroll requires a CustomFlowLayout to achieve the Grid?? (@zhubofei #225). More suggestions are welcome. Im attempting this now.

2. How to create sticky headers for both sections

The Supplementary views example provides an example of how to achieve Section Headers but in order to get the Sticky effect, it requires you to do UICollectionViewFlowLayout().sectionHeadersPinToVisibleBounds = true for iOS9+. I'm not sure this is available for CustomFlowLayout's. How can this be done for custom layouts?

3. How to hide the Horizontal or Vertical section in case of no data?

UITableView provides this behaviour for free where a section along with its header are hidden if there is no data in it. How can this be done in this framework?

Thanks🙌

New issue checklist

General information

  • IGListKit version: Latest
  • iOS version(s): 9+
  • CocoaPods/Carthage version: Latest
  • Xcode version: 8
  • Devices/Simulators affected: ?!?
  • Reproducible in the demo project? (Yes/No): ?!?
  • Related issues: ?!?
@rnystrom
Copy link
Contributor

rnystrom commented Dec 8, 2016

Then I guess the Vertical Scroll requires a CustomFlowLayout to achieve the Grid

Ya it will. This is one of the limitations of the supplied grid layout for sure. We have a custom layout internally for IG that handles grid and full-screen units. Honestly I'd like to refactor the grid layout a bit so it can do this and use it internally. That way we have the highest-quality layout that gets the same testing and attention as the rest of IGListKit.

Another option is to use UICollectionViewFlowLayout with 3 items-per-section controller. Then your objects array for the vertical list has a model for the h-scroll in the first position, then a model-per-3 grid items. The section controller returns 3 for numberOfItems.

There are drawbacks to doing this though (e.g. if an item in the middle of the grid is removed...) but it might save you from making a custom layout that supports sticky headers.

How to create sticky headers for both sections

Not impossible, but sometimes tricky. In a custom layout just return NO in shouldInvalidateLayoutForBoundsChange: to recalculate the frame of your supplementary views with every bounds change.

This layout might give you a place to start if you're going the custom layout route.

How to hide the Horizontal or Vertical section in case of no data?

If you use supplementary views w/ the section controllers, just make sure to return an empty objects array in the adapter data source and you're set. The supplementary views will be removed.

@otymartin
Copy link
Author

Another option is to use UICollectionViewFlowLayout with 3 items-per-section controller. Then your objects array for the vertical list has a model for the h-scroll in the first position, then a model-per-3 grid items. The section controller returns 3 for numberOfItems.

😵 This is super interesting. I'm interested to see how this works so I'll demo it out.

If you use supplementary views w/ the section controllers, just make sure to return an empty objects array in the adapter data source and you're set. The supplementary views will be removed.

Easy enough, I thought it would be yet another struggle😅

Thanks @rnystrom

@cruisediary
Copy link

  1. How to create sticky headers for both sections

The Supplementary views example provides an example of how to achieve Section Headers but in order to get the Sticky effect, it requires you to do UICollectionViewFlowLayout().sectionHeadersPinToVisibleBounds = true for iOS9+. I'm not sure this is available for CustomFlowLayout's. How can this be done for custom layouts?

In my case, to make sticky section header with IGListKit, use CSStickyHeaderFlowLayout

how about use CSStickyHeaderFlowLayout it works perfectly for me to make Wine SNS application similar to Instagram's layout

@otymartin
Copy link
Author

@cruisediary Interesting I came across that library earlier this week. Good to know someone else though along the same line. I haven't tried implementing it though but since you succeeded i will.

@ibakurov
Copy link

ibakurov commented Dec 13, 2016

I have very similar layout in my app (Atsight), except for sticky headers. I am going to describe what I did, and I leave it up to the judgement of the community, because I am curious about better ways of doing it too!

Just as a heads up, here is what it looks like in UI Hierarchy Viewer:

screen shot 2016-12-12 at 8 29 18 pm

I've implemented section titles as simple IGListSectionController with one cell. And they are added to the main IGListCollectionView. Then I have my posts, which are IGListSectionController which is divided into multiple UICollectionViewCells. And finally, for the horizontal-scrolling collection view with suggestions I have another IGListSectionController, which has only one UICollectionViewCell, with IGListCollectionView and IGListAdapter in it. The hardest part here was to properly maintain paginating through suggestions as well as it been properly updated, whenever new suggestions available.

  1. Paginating: this was relatively easy to solve. I have my suggestions' UICollectionViewCell which implements UIScrollViewDelegate and tracks when user is getting to the end of the list. I call the delegate method which goes up to UIViewController which holds the main IGListCollectionView and make an API call to the server to load more data. And now performUpdates should be called.

  2. performUpdates: I was thinking a lot on what is the easiest way to implement it with the current IGListKit framework setup and came to this solution. As for spinner, error or titles in my main IGListCollectionView I have tokens, I thought to use the token for the suggestions IGListCollectionView too, because I want it always to be there when there are any suggestions available, and I can pass the data to it in func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController function. However for IGListAdapter to actually reload data in it, we need to have a new token there every time func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] is called. My solution was simply to assign new randomized string to the token variable before calling performUpdates on the main IGListCollectionView.

Let me know what you think, and as I said, this approach works for me, so if there are any more questions I could help with, I am glad to share an information.

@jessesquires
Copy link
Contributor

Is this good to close?

@otymartin
Copy link
Author

@jessesquires I'll post the method I used either today or tomorrow but for most part yeah it can close.

@waltermvp
Copy link

@otymartin did you ever attempt to use CSStickyHeaderFlowLayout , if so did it work?

@zhubofei
Copy link

zhubofei commented Feb 4, 2017

@waltermvp there is a new layout coming soon which support sticky header. See #450

@otymartin
Copy link
Author

otymartin commented Feb 4, 2017

@waltermvp Oh man I forget to update myself on this.
So no actually.I didnt use that...

What I did was use a tableView with two sections. Both sections have stickyheaders.
Then I stuck an IGListCollectionView inside both tableViewCells. A total cop out, I dont know if thats frowned upon here or what but whatver it was the easier option for me.

The top is a horizontalFlowLayout so thats cool
But the bottom is a verticalFlowLayout which poses the problem as content populates, you want to scroll the tableview cell not the collectionView. So I disabled scrolling on the collectionview and have to dynamically calculate the tableViewCell height in order to fit the expanding collectionView height.

As for that perfect grid, I had issues with "IGListGridCollectionViewLayout" which I mention in #140 so Instead I followed @rnystrom advice in #341 where rather than return 1 in my numberofItems() I returned all objects in my dataArray.count. That magically gave me a perfect grid :)

@rnystrom ...
`instead of using the mutable dataArray.count in the section controller, I would use an immutable object that represents the data in your section. Whenever a network request finishes, you can call performUpdates(...) and recreate your immutable models.

Take a look at my weather app data source as an example. Anytime something changes I recreate the models which power my different section controllers.`

@zhubofei that looks super promising 👍 sweet :)

slack for ios upload

@waltermvp
Copy link

@zhubofei thanks for the update

@otymartin thanks for the workaround it's good to have something to use in the meantime

@ryancstack
Copy link

@cruisediary do you have an example project using CSStickyHeaderLayout in conjunction with IGListKit?

@IamAbdulQadar
Copy link

@otymartin can you please share the actual project with same scenario ? As i'm facing some trouble with same structure layout .

This design i'm trying to make where the upper part is horizental scrolling and down part is vertical scroll but with condition that when i drag up the down collection View then the upper collectionView should hide .

imgpsh_fullsize

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants