Должна ли клавиатура для UITextField занимать весь экран?

Кажется, что клавиатуре не нужно занимать весь экран, проверьте UPDATE в разделе "Вопрос" моего сообщения. Спасибо.

Описание

Используйте UITextField для размещения полноэкранной клавиатуры на экране.

ссылка

Я установил UISplitViewController, и я хотел бы, чтобы RootViewController (aka MasterViewController) имел UITextField с показанием клавиатуры. Затем я хотел бы получить результаты поиска справа (в "ResultViewController" (UIViewController).

Идея заключается в том, когда пользователь вводит, результаты предлагаются.

Что я пробовал:

Я сначала добавил UITextField в мой RootViewController через storyboard, но это заняло весь экран, когда я активировал клавиатуру с помощью textField.becomeFirstResponder().

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

class RootViewController: UIViewController {

 override func viewDidLoad() {

    let alertController = UIAlertController(title: "Search", message: "Search for something!.", preferredStyle: UIAlertControllerStyle.Alert)

    alertController.addTextFieldWithConfigurationHandler({(textField: UITextField!) in
        textField.placeholder = "Search"
    })
    self.addChildViewController(alertController)
    alertController.view.frame = self.view.frame
    self.view.addSubview(alertController.view)
 }
}

Вопрос:

При использовании UISplitViewController как я могу заставить клавиатуру оставаться в ней RootViewController и не занимать весь экран?

ОБНОВЛЕНИЕ: Похоже, что это было реализовано в приложении Netflix на новом Apple TV. Клавиатура сверху и занимает всю ширину. Дно разделено на две секции. Слева - предлагаемое слово, а справа - просмотр коллекции видеороликов возможных видеороликов. Все обновляется по мере ввода пользователем.

Если это считается плохим дизайном для Apple TV, то не стесняйтесь указать, почему.

Снимок экрана:

Это то, что я сейчас получаю. Текстовое поле открывает клавиатуру, которая занимает весь экран.

введите описание изображения здесь

Ответ 1

Введение:

Наконец, я смог реализовать это, не используя TVML templates. Окончательное решение выглядит примерно так:

текстовая клавиатура и результаты на одном представлении

Общая идея заключается в создании UICollectionViewController с UICollectionViewCell. Затем программно добавьте клавиатуру и добавьте ее в TabViewController через AppDelegate.


Как реализовать это представление поиска с результатами:

Шаг 1: Создание раскадровки и контроллера

Откройте свою раскадровку и создайте UICollectionViewController (с пользовательским классом "SearchResultViewController" ), который не прикреплен к вашему TabViewController.

Внутри создайте свой UICollectionViewCell с любыми labels и images, которые вы хотите. UICollectionViewCell должен иметь собственный класс под названием "VideoSearchCell".

В вашем SearchViewController не должно быть ничего другого.

Шаг 2: добавление SearchViewController в TabViewController и реализация клавиатуры через AppDelegate программно

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    override init() {

    }
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        if let tabController = window?.rootViewController as? UITabBarController {
            tabController.viewControllers?.append(configueSearchController())
        }

        return true
    }

    //... standard code in-between

    func configueSearchController() -> UIViewController {

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        guard let searchResultController = storyboard.instantiateViewControllerWithIdentifier(SearchResultViewController.storyboardIdentifier) as? SearchResultViewController else {
            fatalError("Unable to instatiate a SearchResultViewController from the storyboard.")
        }

        /*
         Create a UISearchController, passing the `searchResultsController` to
         use to display search results.
         */
        let searchController = UISearchController(searchResultsController: searchResultsController)
        searchController.searchResultsUpdater = searchResultsController
        searchController.searchBar.placeholder = NSLocalizedString("Enter keyword (e.g. Gastric Bypass)", comment: "")

        // Contain the `UISearchController` in a `UISearchContainerViewController`.
        let searchContainer = UISearchContainerViewController(searchController: searchController)
        searchContainer.title = NSLocalizedString("Search", comment: "")

        // Finally contain the `UISearchContainerViewController` in a `UINavigationController`.
        let searchNavigationController = UINavigationController(rootViewController: searchContainer)
        return searchNavigationController

    }

}

