Creating manual segue correctly through storyboard and xcode

后端 未结 2 936
生来不讨喜
生来不讨喜 2020-12-15 06:14

I\'m quite new to xcode, and I am trying to develop a sample app that is basically an embedded tableview which has many levels. I have a plist which stores the cells of each

相关标签:
2条回答
  • 2020-12-15 06:51

    A couple of problems, actually:

    First, in that project you uploaded for us, the segue does not bear the "segue1" identifier:

    no identifier

    You should fill in that identifier if you haven't already.

    Second, as you're pushing from table view to table view, you're calling initWithNibName to create a view controller. You really want to use instantiateViewControllerWithIdentifier.

    Thus, the line that says:

    DrillDownViewController *rvController = [[DrillDownViewController alloc] initWithNibName:nil bundle:[NSBundle mainBundle]];
    

    should say:

    DrillDownViewController *rvController = [self.storyboard instantiateViewControllerWithIdentifier:@"TableView"];
    

    Third, your prepareForSegue was:

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if([[segue identifier] isEqualToString:@"segue1"])
        {
            dvController = [[segue destinationViewController] visibleViewController];
            [dvController setItemName:self->nameToSend];
        }
    }
    

    And it should be simplified to eliminate reference to visibleViewController, e.g.:

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if([[segue identifier] isEqualToString:@"segue1"])
        {
            dvController = segue.destinationViewController;
            dvController.itemName = nameToSend;
        }
    }
    

    Fourth, your DrillDownDetailController.m has this method:

    -(void) setItemName:(NSString *)itemName
    {
        if(!itemName)
        {
            itemName = [[NSString alloc] initWithString:itemName];
        }
        label.text = itemName;
    }
    

    There are a bunch of problems here, but you simply should not be updating the label.text here (because it might not yet be created!). You should just eliminate this custom setter method completely (just let Xcode synthesize the standard setter for you) and just change your viewDidLoad to read as follows:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        label.text = self.itemName;
    }
    

    Make sure you don't update UI objects until viewDidLoad!

    I haven't gone through the whole program, but with those four corrections I can tap on "SubItem1", and then "Cars", and then "BMW" and I see a detail screen that says "BMW". I think there are some problems with your plist on other items (e.g. the shoes entries are strings, and not dictionary entries and you get an error ... I presume you just haven't filled in your plist completely), but the above fixes correct the more significant coding issues.

    0 讨论(0)
  • 2020-12-15 07:00

    THE MAIN ISSUE IS HERE, you were creating a blank DrillDownViewController, not reusing the one from storyboards, see comments in code below

        -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
        {
            if([[segue identifier] isEqualToString:@"segue1"])
            {
                 [segue.destinationViewController setItemName:(NSString*)sender];
            }
        }
    
        - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
        {
            //Check the dictionary to see what cell was clicked
           NSDictionary *dict = [self.tableDataSource objectAtIndex:indexPath.row];
    NSString *titleName = [dict objectForKey:@"Title"];
    NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];
    
    NSArray *children = [dictionary objectForKey:@"Children"];
    
    if([children count] == 0)
    {
        [self performSegueWithIdentifier:@"segue1" sender:titleName];
    
    }
            else{
        //Prepare to tableview.
    
        //THE MAIN ISSUE IS HERE, you were creating a blank DrillDownViewController, not reusing the one from storyboards so it did not have a segue at all defined. instead do this:
        UIStoryboard*  sb = [UIStoryboard storyboardWithName:@"MainStoryboard"
                                                      bundle:nil];
        DrillDownViewController *rvController = [sb instantiateViewControllerWithIdentifier:@"DDVC"];       
        //Increment the Current View
        rvController.CurrentLevel += 1;
    
        //Set the title;
        rvController.CurrentTitle = [dictionary objectForKey:@"Title"];
    
        //Push the new table view on the stack
        [self.navigationController pushViewController:rvController animated:YES];
    
        rvController.tableDataSource = children;
    
    }
    
    
        }
    
    0 讨论(0)
提交回复
热议问题