Container View with multiple child views issue - ios

I am trying to develop a Table View Controller(having a navigation controller),where rows are connected to multiple View Controllers (TextField,TextView,TableView,DatePicker,ImageView etc.).
So I design like this,if I click on any row,it should open one UIViewController having container view and then place the appropriate controller in the container.All the same type of tableview rows are using same View Controller as a child view of the container.
I am able to place proper view controller(example - 1.TextViewController for Text View
2. Table View Controller for Table view 3. DatePickerController for Date Picker.) in the container depend on their the row type.
But I am little bit confuse about how to pick the data from the child view when I click the done button(2nd screen right top). i.e for child Text Field I have to pick the input data whatever I type in the input box. For child Table view I hide the done button,so as soon as user select the data 'cellForRowAtIndexPath' should get fire and pass the seleted data.
How to do that data handleing? where to write that?
Is there any other way to design this?

As #Suhail mentioned the best way to do it, in general, when you want to pass data from a child view controller to the parent view controller, or in some cases from a controller to previous displayed controllers (that are still in the stack), is by using delegate pattern. You can implement delegate pattern with iOS protocols or with blocks. In my opinion, both approaches have their pros and cons, for that topic you'll have to do little more google search since this is not the place to discuss it.
Let's define some cases for your case(not all the cases):
You want to send data from ChildTableViewControler to Field controller (screen 3 to screen 2)
In this case, from what I understood, both controllers are embedded in a parent controller, so you'll have to set parent to be the delegate to the two child controllers. You have to create one or two protocols depending on your actions or data you want to send to the controllers. Create a property called delegate (you can choose your own name) on each of the children, implement the methods on the parent view controller, whenever you add one of the children on screen, set the delegate property to be the parent view controller. Now whenever you want to send data to the other child, you'll have to call the methods declared in your protocols. Remember, you have access from the parent to both children via childViewControllers propery.
Short version: One/Two protocols for children, parent implements the protocol(s) and responds to child action.
You want to send data from Filed to TableViewController (from screen 2 to screen 1)
In this case you'll declare a protocol in the parent view controller, which will be implemented by the TableViewController.Declare a delegate (or whatever name you like) property in the parent view controller. When you add the Filed controller on screen, you set the delegate property to be the TableViewController. Now you can communicate with the TableViewController from the Field controller via delegate property.
Short version: one protocol in parent view controller, TableViewController implements the protocol and responds to TableViewController actions.
You want to send data from ChildTableViewController to TableViewController (screen 3 to screen 1).
This is the same as case 2.
One of my rule when I send data from view controllers is something like this: if I want to send data forward (to the next screen that will be displayed) then I use property/methods. If I want to send data backwards(to previously displayed controllers) then I use delegate/blocks.
And my last advice, please check the delegate/blocks implementations and how to use them before you start implementing one of the above solutions. You can have lots of troubles if you implement them wrong, especially memory issues and random crashes.
A little bit off topic, if the reader of my answer is a 9gagger then "sorry for the long post, here's a potato"

Related

Pass data between viewcontroller without changing views

As the title states, I'm looking to simply pass the information.
I have a tabbed view application currently, and the user inputs data into a text field, presses a button, then labels are filled with the entered text on the same viewcontroller.
I want to send that information to the other tab and fill a label.
I know I can do this via protocol or segues, however, I want to remain on the current tab. I haven't seen this as an example anywhere, only to switch the view to the other screen.
Anyone know how to simply pass the string entered and not change the view?
You are looking at this all wrong. You do not want or need to pass data between view controllers. If your app makes proper use of MVC (model, view, controller), then what you should be doing is updating a model. That model should broadcast that is has been updated. Anyone that cares about the model should react to those notifications as needed.
You have a tab controller with multiple view controllers. Two or more of your view controllers have an interest in the same data model. Both should reference the same instance of the data and be setup to be notified about changes to that instance of the data model.
One view controller, through its views, updates the data model. The data model then sends out a notification that is has been updated. Now the interested view controllers receive this notification and update their own views based on the updated data model.
No view transitions required. No segues required. No communication between different view controllers required.
Look at the documentation for NotificationCenter for ways to broadcast messages and for ways to listen for such messages.

How to create simple tableview and load data using Swift in iOS

