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

IOS 11 SearchBar в NavigationBar

С iOS 11 Apple переработала UISearchBar, сделав углы более круглыми и увеличивая высоту. Добавить UISearchBar к навигационной панели довольно просто, просто установив его в качестве titleView элемента navigationItem с помощью navigationItem.titleView = searchBar.

Тем не менее, в iOS 11, похоже, он работает не так, как ожидалось. Взгляните на экраны, где мы сравниваем одни и те же настройки с использованием iOS 10 и iOS 11

iOS 10 enter image description here

iOS 11 enter image description here

Вы можете четко видеть, что панель поиска увеличивает размер панели навигации, но кнопки панели не выровнены правильно. Кроме того, панель поиска больше не использует доступное пространство слева.

Помещение панели поиска в представление-обертку для получения кнопки отмены на iPad, как описано здесь Кнопка отмены не отображается в UISearchBar, также больше не работает, так как панель поиска тогда вообще не видна.

Если у кого-то есть подобные проблемы или вы уже знаете, как это исправить/улучшить, я был бы очень благодарен.

Это было построено с использованием Xcode 9 Beta 4. Возможно, будущие выпуски исправят эту проблему.

UPDATE:

Поскольку это не исправлено, мы решили использовать следующее решение. Мы добавили новый UIBarButtonItem в NavBar, который затем представляет новый ViewController, где мы помещаем только searchBar и ничего больше в NavBar, который, кажется, работает. Использование выбранного ответа может быть лучшим решением, поскольку Apple с iOS 11 хочет, чтобы мы использовали этот новый дизайн, даже если он не дает нам того результата, который мы изначально хотели. Другим способом решения этой проблемы может быть пользовательский SearchBar, но это уже другая тема.

4b9b3361

Ответ 1

В iOS 11 появилось новое свойство searchController для функции navigationItem.

https://developer.apple.com/documentation/uikit/uinavigationitem/2897305-searchcontroller

Используйте это как...

if #available(iOS 11.0, *) {
     navigationItem.searchController = searchController
} else {
     // Fallback on earlier versions
     navigationItem.titleView = searchController?.searchBar
}

В Objective-C оператор if выглядит так:

if (@available(iOS 11.0, *)) {

В iOS 11, если вы не установите navigationItem.hidesSearchBarWhenScrolling = false, панель поиска может быть сначала скрыта, если пользователь не прокрутит страницу вниз, чтобы открыть ее. Если вы установите для него значение false, оно окажется уложенным ниже, где заголовок будет идти без прокрутки пользователя.

Ответ 2

Вы можете изменить высоту UISearchBar в iOS 11, добавив ограничение высоты 44:

if #available(iOS 11.0, *) {
    searchBar.heightAnchor.constraint(equalToConstant: 44.0).isActive = true
}

Ответ 3

У меня была одна и та же проблема, и через несколько дней я разобрался с этой страницей - https://translate.google.com/translate?hl=en&sl=zh-CN&u=http://www.jianshu.com/p/262f6e34a7d3&prev=search.

Эта страница приводит к этому git repo - https://github.com/DreamTravelingLight/searchBarDemo - этот демонстрационный проект показывает, как использовать старый путь с titleView для все еще есть searchBar без вопроса о размерах.

Ключевыми строками являются эти

_searchBar = [self addSearchBarWithFrame:CGRectMake(0, 0, kScreenWidth - 2 * 44 - 2 * 15, 44)];
UIView *wrapView = [[UIView alloc] initWithFrame:_searchBar.frame];
[wrapView addSubview:_searchBar];
self.navigationItem.titleView = wrapView;

Если вы вставляете UISearchBar внутри представления и устанавливаете этот wrapView в качестве titleView, UISearchBar будет иметь размер, который вы ему устанавливаете, и подойдет к панели навигации, как предполагалось.

Спасибо, Дэвид

Ответ 4

Если вы действительно хотите использовать собственный UISearchBar (и избегать необходимости создания своих пользовательских компонентов) в iOS 11+ navigationBar, вы можете создать контейнерное представление для этого searchBar, чтобы иметь полный контроль над кадром, Это контейнерное представление будет суперпредставлением searchBar, которое вы передаете.

Что-то вроде:

class SearchBarContainerView: UIView {

    let searchBar: UISearchBar

    required init?(coder aDecoder: NSCoder) {
        searchBar = UISearchBar()
        super.init(coder: aDecoder)
    }

    init(searchBar: UISearchBar) {
        self.searchBar = searchBar
        super.init(frame: CGRect(x: 0.0, y: 0.0, width: 0.0, height: 44.0))
        addSubview(searchBar)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        searchBar.frame = bounds
    }
}

А потом:

let containerView = SearchBarContainerView(searchBar: searchController.searchBar)
containerView.frame.size.width = navigationController?.navigationBar.frame.size.width ?? 0.0
navigationItem.titleView = containerView

Обратите внимание,, что это всего лишь небольшая демонстрация, которая не готова к смене кадров navigationBar (поворот экрана и т.д.). Вы можете решить это, например, autoresizingMask.

Ответ 5

Я думаю, вам придется иметь дело с настройкой нового свойства UINavigationItem.searchController для вашего объекта UISearchController. Это то, как вы получаете новый эффект, как видно в сообщениях. Похоже, что прежнее поведение просто исчезло. Надеюсь, я ошибаюсь, но весь API получил капитальный ремонт за 11. Я знаю, что это багги вообще, поэтому мы увидим с новыми бетами и GM, если это будет исправлено. (Запись во время бета-версии 6)

Ответ 6

Это помогло мне:

    if ([self.navigationItem respondsToSelector:@selector(setSearchController:)])
    {
        [self.navigationItem performSelector:@selector(setSearchController:) withObject:self.searchController];
    }
    else
    {
        self.tableView.tableHeaderView = self.searchController.searchBar;
    }

Ответ 7

Я опробовал searchController и searchBar, но обнаружил, что searchBar соответствует моим требованиям (поиск по нажатию кнопки поиска).

-(void)searchBarSetUp{
//Search button to reload the radio content.
self.searchButton.action = @selector(addSearchBarToNavigationTitleView);
self.searchButton.target = self;

//search bar initialization
searchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
searchBar.delegate = self;
searchBar.showsCancelButton = YES;
[searchBar sizeToFit]; }

-(void)addSearchBarToNavigationTitleView {
// Install the search bar as the table header.
self.navigationItem.titleView = searchBar;}

Я тоже столкнулся с трудностями при работе с черным экраном, если использую searchControl.