iOS - Performance Issues with Embedded Table View in Storyboard - ios

A project I'm working on has a storyboard set up as follows:
Tableview controller (A) contains a tableview of static cells
Each static cell is a container view
One of these container views embeds another table view controller (B)
The table view of controller B is tableview with dynamic prototypes.
Everything works and renders appropriately, however I have begin to run into a performance problem when the number of cells in the embedded table view controller (B) becomes very large.
What seems to be happening is that iOS is allocating / attempting to render all the cells (ie calling cellForRowAtIndexPath), even those which are offscreen. This is because the embedded table is large enough to show all cells, because scrolling is disabled for this table and instead the root controller (A) scrolls the content.
Does anyone know a way to make this situation more performant when the embedded table view has a large number of cells? I thought about creating an artifically paged system where cells are only loaded when the user scrolls, however initial cells which have scrolled out of the view would still remain allocated, so I would have to set up some sort of dynamic allocation, which is what iOS already does if you simple use a single table view.
I have seen this design pattern proposed elsewhere and it seems Apple is really pushing adoption of containers as it makes for clean and modular code using storyboards, so I am hoping that there is a simple solution to this that I am missing.
Thanks.

Related

iOS need reusable table view controller

ios 7.1
Summary: When user segues to new table view controller, system allocates too much memory that's why I need some kind of re-usable or singleton table view controller.
I have a table view controller (let say vertical home) which has inner table view's(horizontal) inside of it's cells. If I wouldn't need to create horizontal tables, I could create a single table and manipulate it's cellForRowAtIndexPath method instead creating an inner one.
Anyway there is another functionality; there are buttons inside of the most inner cells and if user taps that, it triggers a push segue which navigates to another table view controller that has same vertical & horizontal structure. It is highly potential that user is going to go to those table view controllers lot's of times.
When monitoring the memory usage of application:
If user stays at home view controller and scrolls vertically, system allocates approximately 1 more mb per each cell which has inner table view. 1 mb is acceptable even it is great actually. Btw. I am using reusable cells to be able to decrease memory usage through those lines of code:
[tableView registerNib: customCellNib forCellReuseIdentifier:HorizontalContainerTableCellIdentifier];
cell = (HorizontalContainerTableCell *) [tableView dequeueReusableCellWithIdentifier:HorizontalContainerTableCellIdentifier];
If user triggers a segue; a new table view controller is created as desribed as here. and even if user doesn't scroll system allocates around 5 mb per each table view controller.
That means cost of creating a new view controller for each segue is too much. I can accept that my view hierarchy is not light weighted but as it can be seen in the 1st usage scenario if user scrolls vertically system is re-using pre-created cells and memory cost is not that much.
So which way should I follow? Do I need to subclass segues and redirect them to pre-initialized view controller and update it's table (like this)? By this way I can force the system to reuse cells. Or is everything normal and is it how it's supposed to be?
If you segue viewController, the older viewController will be pushed into the navigation stack and a new viewController will be created and also pushed into the stack. I think you can make the usage less by freeing tableView data in viewWillDisappear and reload them on viewWillAppear. Just trigger reloadData and return 0 in numberOfRowsInSectionthat will free the memory used by tableView.
It seems that was my mistake. Because the controller view which contains the most outer table view was not releasing at all. When I profile via instruments I have seen couple instances of same controller despite I have popped them already.
The root cause of that, ARC was expecting GUI elements defined as weak. I have changed property definitions as weak instead strong. Then ARC started to release controller instances.
However I have still memory problem. Because I am creating image context for each cell which consumes memory a lot.

Multiple UITableViews visible at once in one UIViewController

