it-swarm.com.de

Größe des UISearchBar TextField ändern?

Ich habe eine UITableView mit einem Index auf der Seite; Ich möchte eine UISearchBar hinzufügen, aber der Index überschneidet sich mit dem "x", um die Suche zu löschen. In der Anwendung "Kontakte" ist mir aufgefallen, dass das Textfeld in der UISearchBar entsprechend angepasst wurde, aber ich kann nicht herausfinden, wie dies in meiner eigenen App geschieht.

Ich habe folgendes in viewDidLoad ausprobiert, aber es scheint nicht zu funktionieren.

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)];

Irgendwelche Ideen?

30
Padraig

es ist viel einfacher als alle diese Vorschläge. Im Interface Builder können Sie statt der Suchleiste als Kopfzeile der Tabellenansicht eine Ansicht einfügen. Fügen Sie dann eine Navigationsleiste in diese Ansicht ein. Ziehen Sie den linken Ziehpunkt der Navigationsleiste nach rechts und ziehen Sie ihn nach rechts, bis NB nur 25 Pixel breit ist. Löschen Sie den Titel in der N B (doppelklicken Sie, um ihn auszuwählen, und löschen Sie ihn dann). Fügen Sie dann in derselben Ansicht eine Suchleiste hinzu. Bewegen Sie den rechten Ziehpunkt nach links und stellen Sie ihn so ein, dass er am N B anliegt. Das war's.

Sie können eine Abbrechen-Schaltfläche auch aktivieren, wenn Sie möchten, und der Index wird nicht überlappt (bleibt innerhalb der Suchleiste).

Anscheinend kann eine Tabellenansicht nur eine Unteransicht in der Kopfzeile haben. Deshalb müssen Sie zuerst die Ansicht, dann die N B und die Suchleiste einfügen.

UPDATE: Siehe Beginn der iPhone-Entwicklung von Apress, S. 27. 241 von SDK 3 Ausgabe. Sie deaktivieren den Index während der Suche.

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

Sie sprechen auch über das Hinzufügen einer Lupe an der Spitze des Index.

Rundum ein tolles Buch.

30
Mike

Warum verkleinern Sie nicht einfach die eigentliche UISearchBar horizontal und platzieren Sie eine (leere) UINavigationBar rechts davon? Sie werden exakt denselben Hintergrund darstellen.

Besser als das Innere der Apple-Objekte zu hacken, die sich ändern könnten.

Wenn Sie die Breite der UISearchBar animieren, werden Sie auch feststellen, dass das innere Textfeld nicht mit animiert wird. Sie können dies beheben, indem Sie UISearchBars "layoutSubviews" innerhalb Ihres Animationsblocks aufrufen, nachdem Sie den Frame geändert haben. (Hier bestimmt es die Größe des inneren Textfeldes)

16
Nick Farina

Ok, ich habe eine Lösung gefunden.

  1. Erstellen Sie eine Unterklasse von UISearchBar
  2. Fügen Sie diesen Code in die drawRect: -Methode ein.

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

Hinweis: kRightSideMargin ist eine Konstante, die ich in meiner Headerdatei festgelegt habe. Ich habe es auf 25 gesetzt.

Danke für die Vorschläge von allen anderen.

8
Padraig

Ab iOS 6 funktionierte die Navigationsleistenlösung für mich nicht gut, da die UISearchBar und die UINavigationBar jetzt etwas anders aussehen. Also wechselte ich zu einem ähnlichen Ansatz wie Padraig, indem ich die UISearchBar-Klasse bildete.

@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

Edit: Ah, ich habe es nicht ausprobiert, aber ich denke, Sie können clipToBounds = YES einer Navigationsleiste so einstellen, dass der neue Schatten deaktiviert wird. Dadurch entsteht wieder ein konsistenter Look zwischen den beiden Steuerelementen.

6
Ernie Thomason

Wie Padraig darauf hingewiesen hat, müssen Sie lediglich die searchBar ausbilden. Erstellen Sie Ihre UISearchBar-Unterklasse und fügen Sie der layoutSubviews-Methode den folgenden Code hinzu:

