側にインデックスがあるUITableViewがあります。 UISearchBarを追加したいのですが、検索をクリアするためにインデックスが「x」と重複しています。私は連絡先アプリケーションで気づきましたが、UISearchBar内のテキストフィールドはこれに合わせてサイズ変更されていますが、自分のアプリでこれを行う方法を見つけることができません。
私は自分のviewDidLoadで以下を試しましたが、動作しないようです。
UITextField * textField = (UITextField *)[[self.search subviews] objectAtIndex:0];
CGRect r = textField.frame;
[textField setFrame:CGRectMake(r.Origin.x, r.Origin.y, r.size.height, r.size.width-30)];
何か案は?
これらすべての提案よりもはるかに簡単です。インターフェイスビルダーでは、テーブルビューのヘッダーとして検索バーを配置する代わりに、ビューを配置できます。次に、このビュー内にナビゲーションバーを配置します。ナビゲーションバーの左側のサイズ変更ハンドルをつかんで、NBの幅が25ピクセルになるまで右側に引き出します。 N Bのタイトルをクリアします(ダブルクリックして選択し、削除します)。次に、同じビューに検索バーを追加します。右のサイズ変更ハンドルを左に動かして、NBに接するように調整します。それだけです。
必要に応じてキャンセルボタンを有効にすることもできます。キャンセルボタンもインデックスと重複しません(検索バー内に残ります)。
どうやらテーブルビューのヘッダーにはサブビューを1つしか含めることができないようです。そのため、ビューを最初に配置してから、その中にN Bと検索バーを配置する必要があります。
更新:ApressからのiPhone開発の開始、p。 SDK 3エディションの241。検索中はインデックスを無効にするだけです。
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
if (isSearching) {
return nil;
}
return keys;
}
また、インデックスの上部に虫眼鏡を追加することについても話します。
周りの素晴らしい本。
実際のUISearchBarを水平方向に小さくして、(空の)UINavigationBarをその右側に配置するだけではどうですか。それらはまったく同じ背景をレンダリングします。
変更される可能性のあるAppleのオブジェクトの内部をハッキングするよりはましです。
また、UISearchBarの幅をアニメーション化すると、内側のテキストフィールドが一緒にアニメーション化されないことに気付くでしょう。フレームを変更した後、アニメーションブロック内でUISearchBarの「layoutSubviews」を呼び出すことで、これを修正できます。 (それが内部テキストフィールドのサイズを決定する場所です)
わかりました、私は解決策を考え出しました。
このコードをdrawRect:メソッドに含めます。
UITextView * textField = [self.subviews objectAtIndex:0];
textField.frame = CGRectMake(5, 6, (310 - kRightSideMargin), 31);
[super drawRect:rect];
注:kRightSideMarginは、ヘッダーファイルに設定した定数です。 25に設定しました。
皆からの提案をありがとう。
IOS 6の時点では、UISearchBarとUINavigationBarの外観が少し異なるため、ナビゲーションバーソリューションはうまく機能しませんでした。そこで、UISearchBarをサブクラス化してPadraigのアプローチに似たものに切り替えました。
@interface SearchBarWithPad : UISearchBar
@end
@implementation SearchBarWithPad
- (void) layoutSubviews {
[super layoutSubviews];
NSInteger pad = 50;
for (UIView *view in self.subviews) {
if ([view isKindOfClass: [UITextField class]])
view.frame = CGRectMake (view.frame.Origin.x, view.frame.Origin.y, view.frame.size.width - pad, view.frame.size.height);
}
}
@end
編集:ああ、まだ試していませんが、ナビゲーションバーのclipToBounds = YESを設定して新しいシャドウをオフにし、2つのコントロール間で一貫した外観を作成できると思います。
Padraigが指摘したように、必要なことはsearchBarをサブクラス化することだけです。 UISearchBarサブクラスを作成し、次のコードをlayoutSubviews
メソッドに追加します。
- (void)layoutSubviews
{
UITextField *searchField;
for(int i = 0; i < [self.subviews count]; i++)
{
if([[self.subviews objectAtIndex:i] isKindOfClass:[UITextField class]])
{
searchField = [self.subviews objectAtIndex:i];
}
}
if(!(searchField == nil))
{
searchField.frame = CGRectMake(4, 5, 285, 30);
}
}
これは、すべてのサブビューをループして、UITextFieldタイプと照合します。そうすれば、それがサブビューのラインナップで動く場合でも、これはそれを取得します。私は、285がtableViewのインデックスと重ならないだけの十分な幅があることを発見しました。
ViewDeck を使用していて、UISearchbarinsideleftController
を表示したい。
ここで問題は、ナビゲーションを含む左側を開くと、右側のビットが検索フィールドと重なることです。
UISearchBar
を上書きしてこれを取り除きました。テキストフィールドは常に同じ幅になりますが、ViewDeckがオーバーラップしている場合と、ViewDeckビットを非表示にしてから[キャンセル]ボタンをクリックすると、スペースを取る:
#import "ViewDeckSearchBar.h"
#define kViewDeckPadding 55
@interface ViewDeckSearchBar()
@property (readonly) UITextField *textField;
@end
@implementation ViewDeckSearchBar
static CGRect initialTextFieldFrame;
- (void) layoutSubviews {
[super layoutSubviews];
// Store the initial frame for the the text field
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
initialTextFieldFrame = self.textField.frame;
});
[self updateTextFieldFrame];
}
-(void)updateTextFieldFrame{
int width = initialTextFieldFrame.size.width - (kViewDeckPadding + 6);
CGRect newFrame = CGRectMake (self.textField.frame.Origin.x,
self.textField.frame.Origin.y,
width,
self.textField.frame.size.height);
self.textField.frame = newFrame;
}
-(UITextField *)textField{
for (UIView *view in self.subviews) {
if ([view isKindOfClass: [UITextField class]]){
return (UITextField *)view;
}
}
return nil;
}
@end
私のナビゲーションクラスでは、検索結果を全画面表示するために、これらの2つのUISearchbarDelegate
メソッドを上書きする必要があります。
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
[self.viewDeckController setLeftSize:0];
// I am also using scopes, which works fine (they fade out when not searching)
self.searchBar.scopeButtonTitles = @[@"Food",
@"Beverages",
@"Misc"];
}
-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar{
self.viewDeckController.leftSize = 55;
}
右側に表示されているViewDeck:
(ソース: minus.com )
全画面で検索します(ボタンとスコープボタンはアニメーション表示されます)。
(ソース: minus.com )
もう一度ドラッグしてごめんなさい。
UISearchBarを短くする必要があり、UISearchBarControllerを使用していますが、実際にはインデックスは必要ありません。これは、右側にオーバーレイがあるためです。
これを行うには、sectionIndexを1つの空白のアイテムで偽装してから非表示にします。これが私のやり方です:
- (void)hideTableIndex {
for (UIView *view in [tableView subviews]) {
if ([view isKindOfClass:NSClassFromString(@"UITableViewIndex")]) {
view.hidden = YES;
}
}
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)aTableView {
if (aTableView == self.searchDisplayController.searchResultsTableView) {
return nil;
} else {
[self performSelector:@selector(hideTableIndex) withObject:nil afterDelay:0];
return [NSArray arrayWithObjects:@"", nil];
}
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
return 0;
}
これにより、UISearchBarが短くなり、インデックスが非表示になるため、タップできなくなります(小さいセクションでは、タップするとUITableViewが一番上にスクロールするオーバーレイの左側に手が届きます)。このような:
何よりも、検索を使用しても、全幅バーが表示されます。
UIViewを配置し、そのUIView内に検索バーを配置するだけです。 UIViewは、UISearchBarと同じサイズでなければなりません。これは私のために働いた。
ネクロポスティングには申し訳ありませんが、テキストフィールドの右側に小さなスペースを作る別の方法を見つけました。私は問題を抱えていました。最初の行に検索バーが付いたインデックス付きのテーブルビューがありました。これで、インデックスと検索バー(IBで作成されたものです)がオーバーラップしていました。ほとんどすべてを試しましたが、成功しませんでした。 textifieldの幅と高さのプロパティが応答しないようです...だから私はこれを思いつきました:
searchBar.showsCancelButton = YES;
UIView *cButton = [searchBar.subviews objectAtIndex:2];
cButton.hidden = YES;
私はまだスペースのサイズを調整することはできませんが、これは今のところそれを行います...しかし...かなり奇妙な解決策...
誰もがUIを変更する方法を提供しています。同じ結果を得る方法を発見しました。次の2つの実装を提供する必要があります。
- (id)initWithSearchBar:(UISearchBar *)searchBar contentsController:(UIViewController *)viewController
有効なUISearchBarを設定しない(またはnilを渡す)と、インデックスのUITextFieldを調整できなくなります。
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView;
Nilを返すと、インデックスは表示されず、UITextFieldは適切に調整されません。
私はAppleにバグレポートを提出しましたが、必要なのは#1ではなく#2だけであることが論理的であるように思われることを示唆しています。ヒューマンインターフェイスガイドライン(iPhone HIG)で、UISearchDisplayControllerの使用を必要とするものは何も見つかりませんでした。
UISearchBarで使用されるテキストフィールドは、UISearchBarTextFieldと呼ばれるUITextFieldのサブクラスです。
私の知る限り、パブリックAPIを使用してUISearchBarTextFieldのサイズを変更する方法はありません。 private API もあまり明らかにしません。
もしあれば、UISearchBarTextFieldのサブビューを確認できます。
UPDATE:ありません。
UPDATE 2:UITextFieldのrightViewプロパティを確認する必要があると思います。以下のコードは機能しませんが、良い出発点のようです。
UIView *emptyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
[textField setRightView:emptyView];
[textField setRightViewMode:UITextFieldViewModeAlways];
[emptyView release];
重要なのは、Interface Builderを使用するときは、「検索バー」ではなく「検索バーと検索表示コントローラー」を使用することです。
私が思いついたのはそれほど良くはありません。基本的には、検索バーに使用するフレームで空のビューを作成します。次に、UIToolbarを作成して、検索バーの背後に移動します。必ずフレームをUIViewと同じフレームに設定してくださいexcept Y値は-1でなければなりません。それ以外の場合は、上部に2つの境界線が描画されます。次にUISearchBarを作成しますが、フレームの幅をUIViewよりも30(またはアプリにとって意味のあるもの)に設定します。それらをサブビューとして追加し、UIViewをtableHeaderViewとして設定します。
私はMikeのアドバイスに従って、UIViewを作成し、その中にナビゲーションバーとUISearchバーを配置しました。唯一の問題は、検索バーが最初に表示されたときに、その背景が通常のナビゲーションバーと同じであることです。
興味深いことに、検索をアクティブにした場合は、この「修正済み」の背景のキャンセルをクリックします!?
私はSDK 3.0を使用しているため、UISearchDisplayControllerをNIBにドラッグしたときに作成されたUISearchBarアイテムを削除し、次に上記のようにビューを作成して、ファイル所有者と検索表示コントローラーのsearchBarアウトレットに配線しました。
それはうまくいきます!!!
[searchBar setContentInset:UIEdgeInsetsMake(5, 0, 5, 35)];
(退屈な)別のアプローチは、検索バーのサイズを変更し、ナビゲーションバーで「ギャップ」を埋めることです。私のために働く。
Apple=ビューのサイズを変更します(インデックスは画面外で右にアニメーション化されることに注意してください)。画面より大きくなります。
これを適切な時点でトリガーするには、UISearchBarDelegate
のsearchBarTextDidBeginEditing:
メソッドを実装する必要があると思います。ただし、これは少しハッキーな感じがしますが、もっと良い方法があるかもしれません。