horizontally and vertically paging UIScrollView, i.e. multi directional paging - ios

I'm looking for a custom component or mini-framework that is capable of handling multi directional paging! Multi directional by means of supporting horizontal and vertical paging simultaneously!
I'd actually like to display data like a grouped UITableView does, grouped by individual sections and rows. Consider the following data example:
Section-A: row-1, row-2, row-3
Section-B: row-1
Section-C: row-1, row-2
This is obviously a standard use-case for a grouped UITableView and nothing special, right?
What i'd like to acomplish is, displaying the above data as paging views!
So i.e. when i page horizontally, paging is section based and i move from Section-A to Section-B etc.!
When i page vertically, i "page" through the single "rows" of a section etc.! I hope you guys get the point!
Technically this would be obviously achieved by nesting 2 UIScrollViews with enabled paging, restricting the single UIScrollViews by either vertical or horizontal paging. Then populating the scroll-views with data (i.e. views) in the right manner etc.
Another requirement would be to have a dynamic or semi-dynamic behavior! Dynamic by means of having the possibility to add "sections" and "rows" afterwards. Much like the UITableView behaves actually, with "cell" reuse etc.!
(Semi-Dynamic by means that i don't need dynamic "row" insertions/deletions etc., just a simple "reloadData" would be sufficient)
So i looked for example into Andrey Vits ATPagingView of his SoloComponents!
ATPagingView looks like a promising foundation for solving my problems! I thought of extending the functionality to acomodate my requirments but would like to ask for advice on stackoverflow first!
So what do you think on this guys?
Is this actually a use case for a grid component?
Is there maybe a component or framework out there already matching my needs or was there never a need for multi directional paging views until yet! ;)

Right now i'm experimenting with ATPagingView for myself and i find it very useful for its purpose. It provides sort of a endless paging solution with cell reuse and is easy to set-up with only 2 delegate methods.
Why not wrap single ATPagingView instances into one "parent" UIScrollView, where each ATPagingView represents a "section" in your use case! Inside every ATPagingView you would then have pages as your "rows". You could set up the outer (i.e. parent) UIScrollView to page only for example horizontally and the single ATPagingViews to scroll vertically.
You'd need some boilerplate code (i.e. something like numberOfSections etc.) in the outer UIScrollView to manage the "inner" ATPagingViews, but that would be a feasible approach i think.

Related

Create a listing inside of a ScrollView

I am writing a Swift app, and on my main screen I have a long scrollview with several regions of content in it (upcoming events, announcements, and then featured products, and finally some basic info). So it's this really long scroll, and you can swipe down to the bottom.
So visualize 4 boxes, if you will, stacked vertically.
The 3rd box shows featured products. This can be anywhere from 1 to 30 items, depending upon any filters the user has in their settings.
My first try was using a UITableView for region#3 inside of this parent scrollview, but the problem is it only shows the first few items/rows and then the rest you scroll inside the table (which is the default/natural behavior of a table, right?). Unfortunately, the requirement I have is that the inner table can't scroll - it needs to display everything at once and you have to scroll (in the main UIScrollView) to get to the bottom (not scroll inside the inner uitableview scroll). Also, everyone seems to say don't use UITableView inside of a scroll.
So how do I create some sort of list where I create one template (like how you would in a xib/tablecell, and then assign a data source to it, and then repeat down without scrolling? Should I use a tableview after all, and just make the height of it very high and turn scrolling off?
Do I somehow instantiate xibs in a for loop and assign them dynamically to some view?
Thanks so much!
Sounds like you want a Table View with Grouped style. That would make it fairly easy to keep your "4 boxes" segregated, and your "3rd box" would simply be 1 to 30 rows in that section.
On note: you don't want to have a "very tall" table view - or any other type of view, for that matter. You want to allow iOS to manage memory for you, and to load and display only those parts of your content that is visible at any one time.
In other words, use a table view like its designed to be used :)

How to wrap self sizing UICollectionViewCell

