Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

RagingGoat

macrumors 6502
Original poster
Jun 21, 2010
307
15
I am playing with a UISplitView and I'm having trouble getting anything to appear in the detail view. I have an array in my master view controller.

Code:
menu = [NSMutableArray arrayWithObjects:@"Home", @"Public Affairs", @"Action Alerts", @"Market Updates", @"Ag Stories", @"KFB News", @"Member Benefits", @"Monthly Video", @"Photos", @"Social Media", @"About Us", @"Contact Us", @"KYFB.com", nil];

When a row is tapped it should show another view corresponding to the row in the detail view of the split view. I tried putting code into the didSelectRowAtIndexPath method but it just changes the master view and does nothing to the detail view.

Any suggestions?
 

KoolStar

macrumors demi-god
Oct 16, 2006
825
9
Kentucky
Do you have a reference to the detailView in your masterview? You will need it in order to change out the views.

Once you have that reference you can then change out the view/viewcontroller (not sure how you are setting your app up) on the didSelectRowAtIndex.
 

MattInOz

macrumors 68030
Jan 19, 2006
2,760
0
Sydney
The other way is to have a property on the DetailViewController that can be set to the detail Item selected by the user.

Either way you still to get a reference to the detail view controller.
If you have a reference to the splitViewController then you can get the detailViewController from there.
 

KoolStar

macrumors demi-god
Oct 16, 2006
825
9
Kentucky
The other way is to have a property on the DetailViewController that can be set to the detail Item selected by the user.

Either way you still to get a reference to the detail view controller.
If you have a reference to the splitViewController then you can get the detailViewController from there.

This is also true, you would want that property to either be a uiviewcontroller so you can use UIViewContainment to add it as a childview or you can replace self.view of the detail view controller, i would not recommend the later of the two. The UIViewContainmentProtocols are vary handy and allow your controllers to coexist in one view.
 

RagingGoat

macrumors 6502
Original poster
Jun 21, 2010
307
15
Here is what I currently have. Right now I'm wanting it so that when I select social media from the master view, it will go to the social networks table view in the detail view.

Code:
//
//  KFBAppDelegate.m
//  KYFB
//
//  Created by KFB on 1/15/13.
//  Copyright (c) 2013 com.kfb. All rights reserved.
//

#import "KFBAppDelegate.h"
#import "KFBMasterViewController.h"
#import "KFBDetailViewController.h"

@implementation KFBAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.

    KFBMasterViewController *masterViewController = [[KFBMasterViewController alloc] initWithNibName:@"KFBMasterViewController" bundle:nil];
    UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];

    KFBDetailViewController *detailViewController = [[KFBDetailViewController alloc] initWithNibName:@"KFBDetailViewController" bundle:nil];
    UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];

    masterViewController.detailViewController = detailViewController;

    self.splitViewController = [[UISplitViewController alloc] init];
    self.splitViewController.delegate = detailViewController;
    self.splitViewController.viewControllers = @[masterNavigationController, detailNavigationController];
    self.window.rootViewController = self.splitViewController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end
Code:
//
//  KFBMasterViewController.h
//  KYFB
//
//  Created by KFB on 1/15/13.
//  Copyright (c) 2013 com.kfb. All rights reserved.
//

#import <UIKit/UIKit.h>

@class KFBDetailViewController;

@interface KFBMasterViewController : UITableViewController

@property (strong, nonatomic) KFBDetailViewController *detailViewController;

@end
Code:
//
//  KFBMasterViewController.m
//  KYFB
//
//  Created by KFB on 1/15/13.
//  Copyright (c) 2013 com.kfb. All rights reserved.
//

#import "KFBMasterViewController.h"
#import "KFBDetailViewController.h"
#import "SocialNetworks.h"

@interface KFBMasterViewController () {
    NSMutableArray *_objects;
    NSMutableArray *menu;
}
@end

@implementation KFBMasterViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.title = NSLocalizedString(@"Master", @"Master");
        self.clearsSelectionOnViewWillAppear = NO;
        self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);
    }
    return self;
}
							
- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    // self.navigationItem.leftBarButtonItem = self.editButtonItem;

    // UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
    // self.navigationItem.rightBarButtonItem = addButton;
    
    menu = [NSMutableArray arrayWithObjects:@"Home", @"Public Affairs", @"Action Alerts", @"Market Updates", @"Ag Stories", @"KFB News", @"Member Benefits", @"Monthly Video", @"Photos", @"Social Media", @"About Us", @"Contact Us", @"KYFB.com", nil];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)insertNewObject:(id)sender
{
    if (!_objects) {
        _objects = [[NSMutableArray alloc] init];
    }
    [_objects insertObject:[NSDate date] atIndex:0];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}