I have seen questions asked about mutliple UITableViews in one view but they all have only one table visible at a time. I am after something different please.
In my head I want four UITableViews visible in one UIScrollView inside one UIView. The four tables will be visible and populated at once. They will have a dynamic number of rows each so the scroll view will allow users to scroll off of the page to see rows that do not fit.
The tables would be two side by side and then below them the next two side by side so that you end up with a 2x2 square.
I can (sort of) wrap my head around how to code this in the controllers etc. but I cannot figure out how to organise the hierarchi. I have tried using the storeboard to layout the tables inside the view but 9 out of 10 attempts to drop controls in fail as I am obviously not fully understanding this.
Do I need to generate the UITableViews in the UIViews implementation file and add them as objects to the UIView? Or can I use the Storyboard?
Could someone please explain how the hierarchi of objects would be structured?
In my head it would be:
UIViewController
-> UiView
---> UIScrollView
------> UITableView
------> UITableView
------> UITableView
------> UITableView
But trying this in Storyboard doesn't work. I assume each UITableView will want its own UITableViewController and what I have read in other posts I would likey need to do this connecting in the UIViewController implementation file.
Any help is appreciated.
I think you might try to drag UITableViewController into your view Controller, at least I don't have that problem to add 4 table view into a scroll view.
here is how i added it
1.> Drag the scroll view control into view controller
Your view controller should look like this:
2.> Drag the table view control into the scroll view, and set the size and position of that table view
Your view controller should look like this:
3.> Then drag all the rest 3 table views onto Scroll view
But i would like to suggest a couple of things in your case
no using that much table view in the same view controller, it's a chaos in your codes to maintain all them. There are always better
options than 4 table view, maybe consider collection view. or even
separate the use flow.
If i were you, i won't use table view inside Scroll view, they are like scroll view inside scroll view, if you don't design the
interaction very very well, they become extremely hard to use.
If you still want to use four table view in the same view controller after all, you want to pay extra attentions on your table view datasource and delegate. very carefully handle all the cases.
Hope that helps you.
Tableviews are very customized scrollviews. I wouldn't put 4 of them on a scrollview, this wouldn't be very intuitive for the user as your finger would scroll the view in many ways depending on where exactly it touches the screen.
Instead, try having your 4 tableviews in a 2x2 pattern directly onto a simple UIView. This can be done inside the Storyboard.
As for filling up and using them, you have 2 ways :
A) Your UIViewController is the delegate and datasource of each of the 4 tableviews. When executing, you perform a switch on the first parameter (the tableview that called you) to determine the appropriate course of action.
B) You create 4 classes that each handle a single tableview, instanciate 4 objects inside your UIViewController and assign the UITableviews' delegate and datasource properties to these objects.
All technicality aside, 4 tableviews in a single screen is pretty crowded. Your design will definitely not fly on a iPhone, so I'm assuming iPad only. Even then, you should make sure that everything is visually appealing and the purpose of each control is clear. It's up to you, but I'd hate to see you work hard on an application only to see your efforts wasted because your visual design doesn't appeal to your users.
If the table views take up the entire region of the scroll view then they wont let any scroll events past to the scroll view that contains them, unless the scroll is horizontal.
For a simple one to one between a table view and a view controller, I would make each table view part of it's own UITableViewController (so you have four), and then make a UIViewController that adds each of the UITableViewControllers to it as a child.
This way you don't have to do any fancy logic around if statements on which tableview is asking for data, because the table view controllers only have one table view.
https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html

Split UITableview horizontally in IOS?

I have a SQLite project in IOS for Ipad. the database contains one table with a lot of products. what I want to do is separate this products into categories. so that i can make a separate tableview for each category. So my question is, can I use one table view with different sections, but put this sections side by side horizontally? The application only work on landscape mode. I hope the question is clearly enough. Thank's.
You can achieve this using a UICollection view (iOS6+ only, but there is an open source back-port here), or you can roll your own using scroll views.
The collection view scrolls horizontally, and has a number of items matching the sections in your catalogue.
Each cell of the collection view contains a header and a table view, holding the detail from the appropriate section.
Use child view controllers to keep your code clean - the view for each cell should be managed by its own view controller, which doesn't need to know it is in a collection view cell.

UIScrollView's Frame getting changed randomly

In my view I am using a UITableView that is controlled by a UITableViewController on the top half of the screen. The remaining screen is used for a UIScrollView that contains a view that is controlled by the main UIViewController.
When I perform a pull down to refresh in the UITableViewController, (for some reason if the number of table entries is less than or greater than the initial load value, the UIScrollView in the main UIViewController's frame gets changed to the screensize...
Essentially it breaks my paging unless I reset the scrollview back to the intialized size...
I have no idea why this happens as the UIScrollView is not used in the UITableViewController. The only scrollview that is used in the UITableViewController is the UITableView's to handle pull down to refresh...
Does anyone know why the main UIScrollView's contentSize gets changed randomly when it shouldn't even been accessible from the UITableViewController class?
Thanks
Just tried it here, and I can't duplicate your experience. I'm guessing you have an unexpected or inconsistent view/controller hierarchy? Look at the controller of the table and scroll views' common superview. Anything fishy there? Remember: view controllers manage sets of views. Container view controllers manage other view controllers and have special rules (see: The View Controller Programming Guide, esp. -addChildViewController:, etc.).
I'd suggest opening a blank project and trying to recreate the problem in its simplest possible form. If it's magically fixed, what's different? If it's still giving you trouble, send us a link so we can see the details of how you have things wired.

iOS: Which approach to take - x number of dynamic UITableViews

I'm trying to figure out the best approach to take in my current situation.
I have an app with a navigation bar controller that at one point needs to present/show x number of table views.(x meaning that the number is decided by communicating with a server)... The table views will each represent e.g a class or a group... (this could be school classes or kindergarden classes)
Okay... So... Only one table view should be visible/in focus, but the others should be accessible from the same view...
E.g. The view is presented. A table view for class A is shown. The user can swipe to get class B
I've been considering different approaches, but I can't figure out the best approach to this...
I considered using a scroll view containing the x table views, where only one was visible at a time, and the others could be scrolled in view... But, after doing some research, it seems that Apple recommends that you shouldn't place table views in scroll views, because the scrolling can interfere with each other..
Using a tab bar... Again, my research told me that the navigation bar should be placed in the tab bar, and not the other way around... And I only want a tab bar on this view, and not earlier in the app..
Use a custom tab bar that better supports my "needs"...
Any ideas??
In my opinion the most important thing is that only one UITableView have to be visible. The best solution (ie the simplest) is a first UITableView with its UITableviewController that lists all the classes/categories A,B,.. retrieved from the server, and a secondary UITableView (ie controller /+ tableView) that will display the detailed list for a given class of items. You may also continue to drill down your data tree other sub-tableViews.
I recommend to use a UINavigationController to push/pop your tableViews when a cell is selected.
Stacking several UITableViews in a unique container view seems too much complicated and may lead to tricky and/or unwanted states.

Resources