ABPeoplePickerNavigationController-削除“キャンセル”プライベートメソッド/プロパティを使用せずにボタン?
-
05-07-2019 - |
質問
UINavigationControllerのサブクラスであるABPeoplePickerNavigationControllerを使用しています。コンテキストでは、右側のデフォルトのナビゲーションバーボタン「Cancel」を使用していますが、意味がありません。私はそれを無効にしたり隠したりする方法を見つけることができず、使用する方法はすべてパブリックでストア承認可能である必要があります。 ナビゲーションバーを完全に削除する(picker.navigationBarHidden = YES;)オプションは、連絡先のリストに戻った後、ナビゲーションバーが再び表示されることを除いてオプションです。 ABPeoplePickerNavigationControllerをサブクラス化し、viewWillAppearをインターセプトしてキャンセルボタンを無効にしました。 [ピッカーsetAllowsCancel:NO];動作しますが、文書化されていないため、承認に合格しないことを期待しています。
解決 3
これに対する答えはありません-キャンセルできない場合は、新しいユーザーピッカーを作成してください。
他のヒント
これ
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
UIView *custom = [[UIView alloc] initWithFrame:CGRectMake(0.0f,0.0f,0.0f,0.0f)];
UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithCustomView:custom];
//UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addAction)];
[viewController.navigationItem setRightBarButtonItem:btn animated:NO];
[btn release];
[custom release];
}
完璧に動作します!
デリゲートメソッドnavigationController:willShowViewController:animated:を使用したここの例は機能しますが、独自のコントローラーに独自のナビゲーションアイテムを追加したい場合があり、指定されたオプションは設定したものをすべて削除します独自のコントローラー。このオプションを適切に機能させるために使用したコードは次のとおりです。
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated {
// Here we want to remove the 'Cancel' button, but only if we're showing
// either of the ABPeoplePickerNavigationController's top two controllers
if ([navigationController.viewControllers indexOfObject:viewController] <= 1) {
viewController.navigationItem.rightBarButtonItem = nil;
}
}
Navigation Controllerのスタックには、連絡先グループ用と連絡先リスト用の2つのView Controllerがあります。これが、viewControllerがNavigation Controllerのトップビューコントローラであるかどうかだけをチェックできない理由です。
ピッカーサブビューを参照して、その結果を表示できます。ちょっとつまらない...
まだ試していませんが、isbyKindOfClass:[UIBarButtonItem class]が見つかるまでピッカーのサブビューを反復処理し、そのタイトルプロパティを変更できるとUbyが言っていると思います。また、navigationBarの「Item」配列にも含まれる場合があります。
PeoplePickerControllerコントローラーへのデリゲートを設定します。 デリゲートクラスで、このデリゲートメソッドを用意します。
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
UIView *pCustomView = [[UIView alloc] initWithFrame:CGRectMake(0,0,0,0)];
UIBarButtonItem *pBtn = [[UIBarButtonItem alloc] initWithCustomView:pCustomView];
[viewController.navigationItem setRightBarButtonItem:pBtn animated:NO];
[pBtn release];
[pCustomView release];
}
ピッカーオブジェクトのデリゲート(peoplePickerDelegateではなく、デリゲートのみ)を次のメソッドを実装するクラスに設定してください:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
UIView *custom = [[UIView alloc] initWithFrame:CGRectMake(0,0,0,0)];
UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithCustomView:custom];
[viewController.navigationItem setRightBarButtonItem:btn animated:NO];
[btn release];
[custom release];
}
それは正常に動作しますが、iOS 4にはもう1つあります。高速アプリ切り替え機能を使用してアプリに切り替えると、キャンセルボタンが再び表示されます。
メソッド
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
呼び出されません。だから私はこれを作りました:
- (void)applicationDidEnterBackground:(UIApplication *)application {
id topView = pickerControllerDelegate.peoplePicker.topViewController;
topView.navigationItem.rightBarButtonItem = nil;
}
非常にうまく機能します。
russell bによれば、 viewdidappear を上書きできます
これは私のために働いた:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UINavigationItem *item = (UINavigationItem *)[self.navigationBar.items lastObject];
item.rightBarButtonItems = [[NSArray alloc] init];
item.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addPerson)];
}
編集:以下のコメントを参照してください。これは、やってはいけないことの例です。
ABPeoplePickerNavigationControllerをサブクラス化し、現在のNavigation View Controllerビューを変更するすべてのイベントをインターセプトすることにより、パブリックAPIで目的の動作を取得しようとしました。その後、ビュー階層をナビゲートして、不要なボタンをすべて削除できます。
デリゲートからビュー階層をナビゲートすることはできますが、ビューステートを変更するイベントに精通していないため、[キャンセル]ボタンを強制終了して固定することは困難です。
このコードは種類は私のために働いた(注:総当たりですべての右側のボタンが強制終了される):
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self killCancelButton];
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
[super pushViewController:viewController animated:animated];
[self killCancelButton];
}
- (UIViewController*)popViewControllerAnimated:(BOOL)animated {
UIViewController *result = [super popViewControllerAnimated:animated];
[self killCancelButton];
return result;
}
- (void)killCancelButton {
for (NSUInteger itemIdx = 0; itemIdx < self.navigationBar.items.count; itemIdx++) {
UINavigationItem *item = [self.navigationBar.items objectAtIndex:itemIdx];
item.rightBarButtonItems = [[NSArray alloc] init];
}
}