30

側にインデックスを持つ 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)];

何か案は?

4

18 に答える 18

30

これらすべての提案よりもはるかに簡単です。インターフェイス ビルダーでは、検索バーをテーブル ビューのヘッダーとして配置する代わりに、代わりにビューを配置できます。次に、このビュー内にナビゲーション バーを配置します。ナビゲーション バーの左側のサイズ変更ハンドルをつかみ、NB の幅が 25 ピクセルになるまで右に引きます。NB のタイトルをクリアします (ダブルクリックして選択し、削除します)。次に、検索バーを同じビューに追加します。右側のサイズ変更ハンドルを左に動かし、N B に接するように調整します。それだけです。

必要に応じてキャンセル ボタンを有効にすることもできます。また、インデックスと重なることもありません (検索バー内に残ります)。

どうやら、テーブル ビューはヘッダーに 1 つのサブビューしか持てないため、最初にビューを配置し、次に NB と検索バーをその中に配置する必要があります。

更新: Apress からの iPhone 開発の開始を参照してください。SDK 3 エディションの 241。検索中にインデックスを無効にするだけです。

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    if (isSearching) {
        return nil;
    }
    return keys;
}

また、インデックスの上部に拡大鏡を追加することについても話しています。

素晴らしい本。

于 2009-10-28T07:10:49.477 に答える
16

実際の UISearchBar を水平方向に小さくし、(空の) UINavigationBar をその右側に配置しないのはなぜですか? それらはまったく同じ背景をレンダリングします。

変更される可能性のある Apple のオブジェクトの内部をハッキングするよりはましです。

また、UISearchBar の幅をアニメーション化すると、内側のテキスト フィールドが一緒にアニメーション化されないことに気付くでしょう。フレームを変更した後、アニメーション ブロック内で UISearchBar の「layoutSubviews」を呼び出すことで、これを修正できます。(ここで、内側のテキスト フィールドのサイズが決まります)

于 2009-02-26T03:08:49.460 に答える
8

わかりました、私は解決策を思い付きました。

  1. UISearchBar のサブクラスを作成する
  2. このコードを drawRect: メソッドに含めます。

    UITextView * textField = [self.subviews objectAtIndex:0];
    textField.frame = CGRectMake(5, 6, (310 - kRightSideMargin), 31); 
    
    [super drawRect:rect];
    

注: kRightSideMargin は、ヘッダー ファイルで設定した定数です。25に設定しています。

他の皆さんからの提案に感謝します。

于 2009-02-17T15:16:05.917 に答える
6

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つのコントロール間で一貫した外観を再度作成できる可能性があると思います。

于 2012-09-04T20:15:26.120 に答える
6

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 のインデックスと重ならないように十分な幅があることがわかりました。

于 2009-09-17T01:50:33.640 に答える
5

ViewDeckを使用していて、UISearchbarを 内に表示したいと考えていleftControllerます。

問題は、ナビゲーションを含む左側を開くと、右側のビットが検索フィールドと重なることです。

上書きすることでこれを取り除きましUISearchBarた。テキストフィールドは常に同じ幅になりますが、ある場合にはViewDeckが重なっており、別の場合にはViewDeckビットを非表示にしてからキャンセルボタンがスペースを占有します:

UISearchBar のサブクラス化

#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

ViewController クラス

私の Navigation クラスUISearchbarDelegateでは、検索結果を全画面表示にするために、次の 2 つのメソッドを上書きする必要があります。