После того, как вы добавили базовый скелет своего SearchResultViewController, вы сможете увидеть клавиатуру в верхней части окна "Поиск" при запуске проекта.

Шаг 3: Обработка результатов ввода и обновления текста

Вы заметите, что в моем filterString я использую класс ScoreVideo и StringSearchService. Это только классы, которые я использую для фильтрации моего списка видео (aka: self.vms.videos).

Итак, в конце, просто возьмите filterString, создайте новый отфильтрованный список и перезагрузите представление коллекции.

import UIKit
import Foundation

class SearchResultViewController: UICollectionViewController, UISearchResultsUpdating {


    //private let cellComposer = DataItemCellComposer()
    private var vms: VideoManagerService!

    private var filteredVideos = [ScoreVideo]()
    static let storyboardIdentifier = "SearchResultViewController"

    var filterString = "" {
        didSet {
            // Return if the filter string hasn't changed.
            guard filterString != oldValue else { return }
                // Apply the filter or show all items if the filter string is empty.
                if self.filterString.isEmpty {
                    self.filteredVideos = StringSearchService.start(self.filterString, videos: self.vms.videos)
                }
                else {
                    self.filteredVideos = StringSearchService.start(self.filterString, videos: self.vms.videos)
                }
           self.collectionView?.reloadData()
        }
    }

    override func viewDidLoad() {
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        self.vms = appDelegate.getVideoManagerService()

    }

    // MARK: UICollectionViewDataSource

    override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }

    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        print("count..\(filteredVideos.count)")
        return filteredVideos.count
    }

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        // Dequeue a cell from the collection view.
        return collectionView.dequeueReusableCellWithReuseIdentifier(VideoSearchCell.reuseIdentifier, forIndexPath: indexPath)
    }

    // MARK: UICollectionViewDelegate

    override func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
        guard let cell = cell as? VideoSearchCell else { fatalError("Expected to display a `VideoSearchCell`.") }
        let item = filteredVideos[indexPath.row]
        cell.configureCell(item.video)

    }

    override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        dismissViewControllerAnimated(true, completion: nil)
    }

    // MARK: UISearchResultsUpdating

    func updateSearchResultsForSearchController(searchController: UISearchController) {
        print("updating... \(searchController.searchBar.text)")
        filterString = searchController.searchBar.text!.lowercaseString ?? ""
    }
}

Если что-то неясно, не стесняйтесь задавать некоторые вопросы. Я, скорее всего, что-то забыл. Спасибо.

Ответ вдохновлен пример кода яблока

Ответ 2

Представление клавиатуры только на части экрана невозможно при использовании встроенных методов SDK.

A UIKeyboard представлен в окне приложения, а не в любом из его подзонов. Чтобы выполнить желаемое поведение, используйте рефлексию, чтобы получить ссылку на объект UIKeyboard в вашем приложении UIWindow (путем итерации через оконные окна) и изменить его фрейм, чтобы он соответствовал ширине вашего RootViewController.

Чтобы начать, вы можете посмотреть частный заголовок tvOS UIKeyboard.h здесь. Я должен отметить, что Apple может иметь код для отключения изменения размера клавиатуры (например, в willMoveToWindow: или didMoveToWindow). Это поведение undefined, и ваше перемещение будет отличаться, если оно вообще работает вообще.

Вы удалили свой комментарий о моем ответе о приложении Netflix, но, как говорит shirefriendship в своем ответе, Netflix, вероятно, использует шаблон TVML. Вы можете пойти по этому маршруту и ​​построить гибридное приложение tvOS/TVML. Кроме того, вы также можете вручную создать клавиатуру с помощью UICollectionView в RootViewController.

Ответ 3

Netflix использует шаблоны TVML для реализации своего поиска вместо UIKit. Вы можете выполнить ту же эстетику, что и Netflix, используя searchTemplate. Вы можете научиться смешивать TVML и UIKit здесь. К сожалению, searchTemplate не настраивается достаточно, чтобы соответствовать вашему желаемому расположению. В настоящее время нет способа реализовать ваш конкретный макет для Apple TV.