I have a table based off Sam's Teach Yourself iOS Development's FlowerViewController, that, under didSelectRowAtIndesPath it goes to a website in a new nib (I tweaked part of the passing data). MY QUESTION: I would like to update this to, instead of going to a nib, to segue within a storyboard. I know that instead of using didSelectRow... I use prepareForSegue...but I can't figure out the details...

my I have ViewController.m with the following:

- (void)viewDidLoad {
    [self movieData];
    [super viewDidLoad];

    self.title = @"Movies";

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}


#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [movieSections count];
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [[movieData objectAtIndex:section] count];
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] 
                 initWithStyle:UITableViewCellStyleSubtitle 
                 reuseIdentifier:CellIdentifier];
    }

    // Configure the cell.

    [[cell textLabel] 
     setText:[[[movieData 
                objectAtIndex:indexPath.section] 
               objectAtIndex: indexPath.row] 
              objectForKey:@"name"]];

    [[cell imageView] 
     setImage:[UIImage imageNamed:[[[movieData 
                                     objectAtIndex:indexPath.section] 
                                    objectAtIndex: indexPath.row] 
                                   objectForKey:@"picture"]]];

    [[cell detailTextLabel] 
     setText:[[[movieData 
                objectAtIndex:indexPath.section] 
               objectAtIndex: indexPath.row] 
              objectForKey:@"detail"]];
    cell.detailTextLabel.numberOfLines = 0;

    cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
    return cell;
}


// Override to support row selection in the table view.
- (void)tableView:(UITableView *)tableView 
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    WebViewController *webViewController = 
    [[WebViewController alloc] initWithNibName:
     @"WebViewController" bundle:nil];

    webViewController.detailURL=
    [[NSURL alloc] initWithString: 
     [[[movieData objectAtIndex:indexPath.section] objectAtIndex: 
       indexPath.row] objectForKey:@"url"]];

    webViewController.title=
    [[[movieData objectAtIndex:indexPath.section] objectAtIndex: 
      indexPath.row] objectForKey:@"name"];

    [self.navigationController pushViewController:
     webViewController animated:YES];

}


#pragma mark -
#pragma mark Table view delegate



#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Relinquish ownership any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
    // For example: self.myOutlet = nil;
}


- (void)movieData {

    NSMutableArray *myMovies;

    movieSections=[[NSMutableArray alloc] initWithObjects:
                    @"Movies",nil];

    myMovies=[[NSMutableArray alloc] init];

    [myMovies addObject:[[NSMutableDictionary alloc]
                           initWithObjectsAndKeys:@"Movie1",@"name",
                           @"1.png",@"picture",
                           @"http://www.url1.com",@"url",@"Some information",@"detail",nil]];
    [myMovies addObject:[[NSMutableDictionary alloc]
                           initWithObjectsAndKeys:@"Movie2",@"name",
                           @"2.png",@"picture",
                           @"http://www.url2.com",@"url",@"Some information 2",@"detail",nil]];
    [myMovies addObject:[[NSMutableDictionary alloc]
                           initWithObjectsAndKeys:@"Movie3",@"name",
                           @"3.png",@"picture",
                           @"http://www.url3.com",@"url",@"Some information 3",@"detail",nil]];
    [myMovies addObject:[[NSMutableDictionary alloc]
                           initWithObjectsAndKeys:@"Movie4",@"name",
                           @"4.png",@"picture",
                           @"http://www.url4.com",@"url",@"Some information 4",@"detail",nil]];

    movieData=[[NSMutableArray alloc] initWithObjects:
                myMovies,nil];
}

I attempted to comment out the didSelectRowAtIndexPath and add the following for the segue, but the cell highlights and nothing happens (thankfully it doesn't freeze/crash, but there's nothing positive)

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    if ([[segue identifier] isEqualToString:@"movieSegue"]) {

        NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
        WebViewSegue *_webViewSegue = [segue destinationViewController];
        _webViewSegue.detailURL =
        [[NSURL alloc] initWithString:[[[movieData objectAtIndex:selectedRowIndex.section] objectAtIndex:
                                         selectedRowIndex.row] objectForKey:@"url"]];
    }
}

Then I want it to pass to WebViewSegue

WebViewSegue.h:

@interface WebViewSegue : UIViewController  {
    IBOutlet UIWebView *detailWebView;
    NSURL   *detailURL;
    IBOutlet UIActivityIndicatorView *activity;
    NSTimer *timer;
}

@property (nonatomic, weak) NSURL *detailURL;
@property (nonatomic, weak) UIWebView *detailWebView;
@property (nonatomic, weak) UIActivityIndicatorView *activity;

@end

WebViewSegue.m:

@synthesize detailWebView =_detailWebView;
@synthesize detailURL = _detailURL;
@synthesize activity =_activity;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle


- (void)viewDidLoad {
    [super viewDidLoad];

    [detailWebView loadRequest:[NSURLRequest requestWithURL:detailURL]];

    timer = [NSTimer scheduledTimerWithTimeInterval:(1.0/2.0) 
                                             target:self 
                                           selector:@selector(tick) 
                                           userInfo:nil 
                                            repeats:YES];
}

-(void)tick {
    if (!detailWebView.loading) 
        [activity stopAnimating];
    else 
        [activity startAnimating];

}


- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

-(void)wevView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Cannot connect"
                                                    message:@"Please check your connection and try again" 
                                                   delegate:nil 
                                          cancelButtonTitle:@"OK" 
                                          otherButtonTitles:nil];
    [alert show];
}

@end
有帮助吗?

解决方案

I've answered your question in another post on the site. See my answer here.

Specifically on how to pass data from a table to the next storyboard segue, first create a property for the data in the next storyboard segue (i.e. the destination view controller). Then set that property in the prepareForSegue method of the table (the source view controller).

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // needed if you have multiple segues
    if ([[segue identifier] isEqualToString:@"changeNameAndDate"])
    {
        [[segue destinationViewController] setDataProperty:self.tableData];
        // where dataProperty is the property in the designation view controller
        // and tableData is the data your are passing from the source
    {
}

其他提示

This is a lot of code to digest; you should try to simplify. But if I've read it correctly, your basic approach seems correct.

First, put a breakpoint on prepareForSegue:sender:, and make sure it's being called, and that the identifier is what you expect it to be.

Then put a breakpoint on viewDidLoad and make sure it's called when you think it should be.

I would pull the loadRequest: out into its own method and call it both in viewDidLoad and in setDetailURL:. It's likely that setDetailURL: is being called after viewDidLoad if all of this is in a single storyboard.


EDIT What I'm saying is that prepareForSegue:sender: is likely correct. You're problem is in the presented view controller.

- (void)reloadWebView { // Pull the loadRequest: out...
    [self.detailWebView loadRequest:[NSURLRequest requestWithURL:self.detailURL]];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self reloadWebView];    // ...and call it both in viewDidLoad...
    ...
}

- (void)setDetailURL:(NSURL *)URL {
    [URL retain];
    [detailURL release];
    detailURL = URL;
    [self reloadWebView]; // ...and in setDetailURL:
}

Also note that there is no reason for your timer. Just turn on your progress indicator in reloadWebView and turn it off in webViewDidFinishLoad and webView:didFailLoadWithError:. Your current approach makes it impossible to deallocate this view controller because the timer retains it forever.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top