Требовать UISplitViewController для отложенной загрузки нескольких контроллеров представления для контроллера подробного представления - PullRequest
1 голос
/ 16 февраля 2011

Ну, может быть, не понятно с заголовком. Я извлек это прямо из примера кода MultipleDetailView от Apple. Каждый раз, когда пользователь выбирает строку из таблицы во всплывающем окне, detailViewController снова выделяет FirstDetailViewController и SecondDetailViewController. Вместо того, чтобы снова и снова выделять и инициализировать контроллер представления, я хочу назначить существующий и уже выделенный и инициализированный контроллер представления, если он существует, элементу detailViewController при выборе строки. Я изменил Split View Template вместо примера кода, чтобы добиться того, что мне нужно. Код из программы:

Это файл AppDelegate.h:

@interface iPadHelloWorldAppDelegate : NSObject <UIApplicationDelegate> {

    UIWindow *window;

    UISplitViewController *splitViewController;

    MasterViewController *masterViewController;
    DetailViewController *detailViewController;
    SecondDetailViewController *secondDetailViewController;
}

Это файл AppDelegate.m:

 masterViewController = [[MasterViewController alloc] init];
 UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
 detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:nil];
 secondDetailViewController = [[SecondDetailViewController alloc] initWithNibName:@"SecondDetailView" bundle:nil];
 splitViewController = [[UISplitViewController alloc] init];
 splitViewController.viewControllers = [NSArray arrayWithObjects:navigationController, detailViewController, nil];
    splitViewController.delegate = detailViewController;
    // Add the split view controller's view to the window and display.
    [window addSubview:splitViewController.view];
    [window makeKeyAndVisible];

Это MasterViewController.m:

- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSUInteger row = indexPath.row;
    [self.appDelegate.splitViewController viewWillDisappear:YES];
    self.tempArrays = [NSMutableArray arrayWithArray:self.appDelegate.splitViewController.viewControllers];
    [self.tempArrays removeLastObject];
    if (row == 0) {
        [self.tempArrays addObject:self.appDelegate.detailViewController];
        self.appDelegate.splitViewController.delegate = self.appDelegate.detailViewController;
    }
    if (row == 1) {
        [self.tempArrays addObject:self.appDelegate.secondDetailViewController];
        self.appDelegate.splitViewController.delegate = self.appDelegate.secondDetailViewController;
    }
    self.appDelegate.splitViewController.viewControllers = self.tempArrays;
    [self.appDelegate.splitViewController viewWillAppear:YES];
}

Это DetailViewController.m:

#pragma mark -
#pragma mark Split view support

- (void)splitViewController: (UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController: (UIPopoverController*)pc {

    barButtonItem.title = @"Master List";
    [navigationBar.topItem setLeftBarButtonItem:barButtonItem animated:NO];
    self.popoverController = pc;
}

// Called when the view is shown again in the split view, invalidating the button and popover controller.
- (void)splitViewController: (UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {

    [navigationBar.topItem setLeftBarButtonItem:nil animated:NO];
    self.popoverController = nil;
}

Я могу лениво загрузить контроллеры вида, но когда я нажимаю кнопку панели для всплывающего окна и перехожу ко второму контроллеру вида, второй контроллер вида не показывает всплывающее окно. Когда я возвращаюсь к первому подробному контроллеру, отображается всплывающее окно.

По сути, здесь - это похожий вопрос. Но ссылка на выпадающий список не работает.

Ответы [ 3 ]

3 голосов
/ 14 марта 2011

Так как вы попросили меня выстрелить - вот так.SplitViewController довольно глючит, по нашему мнению здесь.Мы столкнулись со многими проблемами, если вы не будете точно придерживаться того, как Apple это делает в своем примере кода.

Прежде всего, я бы посоветовал вам снова взять образец кода и начать с нуля, так как он кажетсяВы много изменили.

Что касается вашей проблемы: в вашем делегате и MainWindow.xib вы настроили SplitViewController.Самое главное - не настраивать массив viewControllers так, как вы это делаете.

Я столкнулся с проблемой, что если я перезаписываю RootViewController, он портит SplitViewController и выдает ошибки, подобные той, с которой вы столкнулись.

Попробуйте настроить RootViewController (TableViewController) только один раз и никогдаперезаписать его в свойстве viewControllers.Похоже, что это нормально для DetailViewController.

Во-вторых, ваш код должен быть размещен в другом месте, а не в RootViewController.Это должно быть только для источника данных tableView и контента.

Попробуйте и отзывы здесь, я буду следовать как можно скорее.

Удачи.

РЕДАКТИРОВАТЬ: добавление кода -сделайте это в вашем RootViewController:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {


DetailViewController *dvC = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];

// take the original view controller from the splitviewcontroller as root
// appDelegateiPad defined like this in my appdelegate:
// #define appDelegateiPad ((AppDelegate_iPad *)[[UIApplication sharedApplication] delegate]) 
NSArray *viewControllers = [[NSArray alloc] initWithObjects:[[appDelegateiPad.splitViewController viewControllers]objectAtIndex:0], dvC, nil];
        appDelegateiPad.splitViewController.viewControllers = viewControllers;
//careful with this, set it to whatever your delegate is in your case           
appDelegateiPad.splitViewController.delegate = dvC;
        [viewControllers release];  


//this is my version
//i have the popoverController property in my detailviewcontroller. this is where my splitviewcontroller delegate methods are. you need to set the popovercontroller property in the class where your splitviewcontroller delegate methos are
    dvC.popoverController = [[[appDelegateiPad.splitViewController viewControllers]objectAtIndex:1] popoverController];     

    } 
}
0 голосов
/ 23 ноября 2011

Нет необходимости создавать новый экземпляр контроллера подробного представления или обновлять viewControllers в контроллере разделенного представления.

Попробуйте это.

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {

        UIApplication *application = [UIApplication sharedApplication];
        AppDelegate *appDelegate = (AppDelegate*) [application delegate];
        appDelegate.detailViewController.label.text = @"Detail view controller updated";

    }

PS: перетащите метку на деталь для тестирования.

0 голосов
/ 16 февраля 2011

Попробуйте выделить viewControllers в viewDidLoad в этом объекте.Дайте обоим viewcontrollers заголовок и поместите их в массив.Эти заголовки вы можете использовать для обеих ячеек надписей текста при необходимости.В didSelectRowAtIndexPath вы можете получить правильный view-контроллер для выбранной строки

UIViewController <SubstitutableDetailViewController> *detailViewController = [theArray objectAtIndex:indexPath.row];

Редактировать:

@interface SomeClass : NSObject {
  NSArray *controllerArray;
}
@end
@implementation SomeClass

- (void) viewDidLoad {
  controllerArray = [[NSArray alloc] initWithObject://yourControllers//,nil];
  [super viewDidLoad]
}

- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {

    // Two sections, one for each detail view controller.
    return 2;
}

- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

  //Create Cell

  UIViewCOntroller *controller = [controllerArray objectAtIndex:indexPath.row];
  cell.textLabel.text = controller.title;

  return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  [detailViewController autorelease]; 
  detailViewController = [[controllerArray objectAtIndex:indexPath.row] retain];
}

@end
...