Creating an array of view controllers? - ios

I'm brand new when it comes to app development so this might be a stupid question.
So i have made a UI table. It is customizable, as in users can insert or delete rows. I want to allow users to click on a table cell and it'll direct them to another view controller. All the view controllers will look the same for each cell (sorta like a template). Any idea how to implement this using storyboard?
Appreciate it!

You do not need an array of view controllers. All you need is one view controller, which gets instantiated when the user clicks the cell to navigate to it, and gets deallocated as soon as the user closes the screen to go back to your main view controller.
All you need to implement this in your storyboard is adding a push segue from a cell or a button in your main view controller to your "detail" view controller. When the segue gets triggerred, your code gets a chance to configure the newly created "detail" view controller in the prepareForSegue:sender: method, before the controller's view appears on the screen. This is the place where you customize the data that shows up in the detail view (presumably, depending on the particular row in the table that has triggered the segue).
Here is a link to a good tutorial explaining how to build a master-detail application with Xcode and storyboards.

In storyboard you create a viewcontroller that will display the data after a cell has been selected, you will only need one and not an array. Link it from the tableviewcontroller to the new viewcontroller. Click the segue in Xcode and in the inspector give it a unique identifier.
tableView:didSelectRowAtIndexPath: will get called when you select a cell, here you can perform the segue:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedObject = ... // store the object that was selected
[self performSegueWithIdentifier:#"mySegue" sender:self];
}
In your tableviewcontroller you make sure you implement prepareForSegue:sender:. Here you can hand over the correct model object to populate your destination viewcontroller with data.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString:#"mySegue"])
{
MyDetailViewCotroller *controller = [segue destinationViewController];
controller.dataObject = self.selectedObject;
}
}
Check out this example code from Apple (does not used Storyboard though): http://developer.apple.com/library/ios/#samplecode/SimpleDrillDown/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007416

Related

ECSlidingViewController - adding UITableView and segue to another ViewController

I am trying to create push segue from view. Maybe image would be best for describing:
I started from sample ECSlidingViewController project (BasicMenu) and I am trying to expand first ViewController (Home) to another ViewController. I get it and I can go from selected row in tableView to the controller. But when I am in controller and I tap on Back I am at different screen from first one (it's blank screen with button at upper left). I guess I must set something more to get this working but I don't know what. Thanks
Updated:
Code from first view controller to go to next view controller:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Find the selected cell in the usual way
UITableViewCell *cell = [self.searchResultsTableView cellForRowAtIndexPath:indexPath];
[self performSegueWithIdentifier:#"selectedSegue" sender:cell];
}
I found that the problem is with code in method didSelectRowAtIndexPath. When I removed it. The segue is performed well and I go to other view controller and when I tap on top left button I get back where I was. It's okay.
So I guess the real problem was with sender in performSegueWithIdentifier.
But I need send to new controller some information about selected row. So I used this answer.

How to use segue to pass taken photo

I want to pass a photo taken in the first view controller to a second view controller. I want the user to take the photo in the first view controller and then crop in in the second view controller and then save.. So its like.. User take photo→crop→save. I just want to do this simple task but taking me days to get the segue go right.. Is segue the best way to do this? or is there a more easier way to do this task. I am a beginner in objective -c so its making me confused with segues and all the stuff.
You need to implement prepareForSegue:sender: in the source view controller. This will give you access to the destinationViewController via the passed storyboard. Then you can set the image so its available when the destination view controller is displayed.
As far as segue is concerned you need to create a segue arrow using storyboard by dragging arrow from first view controller to second view controller, and most importantly you need to give the segue an identifier or name.
For firing you segue you may do it programatically, like:
[self performSegueWithIdentifier:#"ShowSecondScreen" sender:self];
For handling things when segue is fired you need to write prepareForSegue() method, you may pass any object from current viewController to next viewController:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ShowSecondScreen"])
{
SecondViewController *secondViewController = segue.destinationViewController;
secondViewController.imageObj = image;
}
}

iOS: Storyboard Segue loads before class method call

I have two scenes. A regular, full-screen iPad view and another popover view. Tapping a button loads the popover view with no problems. In the popover view I have a button that will perform some action and is also linked to a storyboard modal transition.
The idea is that pressing the button from the popover view will save the user's selection state and send that data to the main view. I have no issues with the data saving, that works just fine.
The issue I am having is that when I press the button from the popover view, the main view's viewDidLoad method actually completes before the popover view's IBAction method does. So the main view gets the data, but since the view already loaded it is not able to update the label in time.
I tried creating multiple popover view scenes and added multiple buttons to the main view that will link to these new scenes. The weird part is that some of them work just fine. Some of them will perform the IBAction method and then it transitions back to the main view via a modal transition. There seems to be no rhyme or reason why one loads before the other.
I suppose a possible solution would be to perform the transition manually within the IBAction method of the popover view. I am definitely new to this so there may be something fundamental about transitions that I am missing.
In the view controller of view on which the button is present... When segue is going to be performed. You can pass data in
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_NAME_HERE"])
{
// Get reference to the destination view controller
YourViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
[vc setMyObjectHere:object];
}
}
This method is called before the view is loaded..
If you are calling a popover so the main screen should not call viewDidLoad method because the main view still on the back. It should be calling the viewWillAppear and the viewDidApper methods instead.
Can you check this? I think you should refresh the main screen after one of these two methods are called.
Give it a try and tell me the results.

