ITVDN logo
Видеокурсы по
программированию

Доступ более чем к 7700 видеоурокам от $19.99

Подписка
ITVDN logo
Видеокурсы по
программированию

Доступ более чем к 7700 видеоурокам от $19.99

Подписка

Здравствуйте, дорогие читатели.

В этом уроке мы научимся:

  • скрывать клавиатуру мобильного устройства для полей “Text Field”, “Text View”;
  • добавлять  различные типы клавиатур цифровая, e-mail, URL;
  • добавлять панель инструментов на клавиатуру мобильного устройства;
  • добавим панель поиска в список товаров;
  • добавим предварительный просмотр на ячейки списка товаров с использованием аппаратной технологии 3D Touch.

Откройте проект Warehouse.

В панели навигатора откройте модуль “ViewController.swift”, нам необходимо унаследоваться от протокола “UITextFieldDelegate”:

Теперь реализуем этот протокол:

Разберем код построчно.

На 43 строке мы реализовали метод “textFieldShouldReturn” протокола “UITextFieldDelegate”. Метод вызывается, когда вы на клавиатуре мобильного устройства нажимаете кнопку “Return” (Done, Next).

Метод принимает один аргумент, который содержит экземпляр текстового поля, для которого была вызвана клавиатура. Возвращаемое значение данного метода говорит о том, скрывать клавиатуру или нет. Мы возвращаем значение “true”, означающее, что мы хотим скрывать клавиатуру.

С 44 по 51 строку идет поиск активного в данный момент текстового поля, куда пользователь установил курсор. Данный код мы добавили, чтобы сделать следующую функциональность. Пользователь ставит курсор в поле “Имя пользователя”, вводит имя пользователя. Затем на клавиатуре нажимает кнопку “Next”, курсор автоматически попадает на поле пароль. После того, как пользователь ввел пароль, он нажимает кнопку “Done” и клавиатура пропадает.

Чтобы поставить курсор в текстовое поле, необходимо на экземпляре этого текстового поля вызвать метод “becomeFirstResponder”.

Чтобы убрать курсор с текстового поля, необходимо на экземпляре текстового поля вызвать метод “resignFirstResponder”.

На 55 строке мы переопредили метод “touchesBegan”. Данный метод объявлен в классе “UIResponder”, класс “UIViewController” наследуется от этого класса.

Метод “touchesBegan” вызывается, когда вы нажимаете в любую свободную область экрана, находящуюся вне редактируемого текстового поля.

На 56 строке мы обращаемся к внутреннему свойству “view”, которое содержит экземпляр представления, подвязанного к контроллеру. И на нем вызываем метод “endEditing” со значение аргумента “true”.

Данный метод посылает представлению событие о том, что необходимо завершить редактирование элементов управления, которые на нем расположены.

Но это еще не все. Теперь необходимо сообщить текстовым полям, что мы реализовали для них соответствующий протокол “UITextFieldDelegate” и хотим проинициализировать у них свойство “delegate”.

Обновите код в методе “viewDidLoad”:

На 30 и 31 строке мы проинициализировали свойство “delegate” для текстовых полей “Имя пользователя” и “Пароль пользователя”. Теперь эти поля знают, откуда им надо вызывать реализацию метода “textFieldShouldReturn”.

Откройте модуль “Main.storyboard”, найдите и выделите представление “View Controller”. На этом представлении выделите текстовое поле “Имя пользователя”. В панели свойств откройте вкладку “Show the Attributes inspector”. Найдите свойство “Return key” и установите в него значение “Next”.

Затем выделите текстовое поле “Пароль пользователя” и установите для его свойства “Return key” значение “Done”.

Запустите приложение.

Если клавиатура у вас не открылась в симуляторе, выполните в меню симулятора “Hardware -> Keyboard -> Toggle Software Keyboard”.

Теперь давайте разберем, какие типы клавиатур имеются и в каком свойстве они задаются. Потренируемся пока на текстовом поле “Имя пользователя”. Выделите это текстовое поле в дизайнере и в панели свойств на вкладе “Show the Attributes inspector” найдите свойство “Keyboard Type”, в этом свойстве задается тип вызываемой клавиатуры для текстового поля.

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

  • Default – клавиатура по умолчанию, содержит в себе все раскладки.
  • Numbers and punctuation – клавиатура содержит цифры и знаки пунктуации.
  • URL – клавиатура содержит все необходимые символы для быстрого ввода URL адреса.
  • Number Pad – клавиатура содержит только цифры, без знаков разделения на дробные составляющие.
  • Phone Pad – телефонная клавиатура.
  • E-mail Address – клавиатура содержит необходимые символы для быстрого ввода e-mail адреса.
  • Decimal Pad – клавиатура содержит цифры и знаки разделения на дробные составляющие.

