简体   繁体   中英

Pushing a new ViewController from a ViewController that is embedded in a TabBarController and NavigationController

I have a tab bar controller that has a navigation controller embedded and then a view controller from there. In that view controller I have a table and I'm trying to display a new view controller when the user selects a row.

I'm trying to build a contacts page (bringing in iOS contact information) and displaying it.

Here is what the StoryBoard looks like

在此处输入图片说明

On cell select I want it to move to the Single Contact view. The code that pulls in the contacts to show on the table works just fine. Here is the PublicContactsViewController class

#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import <Parse/Parse.h>
#import <iAd/iAd.h>
#import "SingleContactViewController.h"
#import "Person.h" 

@interface PublicContactsViewController : UIViewController <ADBannerViewDelegate,UITableViewDelegate, UITableViewDataSource>
@property (strong, nonatomic) IBOutlet ADBannerView *banner;

@end

#import "PublicContactsViewController.h"

@interface PublicContactsViewController ()
@property (nonatomic, strong) NSMutableArray *tableData;
@end

@implementation PublicContactsViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    _banner.delegate = self;
 //   self.title = @"Public Contacts";
    self.tableData = [[NSMutableArray alloc]init];
    [self getPersonOutOfAddressBook];

}

#pragma mark - Address Book Methods

- (void)getPersonOutOfAddressBook
{
    CFErrorRef error = NULL;

    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
    if (addressBook != nil){
        NSLog(@"getPersonOutOfAddressBook - addressBook successfull!.");

        NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
        NSUInteger i = 0;
        for (i = 0; i < [allContacts count]; i++){
            Person *person = [[Person alloc] init];

            ABRecordRef contactPerson = (__bridge ABRecordRef)allContacts[i];
            NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty);
            NSString *lastName =  (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
            NSString *fullName = [NSString stringWithFormat:@"%@ %@",firstName, lastName];

            person.firstName = firstName;
            person.lastName = lastName;
            person.fullName = fullName;

            //email
            ABMultiValueRef emails = ABRecordCopyValue(contactPerson,
                                                       kABPersonEmailProperty);
            NSUInteger j = 0;
            for (j = 0; j < ABMultiValueGetCount(emails); j++){
                NSString *email = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(emails, j);
                if (j == 0){
                    person.homeEmail = email;                 
                    NSLog(@"person.homeEmail = %@ ", person.homeEmail);                 
                }                              
                else if (j==1)                     
                    person.workEmail = email;
                    NSLog(@"person.workEmail = %@ ", person.workEmail);
            }           

            [self.tableData addObject:person];         
        }     
    }          

    CFRelease(addressBook); 
}


#pragma mark - Table View Methods

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.tableData count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"Identifier";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier:cellIdentifier];
    }
    Person *person = [self.tableData objectAtIndex:indexPath.row];

    cell.textLabel.text = person.fullName;

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"Cell was clicked");
    Person *person = [self.tableData objectAtIndex:indexPath.row];
    NSLog(@"Person selected: %@",person);
    SingleContactViewController *singleContactViewController = [[SingleContactViewController alloc] initWithPerson:person];
    NSLog(@"created singlecontactviewcontroller");

    [self.navigationController pushViewController:singleContactViewController animated:YES];
}

#pragma mark iAd Delegate Methods

- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
    // Gets called when iAds is loaded.
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:1];
    // Set iAd to visible, creates nice fade-in effect
    [banner setAlpha:1];
    [UIView commitAnimations];
}

- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
    // Gets called when iAds can't be loaded (no internet connection).
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:1];
    // Set iAd to visible, creates nice fade-in effect
    [banner setAlpha:0];
    [UIView commitAnimations];
}



@end

Here is the error I am receiving when I click on a cell

2013-12-05 07:25:35.186 ConfidentialContacts[21902:70b] Cell was clicked
2013-12-05 07:25:35.187 ConfidentialContacts[21902:70b] Person selected: <Person: 0xad670c0>
2013-12-05 07:25:35.187 ConfidentialContacts[21902:70b] created singlecontactviewcontroller
2013-12-05 07:25:35.225 ConfidentialContacts[21902:70b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/david/Library/Application Support/iPhone Simulator/7.0.3/Applications/7DCB2344-3497-4CAF-BA47-8E80E6D1FBB6/CustomContacts> (loaded)' with name 'SingleContactViewController''

if your using storyboard segue then better use prepareForSegue: method and pass the person object.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"Cell was clicked");
    [self performSegueWithIdentifier:@"yourSegueIdentifier" sender:self];

}

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"yourSegueIdentifier" ]) {

         NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
         Person *person = [self.tableData objectAtIndex:indexPath.row];
         NSLog(@"Person selected: %@", person);
         SingleContactViewController *singleContactViewController = segue.destinationViewController;
         singleContactViewController.person = person; // create person object as a property in SingleContactViewController and assign the person object.
    NSLog(@"created singlecontactviewcontroller");

   } 

}

I don't think you can push a new controller onto an existing one. Just segue to the new view. This will push the view onto the viewController's stack.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM