iOS screen break open closed principal - ios

I am facing one issue, I have designed one screen which contain table cell. after some time I got new screen to be designed in which 90% cell design is same as I already implemented, but this time I don't want to make any separate custom view and reuse in already implemented table cell and new cell.
So, How can I reuse table cell in new screen without modification of existing one?
Does iOS UI element break open closed principal? or I am thinking in wrong way?

Your first option is to create a custom view that has the same design and embed that in each of your table view cells and customize the rest of the part.
Second, you can pass the state/type of the cell as per your screen requirements. Based on the state/type, you can hide/unhide the required elements.
Also, views are design components. If we modularise them well enough and keeps them separate from business logic, they won't come in way of breaking SOLID principles. Apple keeps it's logical and UI components in separate frameworks. For example, Contacts and ContactsUI.

Related

How do we restore the UI state of UICollectionView for current visible page, for a UIPageViewController which contains a large amount of pages?

We need to build a horizontal swipe-able page, with number of page range from 2 to infinity. User has the ability to add and remove any page.
We really do not want to create all and keep all UIViewController in memory. That is highly inefficient.
We hope, UIPageViewController can have mechanism, similar to UICollectionView cell reusing mechanism.
Since I'm pretty familiar how Android handling this case. Let me describe it below
When you want to have 100 swipe-able pages, Android will only create 2 (This figure is configurable) view hierarchy. If the view is not visible, the view hierarchy will be destroyed, and a new view heirarhy for the newly visible page will be created. All the view hierarchy recreation, is done through Fragment's onCreateView (Android Fragment is similar to iOS ViewController)
When you swipe from page 1 direcly to page 4, then swipe back again to page 1, the view for page 1 will be re-created via Fragment's onCreateView. However, how does Android restore multiple UI states in the page? If there is a RecyclerView (Similar to iOS UICollectionView) in page 1 being re-created, RecyclerView's previous scroll position will be restored via onRestoreInstanceState.
In Android, the mechanism 1 & 2, is pretty much offered by the Android framework out of the box. Not much work required at developer side.
I was wondering, how does iOS able to achieve the same thing?
I have seen a technique, described in https://stackoverflow.com/a/36876103/72437
However, it isn' clear, on how the UI state restoration state work? For instance, if I have an UICollectionView in page 1. How can I restore the UI state (scroll position) of UICollectionView, when I swipe back to page 1?
Use a UICollectionView.
If you need to have controllers for each cell, load the controllers in the re-useable cell on cell initialization.
UICollectionViewCells are UIViews with reuse functionality built on top; they are only de-initialized when the UICollectionView is de-initialized. When your cell is created for the first time, also create the view controller inside (which holds the actual view you want to reuse). Use the cell reuse and configuration calls (e.g. cellForRowAt(indexPath) and prepareForReuse()) to setup your vc/view inside the cell. Dependency injection is great in this flow. Prefetch if you need to load a lot of data or have slow response times.
iOS will also optimize the number of cells being reused at a time (really should never be more than say 20, there can only be so many on the screen), so you wont have to worry about maintaining a set or tracking how many instances you have.
Use a page view indicator if you need that, or make your own.
If you want to develop your own reuse system, study that of UICollectionView(Cell) first because they do this very well imo.

How are complex iOS screens made?