UINavigationController code push to UIViewController not working correctly

I am having an issue when I am pushing to a UIViewController by code from another UIViewController which has the same UINavigationController.
Notes & assumptions:
I created all my UIViewControllers using IB but want to push between them using code.
Both UIViewControllers contain UITableViews: The first to select search criteria & the second to display the results.
"LT" stands for League Table in my class names.
I have three classes in my UINavigation Controller:
LTMasterNavController - of type UINavigationController - owns the properties & results across all the subsequent view controllers. LTResultsViewController retrieved the results from here once LTOverviewViewController has generated them.
LTOverviewViewController - of type UIViewController containing a UITableView. Used to select the filters to be displayed in LTResultsViewController.
LTResultsViewController - of type UIViewControllercontaining a UITableView. Used to display the results from the LTOverviewViewController
Please find my code on the Dropbox link below:
https://www.dropbox.com/sh/9m37y4f1gws99lf/VGNloaLSVO
When the "Show League Table" button is pushed in LTOverviewViewController I want the program to get the results from the filters & then immediately push to the LTResultsViewController.
With this code it pushes to the LTResultsViewController however the view appears to contain nothing. It is black with no UITable View & you cannot select anything.
In testing/debugging I created another button in LTOverviewViewController called "Push to Results" and connected it to LTResultsViewController as a push action in IB. It worked perfectly then when pushing the "Show League Table" button and then the "Push to Results" button, however I want it to happen without user having push that second button. Been stuck on this for days now so any help would be greatly appreciated!
Many thanks,
James
With storyboards and segues this is fairly simple. In the storyboard, click on the connection between the UIViewController you want to transfer data between, I guess between LTOverviewViewController and LTResultsViewController, and give the segue an identifier name: say ResultsSegue.
Now, in the LTOverViewController, you need to implement this method:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
In this method you will identify the segue name and the destinationViewController and pass the data you want the new view controller to have. Here is an example:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ResultsSegue"])
{
LTResultsViewController *viewController = [segue destinationViewController];
[viewController setData:self.data];
}
}
When the storyboard wants to use this particular segue, this method will be called and executed before moving on to the new viewController.

iOS - UISplitViewController with storyboard - multiple master views and multiple detail views

I'm trying to put together an iPad app using UISplitViewController and storyboards. The master view starts with a navigation controller linked to a table view of 6 menu options. Each cell in the table pushes a different table view controller onto the navigation stack. This is working fine for the master view. Each master view has a table list which when clicked needs to display a different view controller in the detail pane. I've currently done this with a segue set to 'Replace' and 'Detail Split' which works the first time a row is clicked, but as soon as you click another row in the master view, or rotate the device then the app crashes with EXC_BAD_ACCESS.
I'm fairly sure my problems are to do with how the delegate is setup for the UISplitViewController. I'm confused as to how this should be used when I have multiple master VCs and multiple detail VCs. Where should the delegate code be placed - master or detail? Do I have to implement the UISplitViewControllerDelegate protocol events in every view controller?
Any help appreciated.
If the split view controller delegate was the detail view controller that had been replaced, this is the cause of the crash. The replaced detail view controller is being dealloc'd and so the split view controller delegate is no longer a reference to a valid object.
You can update the delegate in prepareForSegue:sender:. For example:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"MySegue"]) {
UIViewController *destinationViewController = [segue destinationViewController];
if ([destinationViewController conformsToProtocol:#protocol(UISplitViewControllerDelegate)]) {
self.splitViewController.delegate = destinationViewController;
}
else {
self.splitViewController.delegate = nil;
}
}
}
Which view controllers you use for delegates is dependent on your view controller hierarchy. In the simplest case, any view controllers that are assigned to splitVC detail will probably need to be delegates. You may want to base them all on a common super class that handles the shared split view controller delegate logic.

Resources