#pragma mark - Table View

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return menu.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:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }


    // NSDate *object = _objects[indexPath.row];
    // cell.textLabel.text = [object description];
    cell.textLabel.text = [menu objectAtIndex:indexPath.row];
    return cell;
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [_objects removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    } else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
    }
}

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // NSDate *object = _objects[indexPath.row];
    // self.detailViewController.detailItem = object;
}

@end
Code:
//
//  KFBDetailViewController.h
//  KYFB
//
//  Created by KFB on 1/15/13.
//  Copyright (c) 2013 com.kfb. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface KFBDetailViewController : UIViewController <UISplitViewControllerDelegate>

@property (strong, nonatomic) id detailItem;

@property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
@end
Code:
//
//  KFBDetailViewController.m
//  KYFB
//
//  Created by KFB on 1/15/13.
//  Copyright (c) 2013 com.kfb. All rights reserved.
//

#import "KFBDetailViewController.h"

@interface KFBDetailViewController ()
@property (strong, nonatomic) UIPopoverController *masterPopoverController;
- (void)configureView;
@end

@implementation KFBDetailViewController

#pragma mark - Managing the detail item

- (void)setDetailItem:(id)newDetailItem
{
    if (_detailItem != newDetailItem) {
        _detailItem = newDetailItem;
        
        // Update the view.
        [self configureView];
    }

    if (self.masterPopoverController != nil) {
        [self.masterPopoverController dismissPopoverAnimated:YES];
    }        
}

- (void)configureView
{
    // Update the user interface for the detail item.

    if (self.detailItem) {
        self.detailDescriptionLabel.text = [self.detailItem description];
    }
}

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    [self configureView];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.title = NSLocalizedString(@"Detail", @"Detail");
    }
    return self;
}
							
#pragma mark - Split view

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
{
    barButtonItem.title = NSLocalizedString(@"Master", @"Master");
    [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
    self.masterPopoverController = popoverController;
}

- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
    // Called when the view is shown again in the split view, invalidating the button and popover controller.
    [self.navigationItem setLeftBarButtonItem:nil animated:YES];
    self.masterPopoverController = nil;
}

@end
Code:
//
//  SocialNetworks.m
//  KFBNewsroom
//
//  Created by Adam Rayborn on 10/18/12.
//  Copyright (c) 2012 com.kfb. All rights reserved.
//

#import "SocialNetworks.h"

@interface SocialNetworks ()

@end

@implementation SocialNetworks
{
    NSMutableArray *mbTableData;
}

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

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    mbTableData = [NSMutableArray arrayWithObjects:@"Facebook", @"Twitter", @"YouTube", nil];
    self.title = @"Social Networks";
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *mbTableIdentifier = @"SimpleTableItem";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:mbTableIdentifier];
    
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:mbTableIdentifier];
        cell.textLabel.font=[UIFont systemFontOfSize:16.0];
    }
    
    // cell.backgroundView = [[CustomCellBackground alloc] init];
    // cell.selectedBackgroundView = [[CustomCellBackground alloc] init];
    cell.textLabel.backgroundColor = [UIColor clearColor];
    cell.textLabel.highlightedTextColor = [UIColor darkGrayColor];
    
    cell.textLabel.text = [mbTableData objectAtIndex:indexPath.row];
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    /*
    if (indexPath.row == 0)
    {
        Facebook *facebook = [[Facebook alloc] initWithNibName:@"Facebook" bundle:[NSBundle  mainBundle]];
        [self.navigationController pushViewController:facebook animated:YES];
    }
    else if (indexPath.row == 1)
    {
        Twitter *twitter = [[Twitter alloc] initWithNibName:@"Twitter" bundle:[NSBundle  mainBundle]];
        [self.navigationController pushViewController:twitter animated:YES];
    }
    else if (indexPath.row == 2)
    {
        YouTube *youTube = [[YouTube alloc] initWithNibName:@"YouTube" bundle:[NSBundle  mainBundle]];
        [self.navigationController pushViewController:youTube animated:YES];
    }
    */
    
}


@end
 

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // NSDate *object = _objects[indexPath.row];
    // self.detailViewController.detailItem = object;
}

Your KFBMasterViewController's didSelectRowAtIndexPath: is not doing anything. What do you think it should be doing?
 

RagingGoat

