0

アプリのエントリ ポイントとして Split VC があります。詳細 VC は UINavigationController であり、マスター VC を常に非表示にして、ツールバーからのポップオーバーでのみ使用できるようにしたいと考えています。

私の問題は、barButtonItem をマスター VC から詳細 VC に配置する方法がないことです。ツールバーは常に空です (self.toolbarHidden = NO;上部にナビゲーション バーがあるため、強制的に表示するために使用する必要がありました)。

UINavigationController (実際の詳細 VC) に以下のコードがあります。

-(void) setBarButtonItem:(UIBarButtonItem *)barButtonItem {
  NSLog(@"adding toolbar button: %@", barButtonItem.title);

  UIToolbar *toolbar = [self toolbar];

  NSMutableArray *toolbarItems = [toolbar.items mutableCopy];

  if (_barButtonItem) [toolbarItems removeObject:_barButtonItem];

  if (barButtonItem) [toolbarItems insertObject:barButtonItem atIndex:0];

  _barButtonItem = barButtonItem;
}

何か不足していますか?ツールバーの代わりにナビゲーションバーにも挿入しようとしましたが、そこにも表示されません。私がコメントで提供しなかった情報を求めてください。

4

1 に答える 1

0

他の誰かが同じことをしようとしている場合に備えて、splitViewController の詳細 VC として UINavigationController を持ち、マスター VC を表示/非表示にするためにナビゲートするときに各ビュー コントローラーの上部にボタンを配置する実装を残しています。 :

詳細 VC は以下のプロトコルを実装する必要があります (したがって@synthesize、barButtonItem が必要です)。

@protocol SplitViewBarButtonItemPresenter <NSObject>
@property (nonatomic, strong) UIBarButtonItem *barButtonItem;
@end

willHideViewController: から渡された barButtonItem を詳細 VC で取得して保持する必要がありますが、マスター VC でそれを行う必要があります。マスター VC で以下を使用します。

- (BOOL) splitViewController:(UISplitViewController *)sender
    shouldHideViewController:(UIViewController *)vc
               inOrientation:(UIInterfaceOrientation)orientation {

    return YES;
}

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

    barButtonItem.title = self.title;

    [self splitViewBarButtonItemPresenter].barButtonItem = barButtonItem;

}

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

    [self splitViewBarButtonItemPresenter].barButtonItem = nil;

}

- (id <SplitViewBarButtonItemPresenter>) splitViewBarButtonItemPresenter {

    id detailVC = [self.splitViewController.viewControllers lastObject];

    if ((![detailVC isKindOfClass:[MainDetailVC class]]) || (![detailVC conformsToProtocol:@protocol(SplitViewBarButtonItemPresenter)])) {

        detailVC = nil;
    }

    return detailVC;
}

ボタンを表示する各ビュー コントローラーで、次のコードを使用します (すべて同じ型の場合は、これをクラスに配置して継承することもできます)。

-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    UIBarButtonItem *newBtn = [[UIBarButtonItem alloc]
            initWithTitle:@"Show Master MC" // might want a better title
            style:UIBarButtonItemStylePlain
            target:self action:@selector(forceOpenMasterVC)];

    self.navigationItem.rightBarButtonItem = newBtn;

}

-(void)forceOpenMasterVC {
    [((MainDetailVC *) self.navigationController) forceOpenMasterVC];
}

次に、詳細 VC で、次を使用します。

#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
// Above line is needed because of self.barButtonItem.action
// It doesn't leak as far as I can tell

-(void)forceOpenMasterVC {
    // Grab the Master VC
    UIViewController * vc = [[self.splitViewController viewControllers] objectAtIndex:0];

    if (self.barButtonItem) {
        [self.barButtonItem.target
            performSelector:self.barButtonItem.action
            withObject: self.barButtonItem];
    }
}

誰かがより良い方法を持っている場合は、それを含めてください。

于 2012-07-26T15:09:15.993 に答える