Horizontally Scrolling UICollectionView with Vertically Scrolling Sections - ios

I'm trying to implement the following:
At the top is a segment control that, based on the user's selection (either tapping or scrolling), moves to the relevant CollectionView section.
I've been playing around for a couple of days with CollectionViews and maybe I've just confused myself with LayoutFlows and CompositionalLayouts or is that over complicating it?
I have a diffable datasource that is made up of [Sections, CellItems] but I'm struggling with how to structure it.
What is the recommended programmatic (rather than using interface builder) to do the above? I was just going to originally do 5 horizontal cells, each with a tableView but based on some other comments I've seen from Apple on the Apple forums and the move away from TableView to CollectionView at this year's WWDC, I thought I should be trying to do this properly.
Any direction would be appreciated. All my research seems to point to using orthogonalScrollingBehavior but that layouts out the sections vertically with each section scrolling horizontally.
So my question is should I be trying to do what I'm doing using a CompositionalLayout?

Well first off your segmented control idea makes this sound like you could just use a page control for the horizontal aspect and remove a lot of the collection view complexity. Something to consider anyway.
As for the data source, I think all you need is an array of arrays. Eg. [[CellItems]]. So CellItems[0] would be the first column. Then CellItems[0][0] would be the first cell. CellItems[1][2]... 2nd column 3rd cell. I do apologize as your current solution may be related to diffable datasources and I haven't had time yet to dig into those.
Start with the horizontal axis first and ignore the vertical axis. Get that working as needed. Once you have that up and running... implement another collection view into the first one's cells.
Sorry if I misunderstood the question if it was more about HOW to implement a collection view.

Related

UITableView scroll on top of cell (or how to keep a cell static)

Recently I've been trying to implement the following behavior in my own app:
As you see, when you scroll the table view up, the first cell remains at its place while others scroll up and overlap it.
Have been searching for a solution for a couple of days and so far I've only found solutions that involve using headers. But the issue is that headers "stick" to the top whereas I need first cell to stay static.
Also had an idea about using a top constraint to keep the cell at place but don't quite understand how to approach this type of thing.
Any ideas how to implement that? Any help will be much appreciated!

UITableView height for dynamic cells

In my current project i'm trying to display data in a table View, however the former view does not take up the whole screen just a part of it. It's number of cells depends on an external json and the height of the cell is dynamic. Sadly there is no inbuilt way to use auto-layout(at least i think there's not) to expand the tableView depending on it's cells.
In the following picture there's an example of how one of these table views should look like:
And here's an example how the table view looks like using the autolayout:
Is there a way to expand the tableView to it's full size?
I've tried to follow various other questions but none have fully helped me, for exampled i've tried to this solution which sadly did not help me :[, creating a subclass of uitableview and overriding its intrinsicContentSize did not do the trick either.
Any help is much appreciated.
-Jorge :]

UICollectionView sticky supplementary view

Assuming I'm on a chat scenario, I want user images to move along with scroll until the other user's messages appear. Some visual example:
I'm using a subclass of UICollectionViewFlowLayout to display the messages and provide that initial left offset for the messages (the sectionInset property is not working on iOS 9 for some reason) and I assumed handling a custom supplementary view to do what's shown above should not be that hard, but apparently it is :)
Some info:
I'm not using standard header/footers for flowLayout since it add a space between sections that I don't want
Found this link which is pretty interesting from performance perspective but the example is somehow incomplete (great post though)
I'm trying to avoid shouldInvalidateLayoutForBoundsChange: to return true and recreate attributes every time since chat cells can be complex in terms of size calculation.
I believe this is not a weird scenario, have anyone accomplish something like this successfully? If so, I would appreciate some pointers.
Thank you in advance.
you can use sections for each cell groups. When using sections they have to be a clear background and be customized. So message cells can be scrolled below sections and circle images on section will be on top of its cells.
As a second way, you can use circle images apart from all collection items. For this, you have to create circle images that how many required. While scrolling up/down, they have to be moved as they will be anchored on top of message cells group.
I hope it helps for you :)

What's the best way to implement a vertical timeline - iOS

