Подтвердить что ты не робот

Изменение размера текстового поля UISearchBar?

У меня есть UITableView с индексом сбоку; Я хочу добавить UISearchBar к нему, но индекс перекрывается с "x", чтобы очистить поиск. Я заметил, что в приложении "Контакты" текстовое поле в UISearchBar изменено для этого, но я не могу решить, как это сделать в моем собственном приложении.

Я попробовал следующее в своем представленииDidLoad, но он не работает.

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

Любые идеи?

4b9b3361

Ответ 1

это намного проще, чем все эти предложения. В построителе интерфейсов вместо того, чтобы помещать строку поиска в качестве заголовка вашего представления таблицы, вы можете поместить представление. Затем поместите панель навигации в этот вид. Возьмите левую ручку изменения размера панели навигации и потяните ее вправо, пока N B не будет шириной всего 25 пикселей. Очистите заголовок в N B (дважды щелкните его, а затем удалите). Затем добавьте панель поиска в тот же вид. Переместите правую ручку изменения размера влево, отрегулируйте так, чтобы она соответствовала N B. Что это.

Вы можете включить кнопку отмены, если хотите, и она также не будет перекрывать индекс (остается в строке поиска).

По-видимому, в представлении таблицы может быть только 1 subview в своем заголовке, поэтому вам нужно сначала поместить View, а затем N B и строку поиска.

ОБНОВЛЕНИЕ: см. начало разработки iPhone от Apress, p. 241 версии SDK 3. Вы просто отключите индекс во время поиска.

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

Также они говорят о добавлении увеличительного стекла к вершине индекса.

Великая книга вокруг.

Ответ 2

Почему бы просто не сделать реальный UISearchBar меньшим по горизонтали и поместить (пустой) UINavigationBar справа от него? Они будут отображать один и тот же фон.

Лучше, чем взломать внутренние объекты Apple, которые могут измениться.

Кроме того, при анимации ширины UISearchBar вы заметите, что внутреннее текстовое поле не анимируется вместе с ним. Вы можете исправить это, вызвав UISearchBar "layoutSubviews" в вашем блоке анимации после изменения его фрейма. (где он определяет размер внутреннего текстового поля)

Ответ 3

Хорошо, я придумал решение.

  • Создайте подкласс UISearchBar
  • Включите этот код в метод drawRect:.

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

Примечание: kRightSideMargin - это константа, которую я установил в своем файле заголовка; У меня установлено значение 25.

Спасибо за предложения от всех остальных.

Ответ 4

Как сказал Падрейг, все, что вам нужно сделать, - это подкласс из поиска. Создайте подкласс 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. Таким образом, если он когда-либо движется в своей линейке subviews, это все равно схватит его. Я нашел 285 достаточно просто, чтобы не накладываться на индекс моего tableView.

Ответ 5

Как и в iOS 6, решение для навигационной панели плохо работает для меня из-за немного разных взглядов между UISearchBar и UINavigationBar. Итак, я переключился на нечто похожее на подход Padraig, подклассифицировав UISearchBar.

@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, чтобы отключить ее новую тень, тем самым создав последовательный внешний вид между двумя элементами управления.

Ответ 6

Я использую ViewDeck и хочу показать панель UISearch внутри 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

В моем классе навигации мне нужно переписать эти два метода 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 показывает справа:

a
(источник: minus.com)

Поиск в полноэкранном режиме (кнопки и кнопки области видимости анимированы).

a
(источник: minus.com)

Ответ 7

Извините, что перетащить все это снова.

Я хотел, чтобы UISearchBar был короче, и я использую UISearchBarController, но фактически не хочу индекса. Это потому, что у меня есть наложение справа:

Long search bar

Чтобы сделать это, я подделываю 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 вверху). Вот так:

alt text

Лучше всего, когда вы используете поиск, вы все равно получаете полосу ширины:

alt text

Ответ 8

Просто поместите UIView и поместите панель поиска внутри этого UIView. UIView должен иметь тот же размер, что и UISearchBar. это сработало для меня.

Ответ 9

Текстовое поле, используемое в UISearchBar, является подклассом UITextField, называемым UISearchBarTextField.