My goal is to have a Swift implementation of a UICollectionView with dynamic content where each cell hold parts of a sentence. Each part of the sentence can be edited by the user. The problem is that some parts of a sentence might be longer than the container itself. Using sizeToFit is not an alternative because all content should have the same font size to maintain readability throughout the collection view.
Right now the behaviour I get, when I have a part of a sentence longer than the container is the following:
As you can see the third row has leading ellipsis.
What I would like to achieve is the following, the overflowing part of the cell should wrap as analogous to a span tag in HTML, like so:
Is this possible? How can I achieve such a thing?
As far as I can tell, it's possible but complex - here are a few pointers of what I'd say you're going to need:
2 additional collection view cell types: in the first, only the left edges are rounded, in the second only the right
Use Core Text API to measure where your text needs to be wrapped
In your datasource, you're going to have to then recognize the situation before you create the cells and then instead of creating a single cell, you create two, using those new types you have.

When to use UICollectionView instead of UITableView?

I found that UICollectionView is like an upgraded version of UITableView introduced in iOS6, but when should I choose UICollectionView instead of UITableView?
There are still Apps using UITableView, if UICollectionView can do anything UITableView can do , why people still use UITableView? Is there a difference as far as performance is concerned?
Thanks!
That depends on the requirements. How the application flows determines which type of UI to integrate into the application.
People mainly use the UICollectionview for creating types of UIs with multiple images shown in a grid. This would have complex logic using UITableView, but with UICollectionview, it would be easy.
When using UICollectionview, you don't need to set buttons with tags or other things by getting selected items values. You can simply get -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath and in UITableViewDelegate:
`-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath`
You get the selected row instead of the item, so for creating grid or modified items, using UICollectionview is best.
For the listing details of each item, people use UITableView because it shows more info on each item.
Apple Docs:
UICollectionView Class Reference
The UICollectionView class manages an ordered collection of data items and presents them using customizable layouts. Collection views provide the same general function as table views except that a collection view is able to support more than just single-column layouts. Collection views support customizable layouts that can be used to implement multi-column grids, tiled layouts, circular layouts, and many more. You can even change the layout of a collection view dynamically if you want.
UITableView Class Reference
A table view displays a list of items in a single column. UITableView is a subclass of UIScrollView, which allows users to scroll through the table, although UITableView allows vertical scrolling only. The cells comprising the individual items of the table are UITableViewCell objects; UITableView uses these objects to draw the visible rows of the table. Cells have content—titles and images—and can have, near the right edge, accessory views. Standard accessory views are disclosure indicators or detail disclosure buttons; the former leads to the next level in a data hierarchy and the latter leads to a detailed view of a selected item. Accessory views can also be framework controls, such as switches and sliders, or can be custom views. Table views can enter an editing mode where users can insert, delete, and reorder rows of the table.
Here's my criteria:
If a UITableView can do it, use it
If a UITableView needs lots of code to do it or can't do it at all, use UICollectionView.
You have to consider the restrictions on UITableView before making a decision: It's a single column. And you can only customize the cells, but not section backgrounds and such. So if you have a straight-up list of things with no extra frills - that looks like a bog standard iOS view, basically - then use UITableview. If you have custom insets, or a border around each section, use UICollectionView.
I'm actually considering UICollectionView for all things simply because it's very expensive when you start developing your view as a table view, then later find out it can't do that one thing that you need it to do. 1st hand experience ;)
Edit after even more experience with the two: Disregard that last paragraph. UICollectionView requires a lot of boilerplate code to make it work like a UITableView. Use UICollectionView only when really needed. ;)
For simple lists and forwards/backwards navigtaion, use UITableView.
If you need a high degree of customisability, use UICollectionView.
Generally speaking, in software development, it's best to choose the approach which represents "The Simplest Possible Thing".
EDIT: As of iOS 14, UICollectionView can now do lists as well and is now the recommended approach. See this session from WWDC20 for more information and implementation details: https://developer.apple.com/videos/play/wwdc2020/10026/
According to my point of view main difference between collectionView and tableView is that
TABLEVIEW --> show list of items in only one column.
COLLECTION-VIEW -->show list of items in multiple column.
Hope it will help you.
If you choose UITableView for iPhone, make sure you have considered your iPad strategy first. If you want an iPad-specific layout, you may want that single-column layout to become a grid.
Although it's not required, I always use a collectionview. That way I can easily adapt how my collections are presented for differing resolutions. A plus is that it's ready to quickly add new types of cells when refactoring in the future.
I see no point of tableviews. It's very simple to use a collection view to represent a table. IMO.
From my personal experience the two elements should only be compared loosly.
TableView
A TableView is a UI element designed for showing data in a list format. There is certain functionality that comes as standard with a UITableView, such as:
Accessory View
Cell Selection Style
Editting Style (Delete and edit buttons).
The above elements enhance the usability of data when displaying and interacting in a list format. Such as viewing emails.
CollectionView
A CollectionView is a UI element designed for showing content using a custom layout (usually anything that isn't a list). CollectionViews improve functionality of displaying data in completely bespoke layout styles and also dynamically changing layouts on the fly. Some examples are:
Horizonal Lists
Photo Galleries
Thumbnail views
Carousels
Dials
Laying out elements on a map
etc.
CollectionViews also allow for multiple selections.
Conclusion
As you can see from the above, both have completely different use cases and are designed for enhancing the development and usability of their own specific data sets.
If you are looking at displaying anything in a list style with the followin interactions:
- Adding
- Deleting
- Re-ordering
Then a UITableView will simplify this process by providing the support straight out of the box.
Anything else, you should leverage the benefits of CollectionView as you have more flexibility.
Its totally dependent on how your data to be shown.
As mentioned by many above, if you require only single set of data and that too not complex, go for UITableView else use UICollectionView.
UICollectionView is customization friendly.
If you are dealing with multiple cell heights or so, then go for UICollectionView.
Both are depends on the requirements. Table Views also have support for a variety of editing scenarios. This support has not been implemented in the Collection View classes.
If you are converting from a Table View that relies on these methods, expect to do a little extra heavy lifting in the Collection View.
Collection View section headers can be placed anywhere within the view.
and UITableView don't need to set buttons with tags or other things by getting selected items values.
In practice, everyone uses UICollectionView that I've come across, when they only need a UITableView. "It's one-dimensional. It goes up and down. Why are you adding unnecessary delegate methods for layout AND data?". I once spent an extra 2 hours helping a startup find out why their UICollectionViewCell got squished because the owner, who didn't read the Animations manual, nor HIG, nor the UICollectionView guide, decided to use it and add variable heights and anims. Needless to say, he gave himself a headache and much lost time on a non-business-critical issue he could have avoided by simply using a table cell, since there's no extra layout delegate + Nib.
Let me get this straight, I am all for UICollectionView's when your data and display need it. They're very powerful. But in practice, most people I've seen have been using them on lists.
This brings up another flaw. They're also used on short, constant lists that won't change, ever. In this case, just make a Xib. Or write a custom view that stacks them. Why? Because you don't need the memory management for 5 sets of labels with a button or switch. If they might change, then yes, use a list. If you want physics, then UICollectionView works well with a some cool effects. But do you really need to add 5 delegate methods and a layout system for 5 labels that will never move?
Also, I'm not forgetting that iOS has a native stacking view now too. I can never get it to deform how I want, even though I'm quite adept at the 2D and animation systems, so I never use the built-in one.
All I'm saying is, define your requirements. Maybe you don't need either of these, if your UI isn't adding/removing items and refreshing itself. Or maybe you want to write a Card Game and throw them out virtually on a table, then use UICollectionView with a physics system for its layout guide.
Personally I think the UICollectionView can do most of the work which UITableview can do. well, at the same time, it's more complex to use.
I suggest you use UICollectionView as TableView just in case your manager change requirements in the future.
Based on our need we are choosing TableView or CollectionView.
Example:
For phone contacts tableView is best option.
For photo gallery, collection view will be best option.
I had this issue in my current project. Which to use. In my case it was simple really. I needed both. I needed my view to look like UITableView and also to change its change / layout. So, UICollectionView was used. I also use UITableView everywhere I don't need any extra customisation. Since UiTableView comes with a default layout that includes images and text - I use it for simplicity.
Based on our requirement we choose UITableView or UICollection view.
If we want to display images or items in grid type or if we need more customisability we use UICollectionview.
For listing each item with details and subdetails we use UITableView.
UICollectionView:
The UICollectionView class manages an ordered collection of data items and presents them using customizable layouts. Collection views provide the same general function as table views except that a collection view is able to support more than just single-column layouts.
UITableView: A table view displays a list of items in a single column. UITableView is a subclass of UIScrollView, which allows users to scroll through the table, although UITableView allows vertical scrolling only.
As per my view for Grid View display use UI Collection View.All other list view use UITable View

Design for annotating UICollectionView selections with additional controls

Using UICollectionView and excellent help given on here on StackOverflow, I've been able to build a "Gantt Chart" style control for my iPhone:
Cosmetics aside (I'm doing the functional right now, I've got a graphics designer on tap to look at colors and all that).
Background aside, the spans were relatively straightforward to do with a custom UICollectionViewLayout subclass. Each span is an item.
But I need to add some functionality, and am unsure how to proceed. Where I'm trying to go is illustrated roughly as:
Sketchy cosmetics aside, the point is that I want to "annotate" whatever the currently selected span is with additional information (I promise to find someone to help me look it pretty). And I want them to be active, I'm not sure if it brings up an editing control or does drag, but I want to be able recognize gestures on either the numbers or the bold lines and do things with them, distinct from touching on the span which drives selection.
I can think of (at least) 3 ways to try and implement this:
Use supplementary views. Cause selection to invalidateLayout, detect the selected state in my prepareLayout, and generate additional layout attributes for the two anchors. Implement a subclass of UICollectionReusableView which does the drawing, and adds touchable subviews (or its own gesture recognizers). This feels... wrong. I get the idea that supplementary views are more for headers and footers, not for controls that come and go as the selection state changes. But maybe it's an appropriate extension of the facility?
Use the backgroundView (or selectedBackgroundView, not sure it matters) of my current SpanCell class (which is a subclass of UICollectionViewCell). As long as I disable clipsToBounds, I can draw the annotation around the bounds of the span. I'll have to give it some knowledge of the big picture to find the endpoints, but that's not too offensive. I would just show/hide this view in response to selection changes. This seems like the best way to do it.
Do it in the main backgroundView of the entire UICollectionView. As shown, I've already got a specialized backgroundView which shows the the current time grid, strip style. I could further extend this view to draw annotations and manage touchable sub controls in response to selection changes. This would give me most direct implementation, but it feels like I'll end up with a big monster "doing too many jobs" object for the background.
Question then, for those who have more experience, is which route would you go? Would it be one of the above 3? Or something different? And why?
While your question is very technical with UICollectionView implementation, which I am not very familiar with, this seems like a job for the container (in this case, the collection view). Imagine you need your annotation to consider, in addition to the selected item, other items? Like for example, avoiding collision between annotation lines and another item?
For me, option number 3 seems like the most correct one. If you fear a large class, you can extern it to an annotation controller class, which should be notified whenever the annotations should be updated.

iOS UI development: approach to building document "selector" screen

I'm looking to build a document "selector" screen, similar to Pages and Numbers on the iPad/iPhone:
I come from a WPF background and have some iOS experience. That being said, I'm looking for a good approach to building something like the tile-based interface Apple uses for opening documents in Pages.
I'm not concerned with the Folder animation.
What is the best way to approach building just the tile interface? I'd imagine I'd build some sort of view that sits within a UIScrollView - but it's the nature of that subview that I'm a little confused about. Does iOS have any wrap-panel or grid-like controls I could load a set of tiles (i.e., documents) into?
What do you guys think?
I don't know of any third-party classes to handle this for you, but there might be some out there.
The basic structure will be a UIScrollView containing a set of views, each representing one cell on the grid. You set the scroll view's contentSize based on the total number of tiles. Then you create tile views on demand, and place them inside the scroll view.
The scroll view's delegate object will be responsible for monitoring the scroll position, putting down tile views as they become visible, and (optionally) removing tile views that move out of view. This is basically how UITableView works: there are only about six or so instances of UITableViewCell at any given time, they are recycled as you scroll up and down the view. (Imagine a train where somebody at the back end is pulling out the rails and passing them forward to somebody in the front, putting them down in front of the train. As far as the train knows, the rails go on for miles.)
If you wind up having to place all the views yourself, take some time to learn the CGRect family of methods, including CGRectDivide. They will be useful in laying out the views and also in computing what's visible and what's not.
There are a few third party classes/libraries you can get to produce this functionality, AQGridView comes to mind. But there are no default easy classes for this.
If I was to develop this type of implementation, I would subclass UITableViewController. Expand it to have columns. Then subclass a UITableViewCell to display the image. That way all the container code and everything would already be there, and all you have to do is customize it to f it your needs.

Resources