- (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); 
    }
}

Dies durchläuft alle Unteransichten und überprüft sie mit dem Typ UITextField. Wenn es sich also jemals in der Reihe der Unteransichten bewegt, wird es trotzdem erfasst. Ich fand 285 zu breit genug, um nicht mit dem Index meiner tableView zu überlappen.

6
timmytheRock

Ich benutze ViewDeck und möchte eine UISearchbar in der leftController anzeigen.

Wenn ich nun die linke Seite öffne, die die Navigation enthält, überlappt das rechte Bit mein Suchfeld.

Ich habe dies durch das Überschreiben von UISearchBar losgelassen, das Textfeld hat immer die gleiche Breite, aber in einem Fall überschneidet sich ViewDeck und in dem anderen Fall verberge ich das ViewDeck-Bit, und dann wird die Schaltfläche zum Abbrechen den Platz beanspruchen:

Unterklasse 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-Klasse

In meiner Navigationsklasse muss ich diese beiden UISearchbarDelegate-Methoden überschreiben, um mit den Suchergebnissen zum Vollbildmodus zu gelangen:

- (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;
}

Ergebnis

ViewDeck zeigt nach rechts:

eine http://i5.minus.com/jA34MnXVqPZez.png

Suche im Vollbildmodus (Die Schaltflächen und die Schaltflächen des Bereichs werden animiert).

ein http://i2.minus.com/jjKEgXLur1kH6.png

5
Besi

Tut mir leid, das alles wieder hochziehen zu müssen.

Ich wollte, dass die UISearchBar kürzer ist, und ich verwende einen UISearchBarController, ohne jedoch den Index zu wollen. Dies liegt daran, dass ich eine Überlagerung nach rechts habe:

Long search bar

Dazu fälsche ich einen sectionIndex mit einem leeren Element und blende ihn dann aus. So mache ich das:

 - (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;
 }

Dies verkürzt die UISearchBar und blendet den Index aus, sodass er nicht angezapft werden kann (ein kleiner Abschnitt würde sich sonst links von der Überlagerung befinden und beim Antippen die UITableView nach oben scrollen). So was:

alt text

Das Beste ist, wenn Sie die Suche verwenden, wird immer noch die gesamte Breite angezeigt:

alt text

2
Alastair Stuart

Fügen Sie einfach eine UIView ein und fügen Sie die Suchleiste in diese UIView ein. UIView muss die gleiche Größe wie UISearchBar haben. Dies hat für mich funktioniert.

2
Ideveloper

Tut mir leid für Nekroposting, aber ich habe einen anderen Weg gefunden, etwas Platz auf der rechten Seite des Textfelds zu schaffen ... Ich hatte das Problem, dass ich eine indizierte TableView mit einer Suchleiste als erste Zeile hatte. Jetzt überlappten sich der Index und die Suchleiste (erstellt in IB, übrigens). Es hat fast alles versucht ohne Erfolg. Es scheint, dass die Eigenschaften width und height des Textfelds nicht reagieren ... Also habe ich mir folgendes ausgedacht:

searchBar.showsCancelButton = YES;

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

cButton.hidden = YES;

Ich kann die Größe des Raums immer noch nicht anpassen, aber das tut es jetzt ... obwohl ... ziemlich seltsame Lösung ...

1
swissdude

Jeder hat Möglichkeiten zur Änderung der Benutzeroberfläche zur Verfügung gestellt. Ich habe herausgefunden, wie man identische Ergebnisse erzielt. Sie müssen die folgenden zwei Implementierungen bereitstellen:

  1. Verwenden Sie UISearchDisplayController Stellen Sie vor allem sicher, dass Sie ihn initialisieren mit:

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

Wenn Sie keine gültige UISearchBar festlegen (oder Null übergeben), wird die Anpassung des UITextFields für den Index verhindert.

  1. Sie müssen ein gültiges Array von Titeln zurückgeben, indem Sie Folgendes implementieren:

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