macrumors 6502
Original poster
Jun 21, 2010
307
15
I tried something like this (which is what I'm doing in an iPhone version of my app), but it just changes the Master view. I'm not sure how to connect it to the detail view.

Code:
if (indexPath.row == 0)
    {
        Facebook *facebook = [[Facebook alloc] initWithNibName:@"Facebook" bundle:[NSBundle  mainBundle]];
        [self.navigationController pushViewController:facebook animated:YES];
    }
 

MattInOz

macrumors 68030
Jan 19, 2006
2,760
0
Sydney
I tried something like this (which is what I'm doing in an iPhone version of my app), but it just changes the Master view. I'm not sure how to connect it to the detail view.

Code:
if (indexPath.row == 0)
    {
        Facebook *facebook = [[Facebook alloc] initWithNibName:@"Facebook" bundle:[NSBundle  mainBundle]];
        [self.navigationController pushViewController:facebook animated:YES];
    }

It changes the masterView because that's what you told it do.
If this code was in the DetailViewController it would then do what you want.
If you un-comment the lines Dejo pointed to then walk them though what that code triggers. Hopefully from there you'll find where these lines need to go too get what you want.

Hint: your if test is going to be very different.
 

RagingGoat

macrumors 6502
Original poster
Jun 21, 2010
307
15
In looking into this some more, I'm seeing a lot of examples doing it like this:

Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // NSDate *object = _objects[indexPath.row];
    // self.detailViewController.detailItem = object;
    
    UIViewController <SubstitutableDetailViewController> *detailViewController = nil;
    
    if (indexPath.row == 9)
    {
        SocialNetworks *social = [[SocialNetworks alloc] initWithNibName:@"SocialNetworks" bundle:nil];
        detailViewController = social;
    }
}

but I can't seem to get this working either.
 

KoolStar

macrumors demi-god
Oct 16, 2006
825
9
Kentucky
In looking into this some more, I'm seeing a lot of examples doing it like this:

Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // NSDate *object = _objects[indexPath.row];
    // self.detailViewController.detailItem = object;
    
    UIViewController <SubstitutableDetailViewController> *detailViewController = nil;
    
    if (indexPath.row == 9)
    {
        SocialNetworks *social = [[SocialNetworks alloc] initWithNibName:@"SocialNetworks" bundle:nil];
        detailViewController = social;
    }
}

but I can't seem to get this working either.

In his case detailViewController shouldn't work. It should be self.detailViewController or _detailViewController depending on how it was compiled.
 

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
In his case detailViewController shouldn't work. It should be self.detailViewController or _detailViewController depending on how it was compiled.

Nice. :p

You pretty much gave him the solution to that issue; I was hoping he would discover it on his own. I find self-discovery holds so much more weight than just being told the answer.
 

KoolStar

macrumors demi-god
Oct 16, 2006
825
9
Kentucky
Nice. :p

You pretty much gave him the solution to that issue; I was hoping he would discover it on his own. I find self-discovery holds so much more weight than just being told the answer.

Three days later and no reply. More of a lets hopefully close up the thread. So if anyone else was looking for the answer it was out there, but I understand what you mean.
 

MattInOz

macrumors 68030
Jan 19, 2006
2,760
0
Sydney
In his case detailViewController shouldn't work. It should be self.detailViewController or _detailViewController depending on how it was compiled.

Isn't just replacing the detailViewController going to stuff up the splitView.
The new controller isn't going to get set as splitView delegate.

It'll work until the first time the user changes the detailView while in protrait.
 

RagingGoat

macrumors 6502
Original poster
Jun 21, 2010
307
15
Here is how I ultimately got it working.

Code:
[((UINavigationController *)[self.splitViewController.viewControllers lastObject]) pushViewController:[[SocialNetworks alloc]initWithNibName:@"SocialNetworks" bundle:nil] animated:YES];
 

RagingGoat

macrumors 6502
Original poster
Jun 21, 2010
307
15
Did you take note of MattInOz's warnings?

I guess i missed his post. I just read it and with my solution I'm seeing what he is talking about. With my implementation, when in portrait, you have to go back through your views in order to be able to tap the master button to open the master table view. I guess it's back to the drawing board.
 

MattInOz

macrumors 68030
Jan 19, 2006
2,760
0
Sydney
I guess i missed his post. I just read it and with my solution I'm seeing what he is talking about. With my implementation, when in portrait, you have to go back through your views in order to be able to tap the master button to open the master table view. I guess it's back to the drawing board.

This is a new one for me, same result but different cause.
Couple of questions.
Do you want the user to be able to navigate detailViews without going back to the masterview or should they always go back to the masterView?

If yes then you could pop off all the previous Views in the navigation controller, before you push the new one.

The other question I had are all your detailViews Tableviews?
 

RagingGoat

macrumors 6502
Original poster
Jun 21, 2010
307
15
I would like them to be able to navigate the individual detail views without going back to the master view. For example, in the social networks table view in the code I posted, the user will select a row and go to another view. I would like the user to be able to go back to the initial table view without using the master view.

And no, not all of my detail views are table views.
 

KoolStar

macrumors demi-god
Oct 16, 2006
825
9
Kentucky
Wrap your detail view in a uinavigationcontroller, that way you can just push and pop views while in the detail view.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.