在完成了 「客製化TableViewCell (Custom TableViewCell)」,接下來需要把參數帶到下一個view 裡。方法還滿多的。
This question seems to be very popular here on stackoverflow so I thought I would try and give a better answer to help out people starting in the world of iOS like me.
I hope this answer is clear enough for people to understand and that I have not missed anything.
Passing Data Forward
Passing data forward to a view controller from another view controller. You would use this method if you wanted to pass an object/value from one view controller to another view controller that you may be pushing on to a navigation stack.
For this example we will have ViewControllerA and ViewControllerB
To pass a BOOL value from ViewControllerA to ViewControllerB we would do the following.
- in
ViewControllerB.hcreate a property for theBOOL@property(nonatomic) BOOL *isSomethingEnabled; - in
ViewControllerAyou need to tell it aboutViewControllerBso use an#import "ViewControllerB.h"Then where you want to load the view eg.
didSelectRowAtIndexor someIBActionyou need to set the property inViewControllerBbefore you push it onto nav stack.ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil]; viewControllerB.isSomethingEnabled = YES; [self pushViewController:viewControllerB animated:YES];This will set
isSomethingEnabledinViewControllerBtoBOOLvalueYES.
Passing Data Forward using Segues
If you are using Storyboards you are most likely using segues and will need this procedure to pass data forward. This is similar to the above but instead of passing the data before you push the view controller, you use a method called
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
So to pass a BOOL from ViewControllerA to ViewControllerB we would do the following:
- in
ViewControllerB.hcreate a property for theBOOL@property(nonatomic) BOOL *isSomethingEnabled; - in
ViewControllerAyou need to tell it aboutViewControllerBso use an#import "ViewControllerB.h" - Create a the segue from
ViewControllerAtoViewControllerBon the storyboard and give it an identifier, in this example we’ll call it"showDetailSegue" - Next we need to add the method to
ViewControllerAthat is called when any segue is performed, because of this we need to detect which segue was called and then do something. In our example we will check for"showDetailSegue"and if thats performed we will pass ourBOOLvalue toViewControllerB-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ if([segue.identifier isEqualToString:@"showDetailSegue"]){ ViewControllerB *controller = (ViewControllerB *)segue.destinationViewController; controller.isSomethingEnabled = YES; } }If you have your views embedded in a navigation controller you need to change the method above slightly to the following
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ if([segue.identifier isEqualToString:@"showDetailSegue"]){ UINavigationController *navController = (UINavigationController *)segue.destinationViewController; ViewControllerB *controller = (ViewControllerB *)navController.topViewController; controller.isSomethingEnabled = YES; } }This will set
isSomethingEnabledinViewControllerBtoBOOLvalueYES.
Passing Data Back
To pass data back from ViewControllerB to ViewControllerA you need to use Protocols and Delegates or Blocks, the latter can be used as a loosely coupled mechanism for callbacks.
To do this we will make ViewControllerA a delegate of ViewControllerB. This allows ViewControllerB to send a message back to ViewControllerA enabling us to send data back.
For ViewControllerA to be delegate of ViewControllerB it must conform to ViewControllerB‘s protocol which we have to specify. This tells ViewControllerA which methods it must implement.
- In
ViewControllerB.h, below the#import, but above@interfaceyou specify the protocol.@class ViewControllerB; @protocol ViewControllerBDelegate <NSObject> - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item; @end - next still in the
ViewControllerB.hyou need to setup adelegateproperty and synthesize inViewControllerB.m@property (nonatomic, weak) id <ViewControllerBDelegate> delegate; - In
ViewControllerBwe call a message on thedelegatewhen we pop the view controller.NSString *itemToPassBack = @"Pass this value back to ViewControllerA"; [self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack]; - That’s it for
ViewControllerB. Now inViewControllerA.h, tellViewControllerAto importViewControllerBand conform to its protocol.#import "ViewControllerB.h" @interface ViewControllerA : UIViewController <ViewControllerBDelegate> - In
ViewControllerA.mimplement the following method from our protocol- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item { NSLog(@"This was returned from ViewControllerB %@",item); } - Before pushing
viewControllerBto navigation stack we need to tellViewControllerBthatViewControllerAis its delegate, otherwise we will get an error.ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil]; viewControllerB.delegate = self [[self navigationController] pushViewController:viewControllerB animated:YES];
References
- Using Delegation to Communicate With Other View Controllers in the View Controller Programming Guide
- Delegate Pattern
Further Help
from:
http://stackoverflow.com/questions/5210535/passing-data-between-view-controllers
iOS – UIStoryboardSegue detecting table cell and opening a viewController?
http://stackoverflow.com/questions/9371028/ios-uistoryboardsegue-detecting-table-cell-and-opening-a-viewcontroller
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Assume self.view is the table view
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
DetailObject *detail = [self detailForIndexPath:path];
[segue.destinationViewController setDetail:detail];
}
UITableView “selection” triggered segue
http://stackoverflow.com/questions/13989826/uitableview-selection-triggered-segue

How to make a push segue when a UITableViewCell is selected
http://stackoverflow.com/questions/22759167/how-to-make-a-push-segue-when-a-uitableviewcell-is-selected
drag From View Controller to View Controller

You will need to give an identifier to your segue:

Perform the segue:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:@"yourSegue" sender:self];
}
Now here is the thing, this will just perform the segue, if you ever needed to pass some data to that view controller. Then you have to implement the following segue delegate:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:@"yourSegue"])
{
//if you need to pass data to the next controller do it here
}
}