I am trying to create an app for iOS using Swift but running into problems with the very basics.
To keep it simple I just want the app to initially be a single view application with a button and some sort of list view on the page. I believe a TableView is what is recommended here. When I click the button, I just want it to populate the list/table view with some entries, that's it. To start with, I don't care if these entries are hard-coded, I just want to get something working.
I have been looking at different samples but I am getting confused. Some of them seem to suggest using a TableViewController others don't. When I use a tableview controller, the UI I had created seems to get completely replaced with just an empty tableview list and the button is gone.
I previously have developed apps in Windows phone and found it a lot easier. I'd just add a listview object and in the click method of button, add the items programmatically etc. But this is my first time trying to create an iOS app and it seems a lot more confusing. There are delegates, controllers, views all seemingly needed in order to do something very simple.
Can anyone give me some basic step by step instructions about how to add a tableview to an application and load some data into it through a button click?
Make sure you are clear about the difference between a view and a view controller.
iOS uses the MVC design pattern (Model View Controller).
A view object displays contents to the user and responds to user interaction.
A model object stores state data.
A controller object drives the app logic and mediates between the model and the view.
A UITableViewController is a special subclass of a UIViewController who's job is to manage a table view. It has some extra support in it that makes it a good choice for managing a table view, BUT... there is one annoying thing about it. It is designed so the ONLY view it can manage is a table view. You can't use a UITableViewController if you want to add buttons, labels, and other UI elements to your screen outside of the table view.
What I usually do is to create a create a table view controller, create a separate regular view controller, add a container view to the regular view controller, and then use an embed segue to embed the table view controller inside the view controller. (you just control-drag from the container view to the table view controller.) That way you get the best of both worlds. You may want to create a protocol that the table view controller would use to communicate with it's parent view controller.
You should be able to find a tutorial online on setting up a table view controller as a child of another view controller using container views and embed segues. It's quite easy.

Do I need a ViewController container or a composite view?

I need to implement an accordion control for iOS. By accordion, I mean a UI like this:
I see two basic ways to do this, but I'm not sure which one to choose.
Method #1: Create a ViewController container, something like a UITabBarController, except that instead of showing tabs at the bottom, I draw a vertical stack of buttons, and when you tap one, the corresponding panel opens and shows the corresponding view controller's view.
Method #2: Create a composite view, add a bunch of views directly to it, and show/hide them as needed.
How do I choose here? What would make me want to treat the sub-units as view controllers vs views?
Generally speaking, if I can avoid it I try not to subclass UIView and instead do everything within UIViewController subclasses. A controller is usually required anyway (model/view glue code, user interaction, delegate stuff, notification handling, etc.), so if no custom drawing is needed it is usually possible to do without a UIView subclass.
In your case I could envision one reusable UIViewController subclass that represents a list entry. It has the following responsibilities:
Create two alternate view hierarchies (collapsed/button, expanded/panel)
Toggle between the view hierarchies in reaction to user interaction (with/without animation)
And another UIViewController subclass that represents the entire list. It has the following responsibilities:
Override the appropriate methods from UIViewController to make it into a container VC
Add/remove child VCs as appropriate to the internal model
Possibly adjust the container view in reaction to collapse/expand events in its child VCs

Xcode: How to call a method from a another view? Interaction between views

I have a view controller with another view controller as a child controller, and
a table view controller also as a child controller. My first child is like a toolbar with several buttons, but without any methods. What I need is, when a button from the first child is tapped, this view must call a method with the button's tag (all the buttons have
different tag) from the table view controller to filter the list. So, what I need to know control the interaction between these child controllers?
Thank you.
Handling changes, actions, or user interaction in other views is the essential use case of delegates. The best practice is to have the first view controller be the delegates of the child view controllers, and then as events happen in the children, they calls certain methods on their delegates to notify it. In response to the delegate calls you could then reload the table view, disable/enable buttons, or any other updates you need to do.
Other options for keeping values/state in sync between views are:
Core Data - best used for data
Key-Value Observation - best used for data
NSNotifications sent through NSNotificationCenter - best used for actions

What's the best controller to use for interactive books?

I'm creating an interactive touch book in iOS. I'd like to know what the best controller is to use for books. (e.g. UIViewController, NavigationController, etc.). I'd prefer to stay with storyboard options.
And secondly what is the best way to handle pages? A separate ViewController for each page? a separate view for each page?
UIPageViewController
From the docs:
Page view controllers allow users to navigate between view controllers
using the specified transition. Navigation can be controlled by the
user using gestures as well as programatically.
View controllers are either provided one at a time (or two at a time,
depending upon the spine position and double-sided state) via the
setViewControllers:direction:animated:completion: method, or provided
as-needed by the data source. Gesture-based navigation is enabled only
when a data source is provided.
To alter the behavior of this class, you should provide a data source
and delegate. This class is not intended to be subclassed.
As for your second question, yes it is easiest to manage each page as a view controller since UIPageViewController is a container view controller and it holds an array of view controllers.

Resources