Теперь добавим функциональность закрытия клавиатуры для представления редактирования продукта. Откройте модуль “ProductViewController.swift”. Добавьте наследование от двух протоколов “UITextFieldDelegate”, “UITextViewDelegate”, для класса “ProductViewController”:

Реализуем эти протоколы:

Методы на 58 строке и 69 мы рассматривали уже ранее, не буду повторяться.

На 64 строке мы реализовали метод “textViewDidEndEditing”, данный метод вызывается, когда редактирование многострочного текстового поля было завершено.

Обновим код в методе “viewDidLoad”:

Запустите приложение. Закрытие клавиатуры будет работать только для текстового поля “Название”, для описания работать не будет.

Дело в том что, чтобы скрыть клавиатуру у поля “Text View”, надо добавить дополнительную панель инструментов над клавиатурой и на нее добавить кнопку, которая будет закрывать эту клавиатуру.

Разберем, как это сделать. Обновите код:

Разберем код построчно.

На 37 строке мы вызываем метод “addToolbar”, который добавим ниже. Данный метод принимает аргумент типа “UITextView”, в него мы передаем экземпляр текстового поля, к клавиатуре которого будет привязана панель инструментов с кнопкой закрыть.

На 40 строке мы объявили метод “addToolbar”.

На 41 строке мы создали экземпляр панели инструментов. Чтобы добавить эту панель на клавиатуру, надо проинициализировать свойство “inputAccessoryView” созданной панелью инструментов.

С 42 по 44 строку мы задаем визуальные стили панели инструментов.

На 45 строке мы создаем экземпляр кнопки пробел.

На 46 строке мы создаем экземпляр кнопки “Х Закрыть” и привязываем к нему метод обработчик “donePressed” на нажатие по кнопке.

На 47 строке мы добавляем кнопки на панель инструментов.

На 48 строке говорим, что панель инструментов будет принимать действия пользователя.

На 49 строке мы вызываем метод “sizeToFit”, который растянет панель инструментов по ширине экрана.

На 51 строке инициализируем свойство “delegate” текстового поля.

На 52 строке добавляем панель инструментов на клавиатуру.

Запустите приложение.

Теперь, при нажатии на кнопку “Х Закрыть” на панели инструментов клавиатуры, клавиатура закрывается. Данный код еще удобно использовать для цифровых клавиатур.

Добавим поле поиска товаров в представление списка товаров. Откройте модуль “SuppliesViewController.swift”.

Добавьте наследование от протоколов “UISearchResultsUpdating” и “UISearchBarDelegate”. Обновите код:

Разберем код.

На 27 строке мы добавили свойство “filteredSupplies”, в котором будут содержаться найденные товары через поле поиска.

На 28 строке мы добавили свойство, которое указывает, активно ли сейчас поле поиска или нет.

На 29 строке мы объявили пока еще не инициализированный экземпляр контроллера для поля поиска типа “UISearchController”.

Отлично, теперь обновим методы табличного представления “numberOfRowsInSection” и “cellForRowAt indexPath”:

Разберем код.

На 74 строке мы проверяем, является ли поле поиска в данный момент активным (т.е. мы в данный момент поставили в него курсор).

Тогда на 75 строке мы возвращаем количество товаров из отфильтрованной коллекции.

Иначе на 78 строке мы возвращаем исходный список товаров.

На 84 строке мы изменили получение модели товара. Теперь мы проверяем: если поле поиска в данный момент активно, то возвращаем товар из отфильтрованной коллекции, иначе возвращаем товар из исходной коллекции.

Ошибки с индексом за пределами коллекции у нас не будет, так как выше мы обновили реализацию метода “numberOfRowsInSection”.

Теперь необходимо добавить метод, который будет инициализировать контроллер для поля поиска:

Разберем код этого метода.

На 131 строке мы инициализируем свойство “searchController”, которое объявляли ранее.

