IOS 6およびiOS 7で実行することになっているアプリで、iOS 7で実行すると、ナビゲーションバーに埋め込まれた検索バーのキャンセルボタンが表示されなくなりました。iOS6では機能します。
検索バーはナビゲーションバーのタイトルビューにあり、検索バーが最初のレスポンダーになると、キャンセルボタンが表示されます。
iOS 7
iOS 6
独立したテストケースでは、コードは非常に単純です。
@interface MyViewController : UITableViewController<UISearchBarDelegate>
@property (nonatomic) IBOutlet UISearchBar* searchBar;
@end
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.titleView = self.searchBar;
}
- (void) searchBarTextDidBeginEditing: (UISearchBar*) searchBar {
[searchBar setShowsCancelButton: YES animated: YES];
}
@end
これは、ドキュメントで見逃したiOS 7の意図的な変更ですか?はいの場合、代替案は何ですか?
そうでない場合は、コードに誤りがありますか?
あなたはすべてを正しく行っているようですが、明らかにAppleはiOS 7でいくつかの点で変更されました これによるとSO質問 iOS 7では、キャンセルボタンはUISearchBar
に埋め込まれたUINavigationBar
に表示されません。
開発者用ドキュメント によると、showsCancelButton
プロパティはsetShowsCancelButton:Animated
メソッドとは少し異なる効果を持つ可能性があります。これを試してください:
searchBar.showsCancelButton = YES;
[searchBar setShowsCancelButton:YES animated:YES];
影響があるかどうかはわかりません。別のデリゲートメソッドにコードを配置してみることもできます。
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar; // return NO to not become first responder
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar; // called when text starts editing
iOS 7 changelog をチェックアウトすることもできます。 Appleが動作を変更したか、UISearchDisplayController
に追加したときのUISearchBar
/UINavigationBar
のように見えます。最後の箇条書きを見てください。 UIKitセクションの下にあります(ただし、何が変更されたかは明確ではありません)。
UISerachDisplayController
を使用することもできます。さらに簡単なのは、UISearchBar
のヘッダーにUITableView
を埋め込むことです。
この問題は、rightBarButtonItemを追加するだけで簡単に解決できました。
self.navigationItem.titleView = self.searchBar;
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Cancel", nil) style:UIBarButtonItemStylePlain target:self action:@selector(didClickCancelButton:)] autorelease];
ただし、現在のiOSバージョンが7.0以上かどうかを確認する必要があります。そうでない場合、2つの「キャンセル」ボタンが表示されます。
ちなみに、この方法では、常に「キャンセル」ボタンを有効にすることができます
iOS 7は、ナビゲーションバーのiOS 6とは異なります。そのため、ナビゲーションバーにUISearchバーを表示したい場合は、これを試すことができます。
this[self.searchView addSubview self.searchBar]
のようなUIViewにUISearchbarを配置し、ナビゲーションバーのtitleViewをthisself.navagitioncontroller.navigationItem.titleView = self.searchView
のようなsearchViewに設定します
それがあなたのために働くことを願っています
UISearchDisplayControllerでUISearchBarを使用している場合は、「searchDisplayControllerWillBeginSearch」デリゲートメソッドで次のように、キャンセルボタンを表示するように設定するだけです(iOS 7テスト済み)。
-(void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller{
controller.searchBar.showsCancelButton = YES;
}
2つのオプションがあります。
私の好みは2番目のものですが、1番目のものよりネイティブに見えます。
私の意見では、これはバグです。私の回避策はこちらです。完璧ではありませんが、iOS 6とiOS 7の両方で機能します。 iOS7では、検索バーのテキストフィールドがフェードアウトしている間、キャンセルボタンの上をスライドします。iOS6では、テキストフィールドの幅の拡張はアニメーション化されません。
@interface FTViewController ()
@property(nonatomic, strong) UISearchBar *searchBar;
@end
@implementation FTViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.searchBar = [[UISearchBar alloc] init];
self.searchBar.delegate = self;
if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1) {
// iOS 6.1 and older (only tested on 6.1)
[self.searchBar sizeToFit];
self.searchBar.backgroundImage = nil;
}
self.navigationItem.titleView = self.searchBar;
}
-(void)cancelBarButtonItemClicked:(id)sender
{
[self searchBarCancelButtonClicked:self.searchBar];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
[self.navigationItem setRightBarButtonItem:nil animated:YES];
}
-(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelBarButtonItemClicked:)];
[self.navigationItem setRightBarButtonItem:cancelBtn animated:YES];
return YES;
}
@end
これは実際に7.1の時点で修正されているバグです。
IOS6とiOS7の間でxxxDidYYY
メソッドからのUIへの変更が機能しないことがあり、xxxWillYYY
メソッドまたはいくつかのコードで変更する必要があるという点で変更があるようですメインイベントループから実行されます(たとえば、ブロック内または短い遅延の後)。
あなたの場合、これを試してください:
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
searchBar.showsCancelButton = YES;
return YES;
}