Wenn Sie null zurückgeben, wird der Index nicht angezeigt und das UITextField wird nicht richtig angepasst.

Ich habe einen Fehlerbericht an Apple übermittelt, der darauf hinweist, dass es logisch erscheint, dass nur # 2 erforderlich ist, nicht # 1. Ich habe in der Human Interface Guideline (iPhone HIG) nichts gefunden, was die Verwendung des UISearchDisplayControllers erfordert.

1
Mark

Das in UISearchBar verwendete Textfeld ist eine Unterklasse von UITextField mit dem Namen UISearchBarTextField.

AFAIK, es gibt keine Möglichkeit, die Größe eines UISearchBarTextField mithilfe der öffentlichen API zu ändern, und die private API gibt nicht viel preis.

Vielleicht können Sie sich die UISearchBarTextField-Subviews ansehen, falls vorhanden.

UPDATE: Nicht.

UPDATE 2: Ich denke, Sie sollten sich die RightView-Eigenschaft von UITextField ansehen. Der folgende Code scheint zwar ein guter Ausgangspunkt zu sein, auch wenn er nicht funktioniert:

UIView *emptyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
[textField setRightView:emptyView];
[textField setRightViewMode:UITextFieldViewModeAlways];
[emptyView release];
1
Can Berk Güder

Der Schlüssel ist die Verwendung von "Search Bar and Search Display Controller" und nicht die "Search Bar" bei Verwendung des Interface Builder.

1
Graeme Wicksted

Was ich mir ausgedacht habe, ist nicht viel besser. Grundsätzlich mache ich eine leere Ansicht mit dem Rahmen, den ich für die Suchleiste verwenden möchte. Dann erstelle ich eine UIToolbar, um hinter die Suchleiste zu gehen. Stellen Sie sicher, dass der Frame auf den gleichen Frame wie UIView gesetzt ist, außer dass der Y-Wert -1 sein muss. Andernfalls werden oben zwei Ränder gezeichnet. Erstellen Sie als Nächstes Ihre UISearchBar, stellen Sie jedoch die Breite des Frames auf 30 (oder was für Ihre App sinnvoll ist) weniger ein als die UIView. Fügen Sie sie als Unteransichten hinzu und legen Sie Ihre UIView als tableHeaderView fest.

0
Jeff Kelley

Ich folgte Mikes Rat, indem ich eine UIView erstellte und dann eine Navigationsleiste und eine UISearch-Leiste einlegte. Das einzige Problem ist, dass die Suchleiste zum ersten Mal angezeigt wird. Ihr Hintergrund entspricht normalerweise einer Navigationsleiste.

Interessanterweise, wenn ich die Suche aktiviere, dann klicken Sie auf den Hintergrund dieses 'Fixes'!

Ich verwende das SDK 3.0, also entfernte ich das UISearchBar-Element, das erstellt wurde, als ich einen UISearchDisplayController in meine NIB gezogen hatte, nahm die Ansicht wie oben beschrieben vor und verdrahtete sie mit dem Dateibesitzer und dem searchBar-Anschluss im Such-Display-Controller.

0
petert

Es funktioniert gut !!!

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

0
Oscar

Ein weiterer Ansatz (durch langwierige) wäre, die Suchleiste in der Größe zu verändern und die "Lücke" mit einer Navigationsleiste zu füllen. Funktioniert bei mir.

0
Bart Jacobs

Es sieht aus, als ob Apple die Ansicht in der Größe ändert (beachten Sie, dass der Index nach rechts und außerhalb des Bildschirms animiert wird), sodass er größer als der Bildschirm wird.

Ich könnte mir vorstellen, dass Sie die searchBarTextDidBeginEditing:-Methode der UISearchBarDelegate implementieren müssen, um dies an der entsprechenden Stelle auszulösen. Dies fühlt sich jedoch etwas hackig an, vielleicht gibt es eine bessere Möglichkeit, dies zu tun.

0