- (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:

a
(出典:マイナス.com

フルスクリーンで検索します (ボタンとスコープ ボタンはアニメーション化されます)。

a
(出典:マイナス.com

于 2013-01-29T14:38:50.600 に答える
2

これをもう一度ドラッグして申し訳ありません。

UISearchBar を短くしたかったので、UISearchBarController を使用していますが、実際にはインデックスは必要ありません。これは、右側にオーバーレイがあるためです。

長い検索バー

これを行うには、1 つの空白項目で sectionIndex を偽造し、それを非表示にします。これが私がそれを行う方法です:

 - (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 が上部にスクロールされます)。このような:

代替テキスト

何よりも、検索を使用すると、全幅のバーが表示されます。

代替テキスト

于 2011-01-06T14:18:37.900 に答える
2

UIView を配置し、その UIView 内に検索バーを配置するだけです。UIView は UISearchBar と同じサイズでなければなりません。これは私のために働いた。

于 2011-02-22T12:13:47.760 に答える
1

Necropostingで申し訳ありませんが、テキストフィールドの右側に小さなスペースを作成する別の方法を見つけました。最初の行に検索バーを含むインデックス付きのテーブルビューがあるという問題がありました。これで、インデックスと検索バー(IBで作成)が重複していました。ほとんどすべてを試しましたが、成功しませんでした。textifieldの幅と高さのプロパティが応答しないようです...だから私はこれを思いついた:

searchBar.showsCancelButton = YES;

UIView *cButton = [searchBar.subviews objectAtIndex:2];

cButton.hidden = YES;

私はまだスペースのサイズを調整することはできませんが、これは今のところそれを行います...しかし...かなり奇妙な解決策...

于 2009-08-08T01:59:36.623 に答える
1

Interface Builder を使用する場合は、「検索バー」ではなく、「検索バーと検索表示コントローラー」を使用することが重要です。

于 2010-05-20T02:47:50.493 に答える
1

誰もが UI を変更する方法を提供しています。同じ結果を得る方法を発見しました。次の 2 つの実装を提供する必要があります。

  1. UISearchDisplayController を使用する さらに重要なことは、次のように初期化することです。

- (id)initWithSearchBar:(UISearchBar *)searchBar contentsController:(UIViewController *)viewController

有効な UISearchBar を設定しない (または nil を渡す) と、インデックスの UITextField の調整が妨げられます。

  1. 以下を実装して、タイトルの有効な配列を返す必要があります。

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView;

nil を返すと、インデックスは表示されず、UITextField は適切に調整されません。

私は Apple にバグ レポートを提出しました。これは、#1 ではなく #2 のみが必要であることが論理的に思われることを示唆しています。UISearchDisplayController の使用を要求するヒューマン インターフェイス ガイドライン (iPhone HIG) には何も見つかりませんでした。

于 2009-12-13T09:39:54.977 に答える
0

私はマイクのアドバイスに従ってUIViewを作成し、その中にナビゲーションバーとUISearchバーを配置しました。唯一の問題は、検索バーが最初に表示されるとき、その背景が通常のナビゲーションバーと同じであるということですか?

興味深いことに、検索をアクティブにした場合は、この「修正済み」の背景をキャンセルをクリックしてください!?

SDK 3.0を使用しているので、UISearchDisplayControllerをNIBにドラッグしたときに作成されたUISearchBarアイテムを削除し、上記のようにビューを作成して、ファイル所有者と検索ディスプレイコントローラーのsearchBarアウトレットに接続しました。

于 2009-11-23T17:29:50.627 に答える
0

それはうまくいきます!!!

[searchBar setContentInset:UIEdgeInsetsMake(5, 0, 5, 35)];

于 2010-05-05T18:57:18.693 に答える
0

もう 1 つのアプローチ (面倒ですが) は、検索バーのサイズを変更し、「ギャップ」をナビゲーション バーで埋めることです。私のために働きます。

于 2009-06-16T18:34:06.537 に答える
0

私が思いついたものはあまり良くありません。基本的に、検索バーに使用したいフレームで空のビューを作成します。次に、検索バーの背後に移動する UIToolbar を作成します。Y 値が -1 でなければならないことを除いて、そのフレームを UIView と同じフレームに設定してください。そうしないと、上部に 2 つの境界線が描画されます。次に、UISearchBar を作成しますが、フレームの幅を UIView よりも 30 (またはアプリにとって意味のあるもの) に設定します。それらをサブビューとして追加し、UIView を tableHeaderView として設定します。

于 2009-06-17T21:08:00.557 に答える