I'm trying my first steps in iOS development, and so far my app is going well. However, I've reached the point where simple UITableViews are just not cutting it.
For starters, I have a table view with two sections. I've implemented the method providing each section's title. But when I compare it to, for example, iOS's Settings screen, Apple's style (which I've seen implemented in other apps) looks much better, with better styling in the "section titles" and complex controls in the "table cells":
Now in my app, in some screens I would like to implement something similar to WhatsApp's settings screen. In this case, each "cell" does not have anything very noteworthy layout-wise, but I like the spacing between the different sections:
My last question is: when I am composing a cell, it is very clear to me how to implement a layout, its constraints, etc. Now imagine that I want to show a Table View showing a list of teams, and for each team I want to show the team players underneath, one player by line. It is not yet clear to me how I define layout contraints with an arbitrary number of elements. How would I approach doing this? Grid inside cell?
To sum it all up, my question is: are these screens TableViews with fancy styles and cells and more complex implementations? Or a different View that I am not aware of? Or even an empty canvas that they then compose "by hand"?
For context, I am developing with XCode 9, Swift, on a project with storyboards.
They are custom UITableViewCell cells (like the volume and profile avatar) or standard cell prototypes (WhatsApp settings are UITableViewCellStyleDefault with cell.imageView.image set.

iOS UIButton or Single Row UITableView For Dropdown Like Thing?

For iOS 7 and iOS 8, we're implementing these things that look like drop-downs, but each just launch a modal window.
What makes more sense, using 3 UIButtons, 3 UITableViews with 1 row, or something else? In the past, there would be more than one of these all lined up, so I would put them in a UITableView and set the accessoryView of the UITableViewCell. Using the cell was nice, but three UITableViews seem like overkill here and a maintenance hassel.
The closest post I found regarding this was one about using an UITableViewCell outside of UITableView
What would make the most sense is to follow the iOS design guidelines. Instead of trying to create custom dropdown menus (or worse: showing a drop down menu, but displaying a modal view when the user is expecting a drop down view), that UI could be replaced with 1 UITableView that has 3 UITableViewCells in it. The text on each cell would be the name of the setting to be changed and selecting the cell would push segue to the next page. This will give the app a uniform iOS UX; allowing users to know exactly how to use your app because it works similarly to other apps on their phone. Check out the Settings app on the simulator to see what I am describing.
I don't see any advantage to using a UITableView or a UITableViewCell. I think this is clearly a case for three UIButtons. You can set constraints to keep them nice and clean. One cool thing that might be worth investigating is using a unicode character for the downward arrow. That way you could have the tap feedback on the whole "thing" as you called it.
When I need to create sort of dropdown menus, I usually take advantages from UITableView, one above all is when you will need to add one or more selections in the dropdown you just need to change the data model.
UITableViewCells are easily customizable that means that you can create almost everything you want.
I think that your design doesn't adapt well to a mobile application, those kind of menu are more web style, with 3 buttons and a UIPickerView you can really improve the user experience and also adapt in a really easy way on the ipad embedding the picker in a UIPopoverController.
as i agree with #keithbhunter, but still if you want then may this links will help you.
http://code4app.net/ios/DXPopover/54741ca3e24741c56db03ca0
https://www.cocoacontrols.com/controls/kxmenu
https://www.cocoacontrols.com/controls/nidropdown

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

Objective C: How to implement a datagrid view (tables with multiple columns)

I am currently working on an iPad application that uses a table view to present data, I was inspired by the iTunes application in iPad that present it's data in multiple columns in a very nice and neat manner, and the most interesting thing is that during the portrait mode the itunes application displays data in 2 columns but when the user switches to landscape mode, it switches the display to 3 columns (since there are plenty of space to display data horizontally).
This is what i'm talking about:
but i found out that iOS SDK only supports single column for tableview (it would be nice to utilize the entire space provided on iPad screen to present data), i did some research and i found out that the best way to present data in multiple columns yet like spreadsheet style is to use datagridview instead, but iOS SDK did not provide any data grid view controls for iOS developers.
I found out over the internet some customized tables like:
AQGridView.
DTGridView.
and also the one from this:
http://usxue.is-programmer.com/posts/14176.html
and the one from this:
http://xebee.xebia.in/2011/04/14/building-editable-gridview-for-iphone-apps/
But sadly none of these ever met the requirements of the application i was working on.
Could you guys provide me some ideas or share some sample codes or links on how to display data in somehow-data grid view, to achieve similar effect used in iTunes application (as shown above).. Any form of help would be pretty much appreciated. Thank you guys!
The summary answer is, place multiple data "views" across in a single cell.
The more detailed answer:
Create custom views that represent the single cells you want. You can for this purpose make them resizable enough to work two across or three across (they will get loaded into 1/2 or 1/3 of the cells bounds).
Then make a custom UITableView cell, that can take two or three data items - load up an instance of the custom view previously created in the cell for each data item you have, placing them next to each other. You can have the cell do the view layout when groups of data items are added.
In the cellForRow code in the table delegate/datasource, you use your data source in groups of two or three (and report the row count accordingly) to pass along to the custom cell.
Sorry I can't share code, but I have used this technique before in other applications.
What's wrong with creating a UIView class to represent a single cell, and another that lays out an array of those cells in a grid? Put your grid view in a UIScrollView and you're about done.
UITableView is obviously a pretty complex class. Much of that is to make it very general, very reusable, and able to support a huge number of rows. Your class doesn't necessarily need to be that complicated -- if you have a fairly small number of cells, your "grid" could really just be a UIView in which you lay out cells in rows and columns. UITableView removes cells that aren't seen in order to save memory; you might need to do something similar if you have hundreds of cells, especially if they're large, but a few dozen probably won't require that.
In short, since you need a grid view for a particular use, you don't need to do all the extra work that would be required for a general, reusable solution.

Resources