AFAIK, нет способа изменить размер UISearchBarTextField с использованием общедоступного API, а частный API также не показывает ничего.

Возможно, вы можете взглянуть на subviews UISearchBarTextField, если он есть.

ОБНОВЛЕНИЕ: Это не так.

ОБНОВЛЕНИЕ 2: Я думаю, вам стоит взглянуть на свойство rightView UITextField. Код ниже, хотя он не работает, кажется хорошей отправной точкой:

UIView *emptyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
[textField setRightView:emptyView];
[textField setRightViewMode:UITextFieldViewModeAlways];
[emptyView release];

Ответ 10

Извините за Necroposting, но я нашел другой способ сделать небольшое пространство справа от текстового поля. У меня возникла проблема, что у меня был индексированный tableview с поисковой панелью в качестве первой строки. Теперь индекс и поисковая панель (сделанные в IB, кстати) были перекрывающимися. Он пробовал почти все без успеха. Кажется, что свойства ширины и высоты textifield не отвечают... Итак, я придумал следующее:

searchBar.showsCancelButton = YES;

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

cButton.hidden = YES;

Я все еще не могу настроить размер пространства, но это делает это на данный момент... хотя... довольно странное решение...

Ответ 11

Каждый предоставил способы изменения пользовательского интерфейса. Я обнаружил, как получить одинаковые результаты. Вы должны предоставить следующие две реализации:

  • Использовать UISearchDisplayController Что еще более важно, убедитесь, что вы инициализируете его:

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

Невозможность установить допустимый UISearchBar (или передающий нуль) будет препятствовать настройке UITextField для индекса.

  1. Вы должны вернуть действительный массив заголовков, выполнив:

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

Если вы вернете нуль, индекс не будет отображаться, а UITextField не будет правильно настроен.

Я отправил отчет Apple об ошибке, предположив, что логично, что требуется только # 2, а не # 1. Я ничего не нашел в Руководстве по интерфейсу человека (iPhone HIG), требующем использования UISearchDisplayController.

Ответ 12

Ключ состоит в том, чтобы использовать "Панель поиска и поисковый дисплей", а не "Панель поиска" при использовании Interface Builder.

Ответ 13

Кажется, что Apple изменит размер представления (обратите внимание, что индекс анимирован вправо, вне экрана), делая его больше, чем экран.

Я бы предположил, что вам нужно реализовать метод searchBarTextDidBeginEditing: для UISearchBarDelegate, чтобы вызвать это в соответствующей точке. Это, однако, чувствует себя немного взломанным, может быть, есть лучший способ сделать это.

Ответ 14

Еще одна оценка (хотя и утомительная) - это изменить размер панели поиска и заполнить "пробел" навигационной панелью. Работает для меня.

Ответ 15

То, что я придумал, не намного лучше. В принципе, я делаю пустой вид с фреймом, который я хочу использовать для панели поиска. Затем я создаю UIToolbar, чтобы идти за панель поиска. Обязательно установите его фрейм в тот же фрейм, что и UIView, за исключением того, что значение Y должно быть равным -1; в противном случае вы получите две границы, нарисованные сверху. Затем создайте свой UISearchBar, но установите ширину кадра до 30 (или что-то другое для вашего приложения) меньше, чем UIView. Добавьте их в виде subviews и установите UIView как tableHeaderView.

Ответ 16

Я последовал совету Майка, сделав UIView, а затем разместил в нем панель навигации и панель UISearch. Единственная проблема - первый раз, когда в строке поиска отображается, что фон такой же, как и панель навигации?

Интересно, что если я активирую поиск, то нажмите отменить фон этого "фиксированного"!?

Я использую SDK 3.0, поэтому я удалил элемент UISearchBar, сделанный, когда я перетащил UISearchDisplayController в свой NIB, затем сделал представление, как описано выше, и связал его с владельцем файла и выводом searchBar на экране поиска контроллер.

Ответ 17

Он отлично работает!!!

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

Ответ 18

searchBar.layoutMargins = UIEdgeInsetsMake(0, 0, 0, rightPad);

Мое старое решение по изменению фрейма UITextField перестало работать в iOS 13. Размещение UINavigationBar справа от UISearchBar никогда не работало для меня, так как они имели разные взгляды сверху и снизу.