Изменение размера текстового поля 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)];
Любые идеи?
Ответы
Ответ 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 для индекса.
- Вы должны вернуть действительный массив заголовков, выполнив:
- (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 никогда не работало для меня, так как они имели разные взгляды сверху и снизу.