First of all, apologies if this question isn't meant here. I searched a lot but didn't find anything.
What is the best approach to create a vertical timeline kind of view?
I tried implementing via UITableView by alternating cells but that approach is very messy in terms of autolayouting (had to disbale autolayout and apply programtically when creating cell on alternate side), thereofre isn't working properly (getting stuck while scrolling). This is what I achieved:
I want to achieve something like this, which is also easily manageble:
Please Suggest. Thanks!
I would have 1 cell row with two image views. One on the left, one on the right. I think this would be easier to use auto layout.
Then you can hide the image view and labels that shouldn't be used.

How can you create a zoomable timeline in iOS?

I would like to create a zoomable timeline in my iOS application for a kind of a todo-list. Zooming in would display days and hours and zooming out would trigger the folding out of days or zooming out to months. There would be a scrolling function.
As an example, I would want it to work like this: http://almende.github.com/chap-links-library/js/timeline/doc/
What kind of basic view would be an appropriate starting point for this, keeping in mind that the memory needed should be as low as possible? Would a UITableView, UIScrollView, or something else work for this?
The UICollectionView / UITableView will not work because the cells are almost always the same width/height. Most importantly the cells always have the same spacing in-between each cell. Because of this it is able to easily calculate what the index range is, and query the dataSource for the cell's it needs based on index.
A timeline view on the other hand is much different than these controls. The spacing between cells is different, with the cells sometimes overlapping with each other. If you had a data source sorted by position, the control would still have to guess where to start looking for the range. So finding the correct index range is going to be more expensive - you just have to find the right algoritm to determine this in a shorter amount of time.
You're going to have to build your own control by subclassing a UIScrollView. You shouldn't have to mess with drawRect at all. An important concept, which is used by UITableView and UICollectionView, is dequeue'ing cells. The iOS 5 version of Apple's PhotoScroller demonstrates this concept with paging (the iOS 6 version replaces the custom paging with UIPageViewController). You'll have to download the old documentation to get the old sample code.
I'm currently building a timeline view, which I will open source at some point. It's somewhat based on the UITableView and works in horizontal or vertical direction. It dequeue's cells just like the UITableView. I'm not focusing on labels or scaling, but the concept of having inconsistent spacing in-between cells. To give you a head start, here are my dataSource methods I settled on:
- (NSInteger)numberOfCellsInTimelineView:(TimelineView *)timelineView;
- (CGRect)timelineView:(TimelineView *)timelineView cellFrameForIndex:(NSInteger)index;
- (TimelineViewCell *)timelineView:(TimelineView *)timelineView cellForIndex:(NSInteger)index;
Two of these calls are identical to what UITableView has, but it has a new call called cellFrameForIndex. What's significant about this call is that the TimelineView can guess an index and lookup the frame of the cell and see where it fits in the visible bounds. If it guesses a cell inside the visible bounds, it can simply iterate forward and backward until it finds the edges.
Currently the algoritm I'm using takes round(count * (CGRectGetMidX(timelineView.bounds) / timelineView.contentSize.width)) (for the horizontal direction). Basically what this does is takes the mid-point of the visible bounds of the UIScrollView and gets the percentage of what has been scrolled. Then it multiplies that by the number of cells. This works fairly well. When testing a random data-set with 100,000 records at random spacing the calls to cellFrameForIndex ranged from 8 to 150. I'm able to pull 52-60 FPS with this. I'm still working on it, and trying to find a better/quicker way to determine the index range. I'm trying to keep it down to visible cell count + 10 (max) iterations.
If you have time to wait, I'll update my answer to include a link to my GitHub project when I'm done. This could be a few days, to a week. I may add scaling. But you'll have to fork it and add labels and anything else you want.
Edit:
Here is my Github project: https://github.com/lukescott/TimelineView
UITableView is definitely not suitable. UIScrollView might be better but it is not very well suited for dynamic or very long content.
I believe the easist approach would be to do it everything by yourself - implement it by a UIView subclass with a drawRect. Of course, you should use UIPanRecognizer in the same manner as UIScrollView uses it.

Resources