На 132 строке мы указываем ссылку на представление, где находятся данные, которые мы будет фильтровать.

На 133 строке мы указываем, доступен ли нам основной контент в ходе поиска данных.

На 134 строке мы задаем текст, который будет отображаться в поле поиска.

На 135 строке мы инициализируем свойство “delegate” поля поиска, тем самым говоря, откуда ему брать реализацию связанных с ним протоколов. Мы указали, что реализация находится в контроллере “SuppliesViewController”.

На 136 строке мы вызываем метод “sizeToFit” на поле поиска, чтобы растянуть панель поиска по ширине экрана.

На 137 строке левым операндом мы обращаемся к свойству “tableHeaderView” экземпляра таблицы и правым операндом инициализируем его нашим полем поиска. Тем самым мы добавляем в заголовок нашей таблицы поле поиска.

Наше приложение на русском языке. А когда поле поиска становится активным, мы видим справа от него кнопку с текстом на английском языке “Cancel”, давайте сразу это исправим, чтобы потом не возращаться к этому:

Разберем построчно код.

На 141 строке мы обращаемся к свойству “searchController”, от него вызываем свойство “searchBar” - это наше поле поиска. И на экземпляре поле поиска вызываем свойство “showsCancelButton”, говорящее о том, отображать кнопку “Cancel” справа от поля поиска или не отображать. Мы говорим, что будем отображать.

На 142 строке мы объявляем переменную типа “UIButton” с именем “cancelButton”.

На 143 строке мы получаем представление, в котором будем производить ниже поиск кнопки с текстом “Cancel” по типу разумеется :)

На 144 строке мы проходимся по иерархии вложенных представлений в поле поиска.

На 145 строке мы проверяем: если представление имеет тип “UINavigationButton”, то это то представление, которое нам надо, это и есть наша кнопка с текстом “Cancel”.

На 146 строке мы инициализируем переменную “cancelButton” экземпляром найденной кнопки.

На 147 строке мы задаем текст кнопки “Отмена”.

Реализуем протокол “UISearchResultsUpdating”:

Разберем код.

На 154 строке мы вызываем метод “searchDisplayControllerWillBeganSearch”, который ранее рассматривали уже, и передаем в аргумент “controller” экземпляр контроллера поиска, который у нас есть в аргументе метода “updateSearchResults”.

На 155 строке мы проверяем, ввел ли пользователь какой -либо  текст в поле поиска, если ввел, тогда сохраняем этот текст в переменную “searchString”, если не ввел, тогда выходим из метода “updateSearchResults”.

На 159 строке мы выполняем фильтрацию данных из основного источника данных по тексту, который ввел пользователь в поле поиска. Для этого у коллекции “supplies” вызываем метод “Filter”, в который передаем лямбда метод с одним аргументом типа “ProductModel”, и возвращаемым значением типа Bool (найден или не найден товар).

На 160 строке мы создаем переменную с именем “product” типа “ProductModel” и инициализируем ее экземпляром аргумента “productItem”. Заметьте, лямбда метод будет вызываться столько раз, сколько элементов товара содержит коллекция “supplies”.

На 161 строке мы объявляем переменную, в которой будет содержаться результат сравнения текста поиска с названием или описанием нашего товара.

На 162 строке мы выполняем сравнение текста текущего товара в лямбда методе с текстом поля поиска . Оба текста путем вызова метода “lowercased” переведены в нижний регистр и теперь регистро независимы. Если по названию товара совпадений не было найдено, пытаемся сравнить по описанию товара. Результат сравнения записываем в переменную результата “res”.

На 164 строке возвращаем результат метода “filter”.

На 166 строке запускаем переинициализацию таблицы для отображения отфильтрованных данных и скрытия данных, не попавших под фильтр.

Реализуем протокол “UISearchBarDelegate”:

Разберем код.

На 170 строке мы реализовали метод “searchBarTextDidBeginEditing”, который вызывается, когда пользователь начинает вводить текст в поле поиска. В реализации данного метода мы задаем свойство “shouldShowSearchResults” в значение “true”, тем самым давая понять контроллеру поиска, что поле поиска сейчас активно. Затем мы переинициализируем таблицу.

На 175 строке мы реализовали метод “searchBarCancelButtonClicked”, который вызывается, когда пользователь нажал кнопку “Cancel” или в нашем случае “Отмена”, справа от поля поиска. В реализации мы говорим, что поле поиска теперь больше не активно и переинициализируем таблицу.

На 180 строке мы реализовали метод “searchBarSearchButtonClicked”, который вызывается, когда на клавиатуре, отобразившейся к полю поиска, мы нажали кнопку “Search” (“Поиск”).

В реализации метода мы проверяем: если свойство “shouldShowSearchResults” еще не активно, активируем его и переинициализируем таблицу. Затем скрываем клавиатуру для поля поиска на 185 строке.

Обновите метод “viewDidLoad”:

На 64 строке мы добавили заголовок представления “Продукты”.

На 66 строке мы вызвали метод, который выполняет инициализацию контроллера поиска и добавляет его в наше представление.

Запустите приложение.

Нажмите на поле “Поиск товара”, введите туда, например, букву “Ш”.

Все работает :)

Теперь в этом уроке нам еще осталось добавить предварительный просмотр товара при выполнении на нем функции 3D Touch. Данная функция поддерживается только на устройствах iPhone 6s / 6s Plus / 7 / 7 Plus. В этих телефонах установлен специальный дисплей, который реагирует на силу нажатия на него. Даже если у вас нет подобного девайса это не проблема, так как данную функциональность можно проверить в симуляторе.

Реализуем протокол “UIViewControllerPreviewingDelegate”. Обновите код “SuppliesViewController”:

Теперь обновите метод “viewDidLoad”:

На 67 строке мы обращаемся к свойству контроллера “traitCollection”, в котором содержится свойство “forceTouchCapability”, и проверяем: если данное устройство поддерживает данную функцию (3D Touch), тогда вызываем метод “registerForPreviewing”, в который первым аргументом передаем ссылку на контроллер, для которого надо применить данную функциональность, и экземпляр таблицы, на содержимом которой эта функциональность и будет выполняться.

Добавим реализацию протокола “UIViewControllerPreviewingDelegate”:

Разберем код.

На 192 строке мы реализовали метод “previewingContext”, который возвращает экземпляр представления , которое надо отобразить в предварительном просмотре. Метод принимает два аргумента.

Первый аргумент “previewContext” типа “UIViewControllerPreviewing” принимает экземпляр контроллера предварительного просмотра.

Второй аргумент “location” типа “CGPoint” содержит позицию места, где пользователь выполнил усиленное нажатие по ячейке таблицы.

На 193 строке мы получаем экземпляр “indexPath” путем вызова на таблице метода “indexPathForRow”, аргументом которого мы передаем аргумент “location”.

Данный экземпляр нам необходим, поскольку у него имеется свойство “row” и по значению этого свойства мы сможем получить нужную модель товара.

На 194 строке мы производим поиск контроллера ”ProductViewController” по его “Storyboard ID”. Это представление редактирования товара.

На 195 строке мы передаем идентификатор товара в свойство “id” найденного выше контроллера.

На 196 строке мы передаем в свойство “sourceRect” полную область ячейки, по которой было выполнено “3D Touch”. Благодаря этому данная область будет выделена, когда вы выполните нажатие “3D Touch” в таблице.

На 197 строке возвращаем найденный контроллер “ProductViewController”.

На 199 строке возвращается пустое значение, если пользователь выполнил нажатие “3D Touch” вне области таблицы.

На 202 строке мы реализовали метод “previewingContext” перегруженный, который ничего не возвращает и отображает представление того контроллера, который мы вернули в методе выше.

Запустите приложение.

На этом завершим урок.

На следующем уроке мы рассмотрим создание иконки нашего приложения и разберемся, как пользоваться “Assets”.

СТАТЬИ ПО СХОЖЕЙ ТЕМАТИКЕ
ВИДЕО КУРСЫ ПО СХОЖЕЙ ТЕМАТИКЕ

КОМЕНТАРИИ И ОБСУЖДЕНИЯ

ОЦЕНИТЕ ДАННЫЙ МАТЕРИАЛ

ПОДПИСКА НА ITVDN ВЫГОДА ДО 29.95$ НА ОБУЧЕНИЕ ПРЕСТИЖНЫМ ПРОФЕССИЯМ!

1 месяц19.99$
подписка

легкий старт в обучении

3 месяца49.99$
подписка

выгода от подписки до9.98$

6 месяцев89.99$
подписка

выгода от подписки до29.95$