Загрузил --

Swift З. Разработка приложений в среде Xcode для iPhone и iPad с использованием iOS SDK. Молли Маскри

реклама
www.dialektika.com
www.apress.com
Swift З
Разработка приложений
в среде Xcode для iPhone и iPad
с использованием iOS SDK
Beginning iPhone
Development with Swift 3
Exploring the iOS SDK
Third Edition
Molly Maskrey
Кim Topley
David Mark
Fredrik Olsson
Jeff Lamarche
лpress�
Swift З
Разработка приложений
в среде Xcode для iPhone и iPad
с использованием iOS SDK
Третье издание
Молли Маскри
Ким Топли
Дэвид Марк
Фредрик Олссон
Джефф Ламарш
Москва •Санкт-Петербург• Киев
2017
J:)J:)K 32.973.26-018.2.75
М31
УДК 68 l .3.D7
Компьютерное издательство "'Л.иалектика··
Зав. редакнией С. 11. Тригуб
Перевод с английског о и редакния докт. фю.-ма�� наук ДА.
Клюшшю
По общим вопросам обращайтесь в издательство "Диалектика" 110 адресу:
[email protected], http://www.dialektika.com
Маскри. Молли. Топли, Ким. Марк. Дэвид. и др.
М31
Swift 3: разработка приложений в среде Xcode для iPhone и iPad с использованием IOS SDK.
3-е изд.: Пер. с англ. - СпБ.: ООО ''Альфа-книга'', 2017. - 896 с. : ил. - Парал. тит. англ.
ISBN 978-5-9908910-2-9 (рус.)
ББК 32.973.26-018.2.75
Вес н�пвания программных продуктов являются зарегистрированными торrпnыми марками со1Jгnстству­
ющих фирм.
Никакая часть настоящего юдания ни в каких uслях 11с может быть восПJХ1И'!ВСдс11а в каю:111 бы ·го ни было
форме и какими бы то ни было средствами. будь то ·mсктронныс ит1 механические, включая фотокшrироваrrие
и запись на маr·нитный носитель. если на это нет nисьмсннот разрешения юдагсльства ЛPress. Г!crkclcy. СА.
Authorized traпslation from the English laпguage edition puЫished Ьу APress, Copyright со 2016 Molly Maskrey.
Kim Topley. David Mark. Fredrik Olssoп and JefT Lamarche.
All rights reserved. No parl о!' this work may Ье reproduced ог transmitted in any l'orm ог Ьу any means.
electronic ог mechanical, including photocopying. recordiпg. ог Ьу any i11Гormatio11 storagc ог rclrieval systcm.
witlюut tl1e prior written permission of the copyright owner and the pt1Ыishcr.
Russian laпguage edition is pt1Ьlished Ьу Dialektika Computcr Books PuЬlishing according to the Лgreemcnt
with R&I Enterprises lnternatioпal. Copyright �) 2017.
Научно-популяртюе издаиие
Молли Маскри, Ким Топли, Дэвид Марк, и др.
Swift 3: разработка приложений в среде
Xcode для iPhone и iPad с использованием iOS SDK
3-е издание
Литературный редактор
В ер стка
Художественный редактор
Корректор
Л.Н. Kpac110.Jl('(J/I
.17.В. 1/ер11окози11ская
В.Г Павлюти11
.!1.А. /ордие11ко
Подписано в печагь 22.03.2017. Формат 70х 100/1 б.
Гарнитура Timcs.
Усл. печ. л. 72.24. У ч.-И'll\. л. 50.б.
Тираж 500 ·ж3. Зака3 № 2095.
Отпечатано в АО «Первая Образцовая типография»
Филиал «Чеховский Печатный Двор»
142300, Московская область, г. Чехов, ул. Полиграфистов, д.1
Сайт: www.chpd.ru, E-mail: [email protected], тел. 8(499)270-73-59
ООО "'Альфа-книr·а". 195027. Санкт-Пстсрбурr� Маrнито1uрская ул" д. 30
ISIЗN 978-5-9908910-2-9 (рус.)
ISBN 978-1-4842-2222-5 (анrл.)
СО Комrrьютерное и1даrельство "J!иалсктика". 2017.
rrсрс вод . оформление. макстироnаrrие
СО 2017 Molly Maskrcy, Kim Toplcy. David Mark.
1:redrik Olsson and JctT l.aniarchc
Огл а вл е н и е
Об авторе
17
Благодарности
19
Глава 1. Знакомство с системой iOS
21
Глава 2. Первое приложение
37
Глава 3. Основы взаимодействия
77
Глава 4. Новые упражнения с интерфейсом
117
Глава 5. Вращение устройства
167
Глава 6. Приложения с несколькими представлениями
215
Глава 7. Панели вкладок и селекторы
247
Глава 8. Введение в табличные представления
293
Глава 9. Контроллеры навигации и табличные представления
347
Глава 1О. Представление коллекции
387
Глава 11. Разделенные представления и всплывающие меню
401
Глава 12. Настройки приложений и пользовательские настройки по умолчанию
431
Глава 13. Основы долговременного хранения данных
475
Глава 14. Документы и служба iCloud
529
Глава 15. Многопотоковое программирование
с помощью технологии Grand Central Dispatch
567
Глава 16. Графика и рисование
607
Глава 17. Введение в каркас Sprite Kit
635
Глава 18. Нажатия, касания и жесты
681
Глава,19. Определение местоположения
713
Глава 20. Распознавание ориентации и перемещения устройства
739
Глава 21. Камера и фотоархив
767
Глава 22. Локализация приложений
783
Приложение. Введение в язык Swift
815
Предметный указатель
885
Сод е р ж а н и е
Об авторе
17
О тех ническом редакторе
18
Благодарности
19
Глава 1. Знакомство с системой iOS
21
О книге
Что вам требуется
Возможности разработч и ка
Что необходимо знать
Отл и ч ител ьные особе нности програм м ирован ия для систем ы iOS
Тол ько одно активное приложен ие (как правило)
Тол ько одно окно
Огран иченный дос�уп с цел ью обеспечения безопасности
Приложение должно быстро реагировать на действия пол ьзователя
О граниче н н ы й размер экрана
О граниченные ресурсы с истемы
Ун и кал ьные возможности устройств iOS
Ввод и вы вод информации
Содержание к н и ги
Что нового в данном издании
Версии язы ка Swift и каркаса Xcode
Нач нем
22
22
25
27
27
28
28
29
29
29
31
32
32
32
35
35
35
Глава 2. Первое приложение
37
38
41
53
54
55
56
58
60
63
65
69
72
76
Проект Hello World
Окно прое кта в среде Xcode
Прис�у п и м к проек�у He llo World
Введен ие в программу l nterface B u i lder
Форматы файлов
Рас кадровка
Вспомогательная область
Добавление метки на представление
Изменение атрибутов
Завершающие штрихи
'Экран запуска приложения
Запус к приложен ия на устройстве
Резюме
Глава З. Основы взаимодействия
Парадигма "модел ь-контроллер-представление"
Создание прил оже н ия ButtonFun
77
77
79
СОДЕРЖА Н И Е
7
Создание контроллера представления
Выходы и действия
Выходы
Действия
Разработка контроллера представления
Разработка пол ьзовател ьского и нтерфейса
Добавление кнопок и метода действия
Добавление метк и и выхода
Создание метода действия
Тестирован ие приложения B uttoп Fun
Решение проблем с помощью механ изма A uto Layout
Предварител ьный просмотр макета
Изменение стиля текста
Ис пол ьзован ие делегата приложен ия
Резюме
80
81
82
83
84
85
86
91
94
95
96
108
110
111
115
Глава 4. Новые упражнения с интерфейсом
117
Активные, статические и пассивные элементы у правления
Создание приложения Control Fun
Реал изация графического представления и полей редактирован ия
Добавление графического представления
Изменение размеров графического представления
Настройка атрибутов представления
Добавление полей редактирования
Добавление огран ичений
Создание и присоединение вы ходов
Закрытие клавиатуры
Закрытие клавиатуры при нажатии кнопки Done
Закрытие клавиатуры прикосновением к фону
Добавление ползун ка и метки
Создание и связы вание действи й и выходов
Реал изация метода действия
Реал изация перекл ючателей, кнопки сегментирован ного элемента у правления
Добавление переключател ей с меткам и
Связы вание и создание выходов перекл ючателя и действи й
Реал изация действи й перекл ючателя
Добавление изображения на кнопку
Растя гивающиеся изображе ния
Состоя ния элемента у правления
Связы вание в ы ходов и действи й кнопки
Реал изация действия сегментированного элемента у правления
Реал и�ация списка действ и й и с и гнала
Демонстрация списка действ и й
Вы вод преду преждения
Р�юме
120
122
123
123
125
127
132
138
140
142
143
144
146
148
148
150
151
152
152
154
155
156
157
158
159
160
163
165
Глава 5. Вращение устройства
167
Механ изм автоматического поворота
Точ ки, п и ксел и и дисплей Retina
С пособы реал изации автоматическо го вращения
168
169
170
8
С ОДЕ РЖАН И Е
Выбор ориентаци и представле ния
Поддержка ориентации на уровне приложения
Настройка поддержки поворота
Создание макета проекта
Переопределение о гран ичен и й, заданных по умолчанию
Кнопки, занимающие всю ш ирину представления
Создание адаптивных макетов
Создание приложения Restructure
Н астрой ка конфи гураци и i Phone в ал ьбом ной ориентации (wC hC)
Настрой ка конфигурации i Pad (i Phone Plus в ал ьбом ной ориентаци и (wR h R))
Резюме
170
171
173
175
180
181
184
184
193
202
213
Глава 6. Приложения с несколькими представлениями
Основные типы приложен и й с несколькими представл е ния м и
Архитектура приложения с нескол ьки м и представлениям и
Корневой контроллер
Устройство представления содержимого
Создание переключателя представлений
Переименование контроллера представлен ия
Добавление контроллеров представле н ия содержимого
Модиф и кация файла Switch ingViewCoпtroller.swift
Создание представления с панел ью инструментов
Связыван ие кнопки панел и инструментов с контроллером представления
Создание корневого контроллера представления
Реал изация представлен и й содержимого
А н имация перехода
Резюме
215
215
221
223
223
224
224
226
227
228
231
232
238
242
245
Глава 7. Панели вкладок и селекторы
247
Приложение Pickers
Делегаты и источ н и к и данных
Создание приложе н ия Pickers
Создание контроллеров представле н и й
Создание контроллера представления панел и вкладок
Первич ный тест на симуляторе
Реал изация сел е ктора даты
Реал изация одноком понентного селектора
Создание представления
Реал изация контроллера как источ н и ка дан н ы х и делегата
Реал изация м ногоком понентного селектора
Создание представления
Реал изация контроллера
Реализация зависимых ком поне нтов
Создан ие простой и гры с пол ьзовательским селектором
Подготовка контроллера представления
Создание представления
Реализация ко нтроллера
Последн ие штрихи
Резюме
248
251
252
252
254
25 8
260
264
264
268
271
272
272
275
283
283
283
284
288
292
СОДЕ РЖА Н И Е
Глава 8. Введение в табличные представления
Основы табл и ч н ы х представлений
Табличные представления и ячейки табл ич ного представления
С гру п п ированные и простые табл ицы
Реал изация простой табл и цы
П роектирован ие представления
Реал изация контроллера
Добавление изображения
Испол ьзование стилей ячеек табл и ч н ы х представлений
Настрой ка уровня отступа
Обработка выбора строки
Изменение размера шрифта и в ысоты строки
Настрой ка ячеек табл и ч ного представления
Добавление дочерних представлен и й к ячейкам табл и ч ного представления
Реал изация приложения с пользовател ьс к и м и табл и ч н ы м и представл е н ия м и
Создание подкласса UITaЬ\eViewCe l l
Загрузка объекта класса U I ТaЬ\eY iewCel l из ХIВ-файла
Проектирование ячейки табл и ч ного представления
с помощью програм м ы lnterface Bui lder
Испол ьзование новой ячейки табл и ч ного представления
Групп ированные и и ндексированные раздел ы
Создание представления
Импортирование дан н ы х
Реал изация контроллера
Добавление и ндекса
Реал изация строки поиска
Отладка представления
Резюме
9
293
293
293
295
296
297
299
303
305
308
3 1О
3 12
3 14
3 14
3 14
3 15
32 1
322
328
328
328
3 29
33 1
334
334
343
346
Глава 9. Контроллеры навигации и табличные представления
347
Основы контроллеров навигации
Стеки
Стек контроллеров
Font
простой браузер шрифтов
Подконтроллеры приложения Fonts
Основа приложения для работы с шрифтам и
Создание контроллера корневого представления
Н ачал ьная настрой ка раскадровки
Перв ы й подконтроллер: представление сп иска шрифтов
Раскадровка сп иска шрифтов
Создание контроллера представления размеров шрифтов
Создание рас кадровки контроллера представления размеров шрифтов
Подготовка контроллера представления сп иска шрифтов к переходам
Создание контроллера представления информации о шрифте
Рас кадровка контроллера представления и нформации о шрифте
Адаптация контроллера представления списка шрифтов для нескол ьких переходов
П редпоч итаемые шрифты
Тон кости табл и ч ного представления
Реал изация жеста удаления
Реал изация переу порядочения перетаскиванием
Резюме
348
348
349
350
352
354
359
363
364
367
370
372
372
373
375
3 79
3 80
3 80
3 81
383
3 85
-
10
СОДЕРЖА Н И Е
Создание проекта DialogViewer
О пределение пол ьзовател ьских ячеек
Н астройка контроллера представления
Предоставление содержимого ячеек
Создание потока
Представления заголовка
Резюме
3 87
388
3 89
393
394
395
397
З99
Глава 1О. Представление коллекции
Глава 11 Разделенные представления и всплывающие меню
401
Построение приложения master-detail с помощью класса UJSpl itViewController
Определение структуры с помощью раскадровки
Определение фун к ционал ьной возможности в коде
Контроллер главного представления
Как работает приложен ие m aster-detai l
Добавление данн ы х о президентах
Создание пользовател ьского всплы вающего меню
Резюме
403
406
408
41О
412
415
421
429
Глава 12. Настройки приложений и пользовательские настройки по умолчанию
431
431
43 3
436
437
454
45 8
.
Знакомство с пакетом настроек
Приложение Bridge Control
Создание проекта Bridge Control
Подготовка пакета настроек
Добавлен ие п и ктограмм в пакет настроек
Чтение настроек из приложения
Изменение пользовател ьских настроек по умолчанию
непосредственно из прил ожения
Регистрация значений по умолчанию
Суровая действител ьность
Переключение в приложение Settings
Резюме
Глава 1З. Основы долговременного хранения данных
"Песоч н и ца" приложения
Определение местоположен ия каталогов Documents и Library
Определение местоположен и я каталога tmp
Стратегии сохранения файлов
Дол говременное хранение одного файла
Долговремен ное хранение нескол ьких файлов
Испол ьзование списков свойств
Сериал изация списка свойств
Первая версия приложе н ия Persistence
Архи вирование объектов моделей
Поддержка протокола NSCoding
Реализация протокола NSCopy ing
Архивирование и разарх ивирование объектов дан н ы х
Приложение Arch iving
Использование встроен ной в iOS базы дан н ы х SQL ite3
Создание ил и открытие базы дан н ы х
Испол ьзование связан ных переменных
463
467
468
471
473
475
476
479
481
481
482
482
483
483
485
491
491
493
494
494
498
499
500
СОДЕРЖАН И Е
11
Приложение SQLiTE3
Исnолыование каркаса Core Oata
Приложение Core Oata
Модификация файла App Oelegate.swift
Резюме
502
508
514
519
527
Глава 14. Документы и служба iCloud
529
530
531
532
535
543
546
551
555
556
559
562
562
566
Уnравление хран ил и щем документов с nомощью класса UIDocument
Создание nриложения TinyPix
Создание класса TinyPix Oocument
Основной код
Начальная раскадров ка
Создание класса TinyPixView
Раскадровка детал изирован ного представления
Добавление поддержки службы iCloud
Создание профиля ресурсов
Как послать заnрос
Местоnоложен ие файлов
Сохранение настроек в службе iC loud
Резюме
Глава 15. Многопотоковое программирование
с помощью технологии Grand Central Dispatch
567
Создание nриложения SLOW WORK E R
Ос новы м ногоnотоковой работы
Еди н и цы работы
Орган изация очередей на низком уровне средствам и G C O
Усовершенствован ие nриложе ния S low Worker
Фоновая работа
Жизне н н ы й цикл nриложения
Уведомления о смене состоя ния
Создание nриложения State Lab
Исследование состоя н и й выnолнения
Практи ческое nрименение смены состоя н и й выnол нения
Обработка неактивного состоя ния
Обработка фонового состоян и я
Резюме
568
572
573
574
575
581
582
584
586
587
589
591
596
605
Глава 16. Графика и рисование
607
Библ иотека QUA RTZ 20
Подход к рисованию в библиотеке Quartz 20
Графические контексты Quartz 20
С11стема координат
Задан ие цветов
Рисование изображен и й в графическом контексте
Рисование форм: пря моу гол ь н и ков, nрям ы х и кривых л и н и й
Образцы и нструментал ьных средств Quartz 20: узоры, градиенты и пунктиры
Приложе н ие QuartzFun
Создание приложения QuartzFun
Ввод кода рисования из библиотеки Quartz 20
Оnтим изация nриложения QuartzFun
Резюме
607
608
608
61 О
612
614
615
615
616
616
625
631
634
12
СОДЕРЖА Н И Е
Глава 17. Введение в каркас Sprite Кit
Создан ие прил ожения Textshooter
П ервоначал ьная настройка сцены
Движение и грока
Создание противни ков
Размещение противников на с цене
Начало стрел ьбы
Атака на противн и ков с соблюдением законов физ и к и
Завершение игры на разны х уровнях
Н астрой ка стол кнове н и й
Придание и гре остроты с помощью части ц
Размещение частиц на сцене
Завершение игры
Создание начал ьной сце н ы
Добавление звуковы х эффектов
Усложнение игры с помощью силовых полей
Резюме
63 5
636
641
645
651
652
653
659
660
662
666
669
672
673
676
677
680
Глава 18. Нажатия, касания и жесты
681
Мул ьтисенсорная терм и нология
Цепочка реагирующих элементов
Реакция на события
Передача события по цепоч ке реагирующих элементов,
поддержи ваемой в актив ном состоя н и и
Мул ьтисенсорная архитектура
Четыре метода у ведомления о касан иях
Создание приложения TouchExplorer
Создание приложения Swipes
Обнаружен ие с кол ьжения с помощью событий касания
Автоматическое рас познавание жестов
Распознавание с кол ьжения нескол ь к и м и пал ь цами по экрану
Рас познавание м ногократных нажатий экрана
Рас познаван ие щипков и вращения
Резюме
682
683
683
Глава 19. Определение местоположения
713
Диспетчер местоположения
Задание требуемой точ ности
Установка фил ьтра расстоя ния
П олучение разрешения н а пользование службами о пределения местоположен ия
Запуск диспетчера местоположения
Благоразум ное использование диспетчера местоположения
Делегат диспетчера местоположения
Обновление координат
О пределение ш и роты и дол готы средствам и класса CC Location
Уведомления об ошибках
Создание приложения WhereAm l
Ис пол ьзование новы х координат в дис петчере местоположения
Отображен ие движе н ия на карте
Изменение разрешений на пол ьзование службам и определения местоположен ия
Резюме
714
714
715
716
716
716
717
717
717
720
720
727
730
734
73 6
685
686
687
688
693
694
697
699
701
707
710
СОДЕ РЖАН И Е
13
Глава 20. Распознавание ориентации и перемещения устройства
739
Физические основы работы акселерометра
Распознаван ие вращения с помощью гироскопа
Каркас Core Motion и диспетчер движения
Создание приложен ия M otion Mon itor
Упреждающий досту п к дан н ы м движения
Результаты ги рос копических и п ространствен н ы х измере н и й
Результаты акселерометрических измере н и й
Распознавание сотрясений
Встроенные средства обнаружения сотрясений
Сотрясение на грани полом к и
Акселерометр в качестве контроллера направл е н ия
Катание шаров
Построение представлен ия для шари ка
Расчет движения шарика
Резюме
739
741
741
742
748
750
751
752
754
754
757
758
760
763
766
Глава 21. Камера и фотоархив
767
Применение селектора изображен и й и класса U l l M A G E I CKERCONТROLLER
Применение контроллера селектора изображен и й
Реализация делегата для контроллера селектора изображен и й
Разработка пользовательс кого и нтерфейса приложения
Функции защиты конфиден циал ьности
Реализация контроллера представления камеры
Резюме
768
768
770
773
775
776
781
Глава 22. Локализация приложений
783
Арх итектура локал изации
Файлы символьных строк
Содержимое файла с и м вольн ы х строк
Фун кция для локал изации с и м вольных строк
Реал изация приложения LocalizeMe
Локал изация проекта
Локал изация рас кадровки
Локализация отображаемого назван ия приложен ия
Добавление еще одной локал изации
Резюме
Резюме книги
784
785
786
787
788
795
798
809
812
813
813
Приложение. Введение в язык Swift
815
Основы язы ка Swift
Игровые площадки, ком ментарии, переменные и константы
Предопределенные типы, о перации и у правляющие операторы
Масс ивы, диапазоны и словари
Необязательные ти п ы дан н ы х
Управляющие операторы
Функции и зам ы кания
Обработка ош ибок
Классы и стру ктуры
Стру ктуры
��ы
815
816
821
834
841
848
854
861
867
868
�
14
СОДЕРЖА Н И Е
Свойства
Методы
Связывание необязател ьных типов в цепоч ку
Создание производных классов и наследование
Протокол ы
Расш ирения
Резюме
872
874
875
877
881
883
884
Предметный указатель
'885
Я 11евероят110 счаспшива получить воз.можность 11аписать иовы й
вариант этой кни<'и. Иwетю ее первое издание вдохиовwю меня
приступить к програм.мироваиию для системы iOS. В связи
с этим я хотела бы выразить благодарность людю\.1, сыгравшил1
особую роль в моей жизии и во миогом придавш�ш ей смысл.
Я благодарю Ча11у, которая была рядом со мной 95% времеии
и постояиио вдохиовляла меня, особенио тогда, когда .wне
казаrюсь, что я уже больше не могу. Из обычиой коллеги
по работе 011а превратилась в мою ближайшую подругу. Каждый
день, проведеииый вместе с ней, я считаю большим подарком.
Я всегда готова прийти к ней тю помощь, где бы оиа ии была.
Последиие два <-.ода моей лучшей подругой была Джессика (Галди).
Оиа стояла рядом со м11ой как подружка иевесты, и с тех пор мы
иеразлучиы. Мы пили вместе, ттщевш�и вместе, вместе являлись
иа вечериики без приглаше11ия и вместе плакали ... О11а 11е делает
мие поблажек, желая мие добра. Во время ее семииедельиого
путешествия по Южиой Америке мы общаr1ись с ией практически
каждый день. И несмотря на то что 11ас разделю� континент,
эти разговоры сближш�и 11ас.
Эш11и, я обещала тебя упомя11уть и я это делаю. Эш связана
со мной совсем 11е так, как остальные друзья. Мы обе - технари
и часто сидиw у 11ее на кухне, попивая виио и рассуж·дая о
.wодериизации компьютеров. Она умиа, красива, добра и одиа
из са111 ы х веселых людей, которых я знаю.
Накоиец я посвящаю ютгу своей спутнице жизии Дженнифер.
Оиа - моя бизиес-партиер, босс, ииогда мы танцуем вместе.
Оиа всегда рядом, когда я засыпаю и когда просыпаюсь.
О11а прочла и одобрwш каждое слово в этой книге.
Мои друзья поддерживш1и меия иа протяжении послед11их
трудных .wесяцев. Работа иад киигой - дело уединенное,
и поддержка таких красивых, восхитительных женщин ста11а
еди11ствениым зшюгом моего успеха. Одии старый дру<-. сказш� .111не
иесколько месяцев иазад, что ииогда дружба длится не больше
одио,-.о года. Я молюсь, чтобы эти жеищииы были моlL'11 и
подруга.ми на всю жизиь.
М М , Сентябрь 20 1 6
----)
О б а вт о ре
Молли Маскри (Molly Maskrey) работала и н­
женером-электри ком в разных аэрокосмических
ком пан иях, в том ч исле в I В М Federal Systems,
TRW (в настоящее время - Northrup G rumman),
Loral Systems, Lockheed Martin и Boeing. С вобод­
но ориентируясь в первом буме доткомов, она
поняла, что пузырь скоро лопнет, и на нескол ько
лет изменила вид деятел ьности - переехала на
остров Мауи и стала уч иться в индсерфингу на
прекрасном пляже Kanaha Beach Park . Однако
Молли н и когда дол го не с идит на одном месте,
поэтому вскоре она переехала в Денвер, штат Колорадо, и открыла несколь ко
компаний вместе со с воей подругой и партнером Джен н ифер, в частности ком­
панию G lobal Tek Labs, которая зан и мается разработкой программ и проектиро­
ванием вспомогательных служб для систе м ы iOS, которая стала одной из сам ых
успешных консалти нговых ком паний, ориентирующихся на новых разработчи­
ков, желающих создавать хорошие п рограм м ы для устройств ком пан и и Apple.
В том же году Молли о публ и ковала первую к н и гу в издател ьстве A press.
В ней оп исы валось, как создать утил иты для операционной с исте м ы iOS; до
сих пор она остается одной из лучш и х книг на эту тему.
В 20 1 4 году Молл и и Джен нифер основал и компанию Quantitative Bioanalytics
Laboratories, дочернюю ком панию G l obal Tek, чтобы в недрить технологию мо­
бил ьных сенсоров высокого разрешения в медицину для разработки приборов,
контрол ирующих равновесие и предотвращающих паде н ие л юдей п реклон но­
го возраста, устройств, оцен и вающих спорти вные упражнения, и приборов для
инструментал ьного анал иза походки ( instrumented gait analysis - IGA).
Недавно Молл и орган изовала п рограм му Galvan ize Data Science l m mersive
в Ден вере, в рам ках которой проводит обучение язы кам Python, SQL и R, учит
создавать веб-агрегаторы дан н ых, проводить анализ больших объемов дан н ых,
байесрвский анализ и создавать м ногие другие полезные вещи, в частности масштабируемую анал итическую платформу реального времен и для Интернета
вещей ( l nternet of Th ings).
Молл и живет в городе Паркер, штат Колорадо, вместе с Дже н нифер и двумя
лабрадорами.
18
ОБ АВТО Р Е
О техни ч ес ком р еда кт оре
Брюс Уэйд ( B ruce Wade)
разработч и к програм м ного обеспечения из
Британской Колумбии, Канада. Он разрабаты вает програм м ное обеспечение с
1 6 лет, когда создал первы й веб-сайт. Он изучал ком пьютерные информацион­
ные системы в Технологическом институте Деври (OeVry Institute of Technology)
в Кал гари, а затем совершенствовал свои знан ия в области програм м ирования
ком п ь ютерных и гр и визуал ьного програм м и рован ия в И нституте искусств в
Ван кувере (The Art l11stitute of Vancouver). Он работал как в крупных корпораци­
ях, так и в нач и нающих ком паниях. П риобретая опыт разработки программ ного
обеспечения, Брюс ос воил разные языки, вкл ючая С/С++, Python, Objective-C,
Sw ift, Postgres и JavaScript. В 20 1 2 году он основал ком пан и ю Warply Oesigned,
зан имающуюся разработкой мобил ьных приложений 2 0/3 0 для систем OS Х .
Когда Брюс н е генерирует новые идеи, он л юбит кататься на велосипеде со
своей собакой-боксером Rasco, зан иматься спортом и путешествовать.
-
Ждем ваших о т з ы вов !
В ы , ч итател ь этой книги, и есть главн ы й ее крити к. М ы цен и м ваше м не­
ние и хотим знать, что было сделано нам и правил ьно, что можно было сделать
лучше и что еще вы хотел и бы увидеть изданн ы м нам и . Нам и нтересны любые
ваши замечания в наш адрес.
М ы ждем ваш их ком ментариев и надеемся на них. Вы можете прислать нам
бумажное ил и электронное п исьмо л ибо п росто посетить наш веб-сайт и ос­
тавить свои замечания там . Одн и м словом, любым удобн ы м для вас способом
дайте нам знать, нравится ли вам эта книга, а также выскажите свое мнение о
том , как сделать наши кн и ги более и нтересн ы м и для вас.
Отправляя письмо ил и сообщен ие, не забудьте указать назван ие книги и ее
авторов, а также свой обратн ы й адрес. М ы в н и мател ьно ознаком имся с ваш им
м нением и обязател ьно учтем его при отборе и подготовке к издан и ю новых
книг.
Наши электронные адреса:
i n f o @ d i a l e kt i ka . сот
E-mai l :
http
: / /www . di a l e kt i ka . com
WWW:
Наш и почтовые адреса:
в Росс и и : 1 95027, Санкт-Петербург, Магн итогорская ул . , д. 30, ящик 1 1 6
в Украи не: 03 1 50, Киев, а/я 1 5 2
Б ла г од а р н о с ти
____
J
_/
Прежде всего я хотела бы выразить благодарность всем моим друзья м, ока­
завш и м мне поддержку в ходе работы над к н и го й . С п асибо, Сэм, Бриттани,
Аманда, Кристи, Пайпер, Петер, Майке, Келл и и вся команда Galvan ize-Platte в
Денвере, которую я знаю и л юбл ю !
С пасибо Детскому гос п итал ю в Колорадо (Ch i ldren 's Hospital Colorado) и
Центру анал иза равновесия и движений (Center for Gait a11d Movernent Analysis),
которые был и стол ь л юбезны, что позволили м не участвовать в изучен и и дет­
ского церебрал ьного парал ича и других нару ш е н и й равновесия : эти знания
позволили мне сосредоточить с вои усил ия на оказании помощи тем, кто в ней
действител ьно нуждается .
Благодарю кл иентов и друзей ком пании Global Tek Labs, разре ш и в ш их м не
испол ьзовать некоторые их проекты для иллюстрации. Спасибо сотням л юдей,
посети вшим мои лекции за последние годы и подел и вшимся с во и м и идея м и ,
таким как Джон Хейли (John Haley), рассказавш и й м не обо всех сложностях, с
которы м и он стол кнулся, изучая механизм Auto Layout в среде Xcode . И х реал ь­
ный опыт помог м не уточн ить материал книги .
В закл ючение я хочу вы разить благодарность всем авторам п редыдущих
книг, ставш их основой моей скром ной работы и позвол и в ш и х расширить мой
кругозор.
ГЛ А В А 1
•
З н а ко м с т в о с с и с те м о й iOS
Програм мирован ие мобил ьных устройств Apple не тол ько nриносит разра­
ботчикам морал ьное и материальное удовлетворение от того, что их приложения
изменяют жиз н ь л юдей (рис. 1 . 1 ), но и позволяет найти замечател ьных еди­
ном ышленников. Несмотря на оnределенные трудности, с которы м и вы може­
те стол кнуться nри изучен и и язы ка, инструментов и nроцессов, знакомство с
этими л юдьм и поможет вам ос воиться в новом м ире и nроя вить свои лучшие
качества.
Рис. 1. 1. Как разработч и к п р иложе н и я дл я систе м ы IOS вы см ожете познако­
миться с людьм и , использующи м и п р одукт вашего творчества на п ракти ке
22
ГЛАВА 1
ЗНАКОМСТВО С С И СТ Е МОЙ IOS
Сч итайте меня своим другом, который будет сопровождать вас на пути ос­
воения системы iOS. Я горжусь возможностью ввести вас в мир разработки
приложения для устройств IOS - i Phone, i Pod Touch ил и i Pad . Система IOS
представляет собой перспективную платформу, демонстрирующую бурн ы й рост,
нач иная с ее поя вления в 2007 года. Распространение мобил ьных устройств оз­
начает, что л юди могут испол ьзовать програм м ное обеспечение везде, где они
захотят, с помощью как телефонов, так и других аксессуаров, напри мер Apple
Watch. С появлением системы IOS 1О, среды Xcode 8, языка Swift 3 и последней
верси и ком плекта для разработки програм м ного обеспечения (S DK) возможнос­
ти стал и еще более захватывающим и и просты м и .
О к н и ге
Эта кн и га представляет собой руководство, призван ное помоч ь вам присту­
п ить к разработке собственных приложений для системы IOS. Ее цел ь - по­
мочь преодолеть перви ч н ые трудности и объясн ить, как работают приложения
для системы iOS и как они создаются .
Прорабаты вая материал кн и ги , вы создадите множество небол ьших прило­
жений, которые иллюстрируют кон кретные возможности системы IOS и демон­
стрируют, как можно у правлять этим и возможностя м и или взаимодействовать
с н и м и . Объединив теоретические знан ия, полученные в этой книге, со свои ми
талантом и упорством, а также с обш и рной и подробной документацией, пре­
доставлен ной ком панией Apple, вы узнаете все, что необходимо для создания
собственных профессиональных приложений для i Phone и i Pad .
ЗАМЕЧАНИЕ. По б ольше й части я буду ссылаться на устро й ства iPhone и iPad , поскольку
именно они расп ространены б ольш е всех . Однако это совершенно не означает, что
устро й ство iPod Touch не заслуживает внимания; это сделано тол ько дл я удо б ств а .
ПОДСКАЗКА. Автор ы п редыдущих и зда н и й организовал и форум , посвя ще н ны й этой
книге . Э то прекрасная возможность поо б щаться со своими едином ы шленниками , по­
лучить ответы на свои вопросы и даже ответить на вопрос ы других участников. Форум
находится по адресу http: / /forum. learncocoa. org. Добро пожаловать!
Что ва м тр е буе т ся
П режде чем приступить к разработке собственного програм м ного обеспече­
ния, вам необходимо иметь нескол ько инструментов. Новичкам понадобится ком­
п ьюгер Macintosh с процессором l ntel, на котором и нсталли рована операцион ная
система Yosem ite (версия OS Х 10.1О), Е1 Capitan (OS Х 1О.11 ), Sierra (macOS
1 0. 1 2) или еще более новая . Все новые ком п ьютеры - как ноутбуки, так и на­
стольные - должны работать без проблем . Кроме компьютеров, вам понадобится
программ ное обеспечение. Имея идентификатор Apple I D, вы сможете научиться
ГЛАВА 1 •� З НАКОМСТВО С СИСТЕМОЙ IOS
23
разрабаты вать nриложения для систем ы iOS и nолучить необходимое nрограм­
мное обесnечение. Если вы я вляетесь владел ьцем устройства i Phone, i Pad ил и
iPod, то у вас nочти наверня ка уже есть идентификатор Арр\е I D. Если же его у вас
нет, то просто nосетите сайт https : / / app l e i d . app l e . сот и создайте учетную
заnись. После этого nерейдите на страницу https : / / deve l ope r . app l e . сот/
deve l op
и увидите страни цу, показанную на рис. 1 .2 .
-
f)c•1t:ior
Bring Your
ldeas to Life
.
.
.
�
·­
........
·­
··­
. ,(С •
·-
Рис. 1.2. Веб -сайт Deve l opment Cente r ком пан и и Apple
Щел кн ите на кнопке Down loads, расположенной на верхней панел и, чтобы
nерейти на стран и цу основных ресурсов (рис, 1 .3), на которой размещены те­
кущие версии nрограм м и текущая бета- версия систе м ы iOS . Здесь вы увиди­
те ссыл ки на м ножество документов, в идеоматериалов, исходных кодов и дру­
гих справоч ных материалов. Все это предназначено для более качествен ного
обучен ия разработке nриложе н и й для систе м ы iOS . В ы nол н и в вертикал ьную
прокрутку экрана, вы найдете раздел ы Documentation и Videos. Кроме того, вы
найдете ссыл ку на форумы Арр\е Developer Forums, содержащие обсуждения са­
мых разных тем, касающихся nлатформ ы iOS, а также macOS, watchOS и tvOS .
Для того чтобы стать участни ком форума, вам необходимо зарегистрироваться
как разработч и ку приложений для устройств ком пан и и Арр\е.
ЗАМЕЧАНИЕ. На конференции разработчи ков l№JDC 20 1 6 компания Apple вернула на­
звание системы "OS Х" к старому варианту "macOS", чтобы обеспечить ее согласо­
ванность с именами четы рех основных платформ .
Наиболее важн ы м инструментом , которы й в ы будете испол ьзовать, я вляется
интегрирован ная среда разработки nрограм м Xcode ком пан и и Apple. Она в кл ю­
чает в себя и нструменты, предназначен н ые для создан ия и отладки исходного
кода, ком пиляции и настройки n роизводител ьности написан н ы х вам и nрило­
жений.
Загрузить текущую версию среды Xcode можно с помощью ссылки Xcode,
расnоложенной на странице Download (с м . рис. 1 . 3). Есл и вы предпоч итаете
использовать новейшую версию, то зайдите на сайт Мае Арр Store, испол ьзуя
меню Apple на компьютере Мае.
24
ГЛАВА 1 �' З НАКОМСТВО С СИСТЕМОЙ IOS
реп M�nu Clo�e Mt'ou
pple Developer
pplP Developer
Downloads
Get tl1e latest beta releases of Xcode, IOS, macOS,
\vatcl10S, tvOS, arкi more.
Xcode 8 beta
Рис. 1.3. На стран и це Downloads можно загрузить л юб ы е п рогра м м н ы е
продукты и бета-версии и н струментов для их разработки . Дл я этого необ­
ходи м о зарегистр и роваться с п о мощью своего идентифи катора Apple I D
Версии комплекта SDK и исходный код для примеров
По мере развития верс и й ком плекта SDK и среды Xcode механизм их загруз­
ки будет изменяться . В настоящее время компания Apple выкладывает текущую
"стабильную" версию среды XCode и пакета iOS SDK на веб-сайте М ае Арр Store,
часто одновременно п редоставляя разработчикам возможность загружать п ред­
варительные версии вы пусков со своего сайта для разработчиков. Если вы хотите
загрузить самую свежую ( н е бета ) версию среды Xcode и пакета IOS SDK, исполь­
зуйте веб-сайт Мае Арр Store .
Данная книга ориентирована на последн юю версию комплекта SDK. И ногда м ы
испол ьзовали новые функциональные возможности , которые стали доступными в
версии iOS 1 0 и м огут быть не совместим ы м и с более ранни м и версиями ком п ­
лекта SDK.
Не забудьте загрузить самые свежие и самые лучшие архивы исходного кода с
веб-сайта , посвященного нашей книге ( www. a p r e s s . com) . По мере появления
новых версий комплекта SDK м ы будем обновлять наши примеры , поэтому реко­
мендуем периодически посещать наш сайт.
ГЛАВА 1 •: ЗНАКОМСТВО С СИСТЕМО Й IOS
25
Во зм ожн ости ра з работ ч и ка
Бесплатно загружаем ы й ком плект S D K содержит си мул ятор, позволяющий
создавать и выпол нять приложения для устройств i Phone и i Pad на компьютерах
Мае . Это прекрасная возможность для обучения програм м ирован и ю для сис­
тем ы iOS. Однако симулятор не поддерживает фун кциональные возможности
аппаратного обеспечения, например работу акселерометра и видеокамеры . Для
того чтобы проверить эти возможности, необходимо иметь физические устрой­
ства i Phone, i Pod Touch ил и i Pad . Нес мотря на то что бол ьшую часть вашего
кода можно тестировать с помощью симулятора, для всех програм м это невоз­
можно. Даже если ваша програм ма работает на симуляторе, перед публи кацией
ее необходимо тщател ьно протестировать на реал ьном устройстве.
Предыдущие верси и среды Xcode требовал и, чтобы разработч ики регистри­
ровал ись как участн и ки програм м ы Арр\е Developer Program (за деньги). Тол ько
в этом случае они могл и загружать с вои приложения на реал ьный i Phone или
другое устройство. К счастью, ситуация изменилас ь . С реда Xcode 7 позволя­
ет пол ьзователя м тестировать прил ожения на реал ь н ы х устройствах (при не­
которых огран ичениях), не требуя, чтобы они регистрировал ись как участн и ки
программы Арр\е Deve loper Program . Это знач ит, что бол ьшую часть примеров,
приведенных в книге, можно бесплатно запускать на устройствах i Phone и i Pad.
Однако это не позволяет вам расп ространять свои приложения через магаз и н
Арр Store. Для того чтобы и м еть э ту возможность, необходимо подписаться на
одну из нижеприведенных програм м, заплатив определенную сум му.
П рограмма Standard стоит 99 долларов в год. Она предоставляет м но­
жество инструментов для разработки, ресурсы , техническую поддержку и
распространение ваш их разработок через магазин Мае Арр Store, а также
дает возможность разрабаты вать и распространять програм м ы для систем
IOS, watchOS, tvOS и macOS .
�:.
П рограмма Enterprise стоит 299 долларов в год. О н а предназначена для
ком паний, разрабаты вающих л и цензион ное корпорати вное программ ное
обеспечение дл я системы iOS .
Для того чтобы узнать бол ьше об этих программах, посетите веб-стран и цу
http : / / deve l ope r . app l e . com/ p r o g rams (рис. 1 .4). Если в ы - независи­
мый разработч и к, то вам целесообразно стать участником программы Standard.
Впрочем, вы не обязаны это делать, если не собираетесь запускать приложения,
испол ьзующие такие функционал ьные возможности, как iC\oud, которые требу­
ют наличия платного членства, или не хотите становиться участни ком форумов
Apple Developer Forums, ил и не планируете продавать свои програм м ы через
магазин Арр Store.
Поскол ьку операционная система iOS поддерживает работу постоя нно подклю­
ченного мобил ьного устройства, испол ьзующего беспроводную инфраструктуру
26
ГЛАВА 1 � ЗНАКОМСТВО С СИСТЕМОЙ IOS
других ком паний, ком пания Apple была вы нуждена установить более строгие
ограничения для разработч и ков програм м ного обеспечения для системы iOS
по сравнению с огран ичениями, наложенн ы м и на разработч иков программ для
компьютеров Мае (которые могут, по крайней мере могли, в момент написания
книги, писать и распространять програм м ы без ведома ил и одобрения компании
Apple). Несмотря на то что устройства i Pod touch и версии i Pad, поддержи ваю­
щие только подключение Wi-Fi, не испол ьзуют ни какой другой инфраструктуры,
на н их распространяются те же сам ые ограничения.
Apple Developer Program
Program Membership Details
Software and
Tools
Download and install tl1e latest
Ьеtа OS releases for
development and distribution.
Access your account to
configure resources required
for the development and
dlstributlon process.
Beta OS Releases
Developer Account Tools
your development AppJe
manage your devices and
Download the latest beta OS
releases and install them on
devi<:es.
•
•
•
Access the resources you need
to configure арр services,
development teams. and to
subm1t new apps and updates.
iOS 10
macOS Sierra
watchOS
• tvOS
Рис. 1.4. П одп и с ка на платное ч л е н ство п редоставляет доступ к бета-ве рси ­
я м и основн ы м верси я м с и сте м н ых и н струм е нтов
Ком пан ия Apple наложила эти ограничения не от скупости, а для того, что­
бы м и н и м изировать вероятность поя вления злонамеренных или плохо нап исан­
ных программ, распространен ие которых может снизить производител ьность
совместно эксплуатируемой сети. Может показаться, что разработка программ
для операционной системы iOS напоми нает бег с препятствиями, но ком пания
Apple приложила м ного усил и й для того, чтобы этот процесс был как можно
более безболезнен н ы м . Кроме того, подписка стоимостью 99 долларов нам ного
ГЛАВА 1 � ЗНАКОМСТВО С С И СТЕМОЙ IOS
27
меньше, чем цена покупки, например, и нтегрированной среды разработки Visual
Stud io, разработанной ком панией M icrosoft.
Ч то нео б ход и мо з н ать
Предполагается, что вы уже умеете програм м ировать и понимаете при н ци п ы
объектно-ориентирован ного программ ирования (т.е. знаете, что такое, например,
классы, объекты, цикл ы и переменные). Кроме того, предполагается, что вы зна­
ете язык Swift. Приложение в кон це книги содержит введение в язык Swift и
описание функциональной возможности Playground в среде Xcode. Если после
прочтения приложения вы захотите углубить свои знания о языке Swift, лучше
всего немедленно приступите к програм мирован и ю и прочитайте справочн и к
ком пании Apple The Swift Programming Language, которы й можно приобрести в
магазине i Books ил и на сайте для разработчи ков приложения для системы IOS
по адресу https : / / deve l ope r . app l e . com/ l i b r a r y / i o s / do cume n t a t i o n /
Swi f t / Conceptua l / S w i f t_Programmi ng_Language / i ndex . html .
Вы должны также знать систему iOS как пол ьзовател ь . Поскол ьку вы со­
би раетесь писать приложения для л юбой платформ ы , освойте н юансы и осо­
бен ности устройства i Phone, i Pad ил и i Pod . Посвятите время изучен и ю и нтер­
фейса системы IOS, а также внешнему виду приложе н и й для устройств i Phone
и/ил и i Pad .
Поскол ьку разн ые терм и н ы могут ввести вас к заблужден ие, в табл . 1 . 1 при­
ведены связи между платформам и, и нтегрирован н ы м и средами разработки, ин­
терфейсам и прикладного програм мировани я и языком.
Таблица 1. 1. Соответствие между платформами, и нструментами и языками
Платфо рма
С реда
И нтер фейс API
Язык
macOS
Xcode
Сосоа
Objective-C, Swift
Xcode
Сосоа Touch
Objective-C, Swift
IOS
Отл и ч ител ьн ы е осо б еннос ти
п рограмми р о вания для сис т ем ы iOS
Ес л и вы н и когда не испол ьзовал и систему Сосоа на ком п ьютерах Мае, то,
,
возможно, каркас Сосоа Touch, предназначен н ы й для разработки прил ожений
на платформе IOS, покажется вам немного недружел юбн ы м . Он существен­
но отл ичается от остал ьных обы ч н ы х сред разработки п риложе н и й , исполь­
зуемых, напри мер, для разработки приложе н и й для платформ ы .N ET ил и на
языке Java. Не стоит беспокоиться о том, что на первых порах вам будет не­
скол ько неудобно. Просто поработайте над у пражне н и я м и , и все встанет на
свои места.
28
ГЛАВА 1 � ЗНАКОМСТВО С С И СТЕ М О Й IOS
ЗАМ ЕЧАНИ Е. В книге часто встречается те р м и н " каркас " (framework ) . Несмотря на то
что его смысл довол ьно туманный и зависит от контекста , мы будем считать, что это
коллекция инструментал ьных средств , к которым могут относиться одна или несколь­
ко библиоте к, сценарии , элементы пользовател ьского интерфейса и м ногое другое .
Элементами каркаса часто я вляются специальные функци и , такие как службы локации
в каркасе CoreLocation .
Есл и вы уже писали программ ы с помощью каркаса Сосоа, то бол ьшая часть
ком плекта IOS SDK будет вам знакома. Очень м ногие классы, содержащиеся в
этом пакете, остались неизменн ы м и еще со времен верс и й для разработки про­
грам м под управлением операционной системы macOS. Однако даже те классы,
которые подверглись изменениям, подч иняются тем же фундаментальным прин­
ципам, которые был и установлены в предыдущей верси и . Тем не менее между
каркасам и Сосоа и Сосоа Touch существует нескол ько разл и ч и й .
Независимо от уровня подготовки вы должны пом н ить о некоторых кл юче­
вых различиях между разработкой програм м для системы IOS и для настол ьных
ком п ьютеров.
Только одно акти вное приложение ( как правило )
В системе IOS в каждый момент времен и быть активным и выводить информа­
цию на экран может только одно приложение. Начиная с версии IOS 4 приложения
иногда продолжают выполняться в фоновом режиме после того, как пользовател ь
щел кнет на кнопке Home, но даже это возможно лишь в редких ситуациях, которые
необходимо предусматривать специально (как именно, мы расскажем в главе 1 5 ).
В системе IOS 9 ком пания Apple добавила возможность выполнять два приложе­
ния в фоновом режиме с одним экраном, но для этого пол ьзовател ь должен иметь
одну из новей ших версий устройства i Pad . Эта фун кционал ьная возможность,
которую ком пания Apple называет м ногозадачностью, описы вается в главе 1 1 .
Когда п риложение не я вляется актив н ы м ил и выпол няется в фоновом режи­
ме, централ ьн ы й п роцессор не обращает на него н и какого внимания, что поз­
воляет этому приложению оставлять открытые сетевые соеди нения и зан имать
другие ресурс ы . Система IOS разрешает фоно в ы й режим, но, для того чтобы
ваше приложение в этой ситуаци и работало правил ьно, необходимо приложить
определенные усил и я .
Только одно окно
Операционные с исте м ы ноутбуков и настол ь н ы х систем допускают парал­
лел ьное вы полнение програм м, каждая из которых может откры вать нескол ько
окон и у правлять и м и . Однако система iOS позволяет приложениям работать
тол ько с одним окном . Все взаимодействия с пол ьзователем происходят тол ько
в этом окне, причем его размер ф и ксирован и совпадает с размером экрана, если
пол ьзовател ь не вкл юч ил режим м ногозадачности, допускающи й ис пол ьзован ие
одного экрана несколькими приложения м и .
ГЛАВА 1 1,с ЗНАКО М СТВО С С И СТЕ М О Й IOS
29
Ограниченный доступ с целью обеспечения безопасности
Програм м ы на комп ьютерах имеют доступ ко всем ресурсам, открыты м для
пол ьзователя . Однако система iOS существенно огран ичи вает возможности при­
ложений.
В ы можете ч итать и записывать файл ы тол ько в той ч асти файловой систе­
мы iOS, которая была создана для вашего приложения. Эта область назы вается
песочн и цей (saпdbox). Здесь ваше п р иложение может хранить документы, на­
стройки и другие данные, которые необходимо запом н ить.
Ваше приложение огран ичено не тол ько эти м . Напри мер, вы не и меете до­
ступа к сетевым портам iOS с мал ы м и номерам и ил и не можете делать то, для
чего требуются права адм и нистратора на настол ьном комп ьютере.
П рилож ение дол ж но быстро реаги ровать
на действия пользователя
Вследствие особе н ностей с воего испол ьзован ия система iOS должна быть
придирч ивой, и того же самого она ожидает от вашего приложения. После за­
пуска програм м ы вы должн ы открыть приложен ие, загрузить настройки и дан­
ные, а также главное представление (rnaiп view) на экране всего за нескол ько
секунд.
ЗАМ ЕЧАН И Е . Под заде ржкой ( l ateпcy) мы не и меем в виду средн юю скорость . Ско­
рость и задержка часто используются как синон им ы , но это о ш и бка . Задержка оз­
начает время между действием и реакцией на н его . Есл и пользовател ь щел кнул на
кнопке Home, система IOS откроет домашний экран , а вы должны быстро сохранить
все данные и выйти . Есл и вы замеш каетесь дол ьше п яти секунд, ваше приложение
будет уничтожено независимо от того , завершили вы сохранение своих данных или
нет. Существует интерфейс прикладного п рогра м м и рова н и я , который п редоставляет
вашему приложению дополн ител ьное время дл я корректного завершения работы , но
для его испол ьзован и я сначала необходи мо научиться это делать. Итак, необходи мо
обеспечить быстрое реаги рова н и е , возможн о , за счет отбрасывания неважной ин­
формаци и .
Ограниченный размер экрана
Экран устройства i Рlюпе действител ьно хорош . В момент своего поя вления
он и� ел максимал ьное разрешение среди всех существовавш их устройств. Од­
нако на дан н ы й момент этот экран невел и к, и в резул ьтате в вашем распоряже­
нии есть существенно меньше места, чем на экранах современных компьютеров .
Экраны первых поколений i Phoпe и м ел и разрешен ие всего 3 2О х 480 п и кселей,
а экраны следующего поколения обеспечивали разрешение 64О х 960 (i Phoпe 4).
Экран ы нове й ш и х устройств i Phoпe ( i Phoпe 6/бs P l us) и меют разрешение
1 08Ох 1 920 п и кселей. Однако следует иметь в виду, что дисплеи с высоким раз­
решением (которые компан ия Apple назы вает Retina) втиснуты в тот же сам ы й
30
ГЛАВА 1 !11: ЗНАКОМСТВО С С И СТЕМ О Й IOS
формфактор, что довольно сил ьно ограни ч ивает возможности приложений. Раз­
меры экранов всех доступных в настоящий момент устройств ком пании Apple,
поддержи вающих операцион ную с истему iOS 1 О, переч ислены в табл . 1 .2 .
Таблица 1 . 2 . Размеры в п икселях экрана устройств iOS
Устройст во
Ф изи ч еский
р азмер
П рогр аммны й
размер
Ма сш та б
iPhone 5 и 5s
640х 1 1 36
3 2 0 х 568
2х
iPhone 6/6s
750х 1 334
375х667
2х
iPhone 6/6s Plus
1 080х 1 920
4 1 4х736
Зх
iPhone SE
640х 1 1 36
3 2 0 х 568
2х
iPad 2 и iPad mini
768х 1 024
768 х 1 024
1х
iPad Air, iPad Air 2, iPad Retina
и iPad mini Retina
1 536х2048
768х 1 024
2х
iPad Pro
273 2 х 2 048
1 33 6 х 1 024
2х
Физически й размер представляет собой реал ь н ы й размер устройства, изме­
рен н ы й в п и кселях. Однако, когда вы п и шете програм му, ориентируйтесь на
програм м н ы й размер. Легко видеть, что во м ногих случаях програм м н ы й раз­
мер составляет тол ько половину физического. Эта ситуация сохраняется с того
момента, когда ком пания Apple разработала э кран Retina, который имел в два
раза бол ьше п и кселей в обоих направлениях по сравнению со своим и предшест­
вен н и кам и . Есл и бы ком пания Apple не предпри няла специал ьных мер, то все
существующие приложения зани мал и бы тол ько половину экрана Retina и стал и
бы практически бесполезны м и . По этой причине ком пания Apple решила вы пол­
нять автоматическое масштабирован ие приложения с коэффициентом 2, чтобы
они заполнял и весь экран на устройствах новых поколен и й . Коэффи циент мас­
штабирован ия, равный двум, применяется ко всем устройствам с экраном Retina
за искл ючением устройства i Phone 6/бs Pl us, которое имеет экран с еще более
высоким разрешением, требующи м коэффициента масштабирован ия, равного
трем . Впрочем, в бол ь ш и нстве случаев п риложен ие масштабируется автомати­
чески, так что вам п росто следует уч иты вать п рограм м н ы й размер, а система
iOS все остал ьное сделает сама.
Еди нстве н н ы м искл ючением из этого п равила я вл я ются растровые изоб­
раже н и я . Посколь ку они по своей природе и меют ф и ксирован н ы й размер, на
любых экранах, как Retiпa, так и остал ьн ы х, лучше всего испол ьзовать одно и
то же изображение. В этом случае вы увидите, что система iOS мас штабиру­
ет ваше изображение на устройствах с э краном Retina, в резул ьтате чего про­
исходит потеря четкости . Для того чтобы устран ить этот эффект, необходимо
сделать специал ьные коп и и для каждого изображения с учетом коэффициентов
масштабирования 2 х и З х для экранов Retiпa.
ГЛАВА 1 д ЗНАКОМСТВО С СИСТЕМОЙ IOS
31
ЗАМЕЧАН ИЕ. В е рнувшись к та бл . 1 . 1 , вы увидите , что коэффициент масштаби р ова н и я
в четве ртом стол бце равен отно ш е н и ю ф и з и ческо го р азме ра к програ м м ному. Н а ·
прим ер , на устро й стве iPhone 6/6s фи з ич ески й разм ер равен 750, а п рогра м м н ы й 375, т. е . отно ш е н и е равно 2 : 1 . Одн а ко если п р исмотреться в н и м ател ьнее , то можно
увидеть, что ситуа ци я с устройством i Phone 6/6s и м еет свои осо б енности . Отношение
физическ о й ш и р и н ы к п рогра м м н о й составл яет 1 080/4 1 4 , т. е . 2 , 608 : 1 . То же самое
отн осится к в ысоте . С л едо вател ьно , в те р м и нах ф изическо го разм е ра устрой ство
iPhone 6/6s на самом дел е не имеет трехкратно го разре ш ен и я экрана Retin a . Однако
с точки зре н и я п ро г ра м м н ого разм ера масшта б увел ич и вается втрое , т. е . п риложе ·
ние , написанное дл я экрана 4 1 4х736 , л огически ото бр ажается на ви ртуа л ьном экране
1 242х2208 , а зате м масшта б и руется н а реальн ы й экран 1 080х 1 920. К счастью , дл я
этого не тре б уется п р и клад ы вать н икаких усил и й , потому что систем а iOS делает зто
авто матичес ки .
Ограниченные ресурсы системы
Програм мистам, имеющим большой опыт работы, возможно, показалось, что
компьюrер, имеющий 5 1 2 Мбайт операти вной памяти и 1 6 Гбайт памяти на жест­
ком диске, ограничен в ресурсах, и это правда. Тем не менее разработку прило­
жения Дll Я системы iOS, вероятно, нел ьзя сравнить с попыткой написать сложное
приложение Дll Я работы с электронн ы м и табл и цам и на ком пьютере с объемом
оперативной памяти, равным 48 Кбайт. Однако, учиты вая графическую приро­
ду системы iOS и все то, что она умеет, исчерпать память очень и очень легко.
Все устройства с системой iOS, доступные в настоя щее время, имеюr л ибо
5 1 2 Мбайт (i Phone 4S, ориги н ал ь н ы й i Pad m i n i , последняя версия i Pod touch),
л ибо 1 024 Мбайт физическо й оперативной памяти ( i Phone 5с, i Phone 6/6s,
iPhone 6/бs Plus, iPad Air, i Pad Air 2, i Pad m in i Retina), и этот показатель со вре­
менем будет увел и ч и ваться . Одна часть этой памяти используется Дll Я буфера
экрана, а другая - для системных процессов. Обы ч но Дll Я приложений пол ьзо­
вателей остается не более половины операти вной памяти, а то и меньше.
Может показаться, что половина памяти - это не так уж и мало Дll Я такого
небол ьшого ком п ьюrера, но существует еще оди н фактор, вл ияющий на объем
памяти . Современные операционные систе м ы ком пьютеров, такие как macOS,
создаюr блоки памяти , которые нел ьзя испол ьзовать, и зап исы вают их на диск
в виде файла подкачки (swap fi le). Файл подкачки позволяет приложени я м про­
должать вы пол нение, даже есл и о н и требуюr больше памяти, чем доступно на
ком пьютере. Однако система iOS не записы вает содержимое кратковременной
памяти, напри мер данн ые, в файл подкачки. В результате объем памяти, доступ­
ный Дll Я вашего приложения, огран ичен объемом свободной физической памяти
на устройстве iOS.
Каркас Сосоа Toucl1 имеет встроен н ы й механизм, позволяющий приложению
узнавать, когда объем доступ ной памяти становится сл и ш ком мал ы м . Когда это
происходит, ваше приложение должно освободить ненужную память, ил и оно
рискует быть уничтожен н ы м .
ГЛАВА 1 [;)1 ЗНАКОМСТВО С С И С Т Е М О Й IOS
32
Уни кальные возмож ности устройств iOS
Как отмечалось в ы ше, каркас Сосоа Touch не имеет некоторых функционал ь­
ных возможностей, которым и обладает каркас Сосоа. С праведл и вости ради от­
мети м , что ком плект IOS S D K и м еет фун кционал ьные возможности, которых
нет в каркасе Сосоа, или, по крайней мере, на каждом ком п ьютере Мае.
1''
Ком плект iOS SDK позволяет вашему приложению определять текущие
географические координаты устройства IOS, испол ьзуя механ изм Core
Location .
'А'
Большинство устройств iOS имеют встроенные видеокамеры и библ иоте­
ки фотографи й, и ком плект S D K предоставляет механ изм, позволяющий
вашему приложению пол ьзоваться эти м и возможностя м и .
.!?
Устройства iOS имеют встрое н н ы й акселерометр, позволя ющий опреде­
л ить, как вы держите и перемещаете свое устройство.
В вод и вывод информации
Устройства, работающие под управлением систе м ы iOS, не оснащены клави­
атурой и м ы ш ью. Это знач ит, что вам предоставлен совершенно новы й способ
взаимодействия с пол ьзователем по сравнению с програм м и рован ием обычных
ком пьютеров. К счастью, бол ь ш инство таких взаимодействи й адаптировано для
вас. Нап р имер, есл и вы добавляете поле редактирования в свое п риложение,
система IOS сама знает, что нужно в ывести на экран клавиатуру, когда пол ьзова­
тель щелкает на этом поле, и вам не нужно п исать для этого специал ьный код.
ЗАМЕЧАНИЕ. Соврем е н н ые устройства позволя ют подкл ючать в н е ш н юю клавиатуру че ­
рез меха н и з м B luetooth . Н есмотря на то что это позвол яет испол ьзовать традицион ­
н ы е навы ки ра б оты с кл авиатуро й и эконом ить место на экране , та кая возможность
испол ьзуется довол ьно редко . В н астоя щ и й м омент в систем е IOS соеди нение с м ы ­
ш ью воо б щ е не п редусмотре н о .
С одер ж ан ие кни г и
Когда я нач и нала разрабаты вать приложения для систе м ы iOS, которая в то
время наз ы валась " i Phone OS", я п рочитала первое издание этой книги, осно­
ван ное на язы ке Obj ective-C . Со временем м не удалось разработать мощные и
производител ьные п риложения, иногда даже получая за это деньги. По этой
причине я хотела бы сделать все, чтобы нап исать самую современную и самую
луч шую верс и ю книги, сохранив ее доступность. Я планирую охватить в книге
следующие тем ы .
1)1
Из главы 2 вы узнаете, как испол ьзовать I nterface B u i lder
неотъемле­
мую часть среды Xcode
для создания простого и нтерфейса, который
вы водит некоторый текст на экран .
-
-
ГЛАВА 1
::i
�·,
•
ЗНАКОМСТВО С С И СТ Е М О Й IOS
33
В главе 3 мы рассмотри м вопросы взаимодействия с пол ьзователем, соз­
дан простое приложение, ди нам ически обновляющее текст, который вы­
водится на экран в ходе в ы п ол нения п рограм м ы в зависимости от того,
какую кнопку нажал пол ьзовател ь.
Глава 4 основана на главе 3 . В ней рассматриваются некоторые стандарт­
ные элементы управления интерфейсом систе м ы IOS . М ы также увиди м,
как вы вести на экран п редуп реждение и меню, чтобы п редложить пол ь­
зователю при нять решение ил и сообщить ему о том, что случ илось нечто
необыч ное.
"i
В главе 5 рассматриваются атрибуты механизмов автоматического поворо­
та и изменения размеров и Auto Layout, ПО'з воляющих использовать прило­
жения для систе м ы IOS как в книжной, так и в ал ьбомной ориентации .
�'='
В главе 6 м ы перейдем к более сложным пол ьзовательским и нтерфейсам
и обсудим создание приложений, поддержи вающих нескол ько представ­
лен и й . Мы покажем, как выбрать представление в ходе вы полнения про­
грам мы, что знач ител ьно повысит потенциал ваш их приложе н и й .
·�
Панел и вкладок и пал итры цветов я вляются частью стандартного пользо­
вательского и нтерфейса систе м ы iOS. В главе 7 м ы покажем, как испол ь­
зовать эти элементы и нтерфейса.
w
В главе 8 описаны табл и ч н ые представления, основной способ создания
списков дан ных для пол ьзователя, а также при н ци п ы создания приложе­
ний, испол ьзующих иерархическую навигацию. Кроме того, будет показа­
но, как организовать поиск дан ных, принадлежащих приложен ию.
�1
Одн и м из основных элементов и нтерфейса приложения в системе IOS я в­
ляется иерархический с п исок, позволя ющий пол ьзовател ю углубиться в
дан ные или выяснить детал и . В главе 9 м ы нау ч и м вас создавать этот
стандартны й тип и нтерфейса.
il"
С самого начала приложе н и я iOS и с п ол ьзо вал и табл и ч н ы е представ­
ления дл я обеспечения д и н а м и ч но й верти кал ьной п ро крутки с п и ско в .
Н е с кол ь ко л ет н азад ком па н и я A p p l e создал а но в ы й класс с и м е н е м
U I C o l l e c t i o nV i ew, е ще более у глубл я ю щ и й эту ко н це п ци ю , п редо­
ставл я я разработч и кам более гибкие возмож н ости дл я изоб раже н и я
в и зуал ь н ы х ко м по н е н то в . Кол л е к ц и я п редставл е н и й о п и с ы ваетс я в
, главе 1 О.
�
В главе 1 1 показано, как создать приложения с главн ы м и детал изиро­
ван н ы м п редставления м и и п редставить сп исок (напри мер, с п исок сооб­
щен и й электронной почты), позволяющий пол ьзовател ю видеть детал и
каждого пункта. Кроме того, в ней о п исаны элементы у правления iOS,
поддержи вающие эту кон це пцию, которые изначально были разработан ы
для устройства i Pad, но сейчас досту п н ы и для устройств i Phone.
ГЛАВА 1 !11 З НАКОМ СТВО С СИСТЕМОЙ IOS
34
lit
В главе 1 2 рассматри ваются вопросы настрой ки приложений, которые
представля ют собой механизм систем ы iOS, позволяющий пол ьзователям
задавать свои параметры на уровне приложения .
W№.
Глава 1 3 посвящена управлению дан н ы м и в системе IOS. В ней обсужда­
ется создание объектов для хранения дан ных п риложения и показано, как
организовать постоян ное хранение дан ных в файловой системе IOS. Здесь
также излагаются основы испол ьзования инструмента Core Data, позволя­
ющего легко сохранять и извлекать данные. Однако для углублен ного ис­
следования этого инструмента вам стоит проч итать кн и гу Майкла Прайви­
та (M ichae\ Privat) и Роберта Уорнера ( Robert Warner) Pro IOS Persistence
Using Core Data (Apress, 20 1 4).
в
Новая фун кционал ьная возможность в системе IOS 5 - служба iC \oud
позволяет пол ьзователя м хранить свои данные онлай н, а также синхрони­
зировать разные экзе м пляры и приложения. Основы службы iC \oud опи­
сы ваются в главе 1 4.
м
Разработчики IOS имеют возможность испол ьзовать новый подход к мно­
гопоточной разработке с помощью технологии Grand Central Di spatch, а
также в некоторых сиrуациях запускать свои приложения в фоновом ре­
жиме. Из главы 1 5 вы узнаете, как это сделать. Кроме того, мы покажем,
как испол ьзовать фун кции системы iOS, позволяющие в некоторых сиrу­
ациях запускать приложение в фоновом режи ме.
f\1#
Все л юбят рисовать, поэтому в главе 1 6 речь пойдет о том, как создавать
р исун ки с помощью системы Core Graph ics.
q
В верси ю IOS 7 ком пания Apple включила каркас Sprite Kit дл я созда­
ния двумерных игр. Он вкл ючает в себя механизмы и м итаци и физических
законов и ани мации , п озволяя создавать и гр ы в том ч исле дл я macOS.
В главе 1 7 м ы продемонстрируем разработку простой и гры с помощью
механизма Sprite K it.
�
Сенсор н ы й экран ( m ultitouch screen), характерн ы й дл я всех устройств,
работающих под у п равлением систе м ы iOS, может рас познавать м ного
разны х жестов пол ьзовател я . В главе 1 8 м ы покажем, как распознать ос­
новные жесты, например щипок и скол ьжение.
11
Благодаря технологии Core Location система iOS способна определять ши­
роrу и дол гоrу. В главе 1 9 м ы создадим программу, которая с помощью
технологи и Core Location будет определять, в какой точ ке земного шара
вы находитесь.
-
"" В главе 20 мы изучи м проблемы взаи модействия с акселерометром и ги­
роскопом, встрое н н ы м и в систему iOS. Эrи и нструменты позволяют опре­
делить, как вы держите устройство, а также с какой скоростью и в каком
направлен и и оно перемещается.
ГЛАВА 1 .\!! З НАКОМСТВО С СИСТЕМОЙ IOS
35
Практи чески каждое устройство с системой IOS имеет видеокамеру и
библ иотеку рису н ков, которые будут досту п н ы для вашего приложения.
В главе 2 1 рассказы вается о том , как получить доступ к эти м ресурсам .
lii:
В настоя щее время устройства с системой iOS досту п н ы более чем в
90 странах. Из главы 22 вы узнаете, как написать приложение, чтобы все
его части легко переводил ись на иностранные языки. Это позволит расши­
рить потенциал ьную аудиторию для вашего п риложения.
;r.i
В приложе н и и описы ваются текущая версия языка програ м м и рования
Swift и все фун кци и, необходимые для понимания примеров, при веден­
ных в книге.
Ч то нового в д а н ном и зд а н и и
С тех пор как первое издание этой книги поступило в кн ижны е магазины,
сообщество разработч иков приложений для системы i O S значительно увеличи­
лось. Ком плект S D K постоя н но разви вается, а ком пания Apple постоя нно вы­
пус кает его новые верс и и . С и стема IOS 1О и каркас Xcode 8 содержат м но­
жество новинок. Я приложила м ного усил ий, чтобы описать новые технологии,
необходимые для того, чтобы приступить к разработке приложения для IOS.
Версии я з ы к а Swift и к а рк аса Xcode
Я з ы к Swift появился всего два года назад; он все еще развивается, и, вероят­
но, этот процесс еще будет продолжаться некоторое время . И нтересно, что ком­
пания Apple обещала, что ском п ил и рован н ы й двои ч н ы й код ранее написанных
приложений будет работать в более поздних версиях IOS, но не гарантировшю,
что исходн ы й код одного и того же приложения будет по-прежнему ком п илиро­
ваться . В резул ьтате возможна ситуация, в которой код примера, которы й был
ском пилирован и выпол нен в верс и и среды Xcode, которая была текущей, в бу­
дущем может перестать ком пилироваться . С реда Xcode 6.0 поставляется с вер­
сией Swift 1 , Xcode 6.3
с версией Swift 1 .2, а Xcode 7
с версией Swift 2.
Код, представлен н ы й в книге, был написан и протестирован с помощью бета­
версии Xcode 8 и Swift 3 .
Есл и в ы обнаружите, что исходны й код примера бол ьше н е ком пил ируется
в вашей версии Xcode, пожалуйста, посетите страни цу, посвященную кн иге, на
сайте www . apre s s . сот и загрузите ее последнюю версию. Если и после этого у
вас будут проблемы, то сообщите об этом в разделе Erratum на веб-сайте Apress.
-
-
Н а ч нем
Система IOS
невероятная в ы ч исл ител ьная платформа и перспекти вная
современ ная среда дл я разработки приложений. П рограм м и рование для систе­
мы iOS представляет собой совершенно новый оп ыт, отл и чающийся от любой
-
36
ГЛАВА 1 '� З НАКО М СТВО С СИСТЕМОЙ IOS
другой платформ ы . Все, что казалось знаком ы м , на поверку оказы вается не­
сколько необ ы ч н ы м , но по мере освоения этой книги все понятия постепенно
прояснятся и образуют новую строй ную конструкцию.
И мейте в виду, что упражнения в книге представляют собой не просто пере­
чень задани й . Если вы их вы пол н ите, то вол шебн ы м образом станете экспертом
по разработке программ для систе м ы iOS. Прежде чем переходить к новому
проекту, убедитесь, что понимаете, что и для чего делаете. Не бойтесь вносить
изменения в програм м ы . Н аблюден ие за резул ьтатам и экспериментов - оди н
и з наилучших способов преодолеть сложности кодирован ия в средах, подобных
Сосоа Touch .
Итак, есл и вы уже загрузил и и инсталл ировал и среду Xcode, то переверн ите
стран и цу и сделайте следующий шаг на пути к своей цел и - стать настоя щим
разработч и ком приложений для системы iOS.
ГЛ А В А 2
11
П е р в о е п р ил о же н и е
Для того чтобы получить представление о програм м ирован и и для системы
iOS и стимул к дал ьнейшему развитию профессиональных навыков, лучше всего
сразу приступить к разработке приложения для вашего i Phone (рис. 2 . 1 ). В этой
главе мы испол ьзуем интегрированную среду разработки Xcode для создани я не­
бол ьшого приложения для системы iOS, которое вы водит на экран текст "Hel lo,
World ! " Мы увидим, какие механизмы вовлечены в создание проекта приложе­
ния для систе м ы iOS в среде Xcode, рассмотри м специфику применения про­
грам м ы l nterface Bui lder при разработке пользовательского и нтерфейса, а затем
выпол н и м наше приложение с помощью симул ятора iOS. Кроме того, снабди м
наше приложение пиктограм мой, чтобы о н о стало еще более похожим на реал ь­
ное приложение для систем ы iOS.
Рис. 2 . 1 . Резул ьтаты работы п риложе н и я , разработа н н ого
в это й главе , м о гут п о казаться п р и м ити в н ы м и , н о ведь м ы
находимся л и ш ь в начале пути
38
ГЛАВА 2 1&1 П ЕР В О Е П Р ИЛОЖЕН И Е
П роект Hello World
К данному моменrу на вашем компьютере Мае должны быть установлены сре­
да Xcode 8 и ком плект инструментов iOS SDK. Желательно также загрузить архив
исходных кодов, приведенных в книге, с веб-сайта Apress (www . apre s s . сот) . Кста­
ти, на этом сайте есть форум читателей книги http : / / forum . lea rncocoa . org.
Это прекрасное место для обсуждения вопросов, связанных с разработкой про­
грам м для системы iOS, обмена вопросами и ответами и для встреч едином ыш­
ленников.
ЗАМЕЧАНИЕ. Н есмотря на то что в вашем распоряжении имеется пол н ы й на бор проект ­
ных файлов из книги , м ы полагаем , что еще б ол ьше пол ьзы вы с можете извлечь, само ­
стоятел ьно разра баты вая со б ствен ны й п роект, а не п росто коп и руя готовые о б разцы .
Создавая свой п роект, вы прио б ретете опыт ра б оты с разноо б разным и инструментам и .
Проект, который м ы собираемся продемонстрировать в этой главе, находится
в папке 0 2 He l l o Wo r l d в архи ве исходных кодов.
С начала необходимо запустить среду Xcode . Это инструмент, которым мы
будем пользоваться на протяжении практически всей книги. После его загруз­
ки с веб-сайта Мае Арр Store он будет автоматически инсталл ирован в папке
/App l i ca t i o n s , как бол ьшинство приложений для систе м ы Мае. М ы будем
м ного работать с этой п рограммой, поэтому стоит перетащить ее пиктограмму
на панел ь Dock, чтобы она всегда была под рукой.
Есл и вы впервые работаете со средой Xcode, не беспокойтесь - мы объяс­
ним весь процесс создания нового приложения . Есл и вы опытн ы й разработч ик,
но еще не работали с програм мой Xcode 4, то сам и убедитесь, что в ней многое
изменилось (в основном, к лучшему).
Запустив впервые среду Xcode, вы увидите окно приглашен ия, похожее на то ,
которое показано на рис. 2.2. В этом окне можете выбрать команду для создания
нового проекта, соединиться с системой проверки версий, чтобы найти сущест­
вующи й проект, или выбрать проект из списка недавно откры вавшихся проектов.
Окно приглашения представляет собой удобную отправную точку, предоставляя
пол ьзователю досrуп к большинству функционал ьных возможностей, которые
могут понадобиться после запуска п рограмм ы Xcode. Все эти возможности до­
сrупны также из меню программы Xcode, поэтому закройте окно и продолжайте
рабоrу. Если не хотите снова увидеть это окно в дал ьнейшем, просто сбросьте
флажок Show this window when Xcode Launches, прежде чем закрыть окно.
Создайте новы й п роект, выбрав команду Newc::> Project. " в меню File ил и на­
жав комбинацию клавиш <Sh ift+Command+N>, откры вающую окно новых про­
ектов (рис. 2.3). На этом л исте можно выбрать шаблон проекта, которы й станет
основой нашего приложения. Л ист разделен на пять разделов: IOS, watchOS,
tvOS, macOS и Cross-platform . Поскол ь ку мы собираемся создать приложение
для систем ы iOS, нажм ите на кнопку IOS, чтобы открыть шаблоны соответ­
ствующих приложен ий.
-
ГЛАВА 2 tй П ЕР В О Е П Р ИЛОЖЕ Н И Е
39
Соге Oata Perslstence
•• Pllli SS. SНAREPOINТ/SOUAC(..COOE/ch13
Swlft&.slca
..SS.Sl-IAREPOINТ/SOURCE..COiOE/Apptnd x
TextShooter
�PRES$.SНARE.POINT/SOURC(,,.COOЩdt1 7
Welcome to Xcod e
OuartzFun
-P11ESЗ.SНAREPOINТ/SOURC!./dt
.COOE l8
PinchМe
-PRESS.SНAREPOINT/SOURCE.CODE/ch18
Таре
•. PRESS.S HAJIEPOINT/SOURCE.J;ODl:ftlll 8
Get st1rted with а playground
Explore new 1deas quickly and eas1ly.
Create а new Xcode proJect
Create an арр lor 1Phone, iPad, Мае, Дррlе Watch or Apple тv.
Swipes
-№EPOtNТ/SOURCE..CODE/ch18JSwlpet З
Check out an existing projec:t
Start working on something lrom an SCM repositorv.
Show this window when Xcode launches
Open enother project•.
Рис . 2 . 2 . Окно п р и гл а ш е н и я п рограм м ы Xcode
Choose а template for your new project:
watchOS
Appncatlon
tvOS
macOS
1
l1 1
Crosa-platlorm
1•1
Slngle View
A pp fication
Garne
� -�1
Master-Oetail
Page-Вased
Applicatlon
Application
ТаЬЬеd
App�catlon
l91
�о'
iMessage
Applicatlon
Application
Sticker Pack
Framework & Library
14;
Сосоа Touch
Framework
-------
Cancel
Сосоа Touch
Stetic LiЬrary
�
Metal Library
J
Рис. 2 . 3 . Окно , позволя ю ще е выб рать разн ые ш абл о н ы файлов для созда ­
н и я нового п роекта
40
ГЛАВА 2 ""' П ЕР В О Е П Р ИЛОЖЕН И Е
Каждая и з п и ктограмм, показан ных в правом верхнем углу рис. 2.3, соответ­
ствует отдел ьному шаблону проекта, который можно использовать в качестве
отправной точ ки для вашего приложения для системы iOS. П и ктограм ма Single
View Application соответствует простейшему шаблону, который будет испол ьзован
в первых главах книги . Остальные шаблоны обеспеч ивают испол ьзование допол­
нительного кода и/или ресурсов для создания обыч ных и нтерфейсов приложен ий
для устройств I Phone и i Pad . Они будут рассмотрен ы в последующих главах.
Щел кните на п и ктограм ме Single View Application (см . рис. 2 . 3 ), а затем на
кнопке Next. В ы у видите л ист параметров проекта, который выглядит примерно
так, как на рис. 2.4. На этом листе необходимо запол нить поля Product Name и
Company ldentifier, соответствующие вашему проекту. П рограм ма Xcode объеди­
н ит эти параметры и сгенерирует у н и кал ь н ы й идентифи катор ком плекта (bundle
identifier) для вашего приложения. В ы также у видите поле Organization Name,
в которое можно в вести назван ие орган изаци и, которое програм ма Xcode бу­
дет испол ьзовать при автоматической вставке уведомления об авторском праве
в каждый создан н ы й вам и файл исходного кода. Н азовите наш п роект He l l o
Wo rld и введите в поля Organ ization Name и Organization ldentifier название вашей
организаци и и идентифи катор ком плекта, как показано на рис. 2.4. Не вводите
имя и идентифи катор, продемонстрированные на рис. 2 .4, потому что, когда вы
попытаетесь вы пол н ить свое приложение на реал ьном устройстве, вы должн ы
будете выбрать у н и кальный идентификатор .
Поле Lang uage предоставл яет вам возможность выбрать я з ы к программиро­
ван ия, на котором вы хотите работать, - Objective-C ил и Swift. Поскол ьку все
при меры в книге приведены на языке Swift, выбор очевиден.
Также нужно выбрать тип устройства в списке Devices . Иначе говоря, про­
грам ма Xcode должна знать, дл я какого типа устройств мы собираемся создать
приложение: дл я i Phone, i Pod Touch, i Pad или для всех устройств, работающих
под управлением операционной системы iOS. Выберите в раскры вающемся спис­
ке Devices пункт i Phone, есл и он не был в ыбран ранее. Теперь програм ма Xcode
будет знать, что мы будем разрабатывать приложение для устройств i Phone и
i Pod, имеющих примерно одинаковый размер экрана и формфактор. В первой
части книги мы будем испол ьзовать толь ко семейство устройств i Phone, но бес­
покоиться не следует - устройство i Pad тоже не будет забыто.
Оставьте флажок Саге Data сброшен н ы м - м ы вернемся к нему в главе 1 3 .
Флажки l nclude U nit Tests и l nclude U I Tests также оставьте сброше н н ы м и . В сре­
де Xcode существует м ного очен ь хороших инструментов для тестирования при­
ложений, но они выходят за рам ки нашей книги и в наших проектах мы не
будем их испол ьзовать. Еще раз щел кн ите на кнопке Next, и програм ма Xcode
предложит вам сохранить новый проект с помощью стандартного листа сохране­
ния, показанного на рис. 2 . 5 . Есл и вы еще не сохраняли проект, нажм ите кнопку
New Folder и создайте новы й главн ы й каталог для всех п роектов, рассматривае­
мых в нашей кн иге, а затем вернитесь в среду Xcode и перейдите в этот каталог.
ГЛАВА 2 »� П ЕР В О Е П РИЛОЖЕ Н И Е
41
Перед тем как щел кать на кнопке Create, убедитесь, что флажок Source Control
сброшен. М ы не будем обсуждать репозиторий G it в нашей книге, но програм­
ма Xcode обеспеч и вает определенную поддержку этого и других инструментов
контроля исходного кода (source contro l management
SCM). Есл и в ы уже зна­
ете, как работать с репозиторием G it, и хотите испол ьзовать его, оставьте этот
флажок установлен н ы м , в п ротивном случае можете его сбросить.
-
Choose options for your new project:
Product Name:
теаm:
Organlzation Name:
OrganlzatJon ldentlfl...
{
JHellO Wo� : :
Molly Maskre"
•
МollyМaskrey
r
1
: ::::: ::_ :J
Your now proclUct'• name г
в
com.mollymaskrey
Вundle ldentifier: con1.mollymaskrey.Hello-World
Language:
SWlft
Dellices:
IPhone
Use Core Data
lnclude Unlt Tests
lnclude UI Tests
Cancel
в
в
Previous �
-
Рис. 2 . 4 . В ы б о р и м е н и и иде нтифи катора ко м п а н и и для п роекта
Окно проекта в среде Xcode
После того как вы щел кнете на кнопке Save, програм ма Xcode создаст и от­
кроет ваш проект. В ы увидите новое окно проекта (proj ect window) (рис. 2 .6),
в котором содержится м ного и нформаци и . Именно в этом окне вы проведете
большую часть времени, разрабаты вая проект.
панель инструментов
Верхняя часть окна проекта Xcode назы вается панелью и н струментов
(toolbar) (рис. 2 . 7 ) . Слева на ней расположен ы элементы управления запуском
и остановкой процесса выпол нения вашего п роекта, и выпадающее меню для
выбора схемы, которую вы собираетес ь вы пол н ить. Схема (scheme) - зто со­
четание настроек целевого устройства и сборки, причем выпадающее меню по­
зволяет задать конкретн ый параметр легко и быстро.
42
ГЛАВА 2 tt: П Е Р В О Е П РИЛОЖЕН И Е
. EXAMPLES
<
Fa-itи
Q Searcl1
Date Modilied
Name
Recents
Slze
Klnd
ОrорЬох
d ICloud Drl".
А App6catio...
utlUtlea
!-' Oocuments
О Oownloeds
. Dnktop
8 Pk:turea
ф bnmasl<r
•••
QВJ.lght."
DolYIO••
r:I user'1 Ма ••
0 Remot& O
.•.
Source Control: С Create Glt reposltory on Му Мае
Xcod• w\11 place }'O<W project under ve<tloo control
New Folder
Cancel
Options
Create
Рис. 2 . 5 . Сохра н е н и е п роекта в п а п ке п рое кто в на жестко м диске
···--IJ
. -­
(lj
_ _,...
· -­
·­
.
1
1 ......
-
s--
·-·
--
--
- --
--
·._
" � ...... ·­
..
... -- ... .
� "'_..,
1
� '"""" � � "IAl ·::;J
...... �. �� .....,.. � (&.
D....<1 � 0 ...11"1
-­
e i--tll"I
o �-- 1119N
•
в
•
в
D О Ф fJ
•
!li .
Рис . 2 . б . П роект H e l l o Wo rld в с реде Xcode
ГЛАВА 2 � П ЕР В О Е П РИЛОЖЕ Н И Е
43
Инструментальная па нель
Рис . 2 . 7. П а н е л ь и н струме нтов среды Xcode
Большое поле в середине панел и инструментов называется п редставлением
действий (action v i ew). Как следует из этого названия, представление действий
отображает л юбые действия ил и процессы, которые протекают в данн ы й мо­
мент. Напри мер, при запуске проекта п редставление действий содержит ком­
ментарии, описы вающие разные этап ы сборки приложения . Кроме того, здесь
вы водятся все сообщения об ошибках и преду прежден и я . Есл и щел кнуть на
предупреждении ил и сообщении об ошибке, то можно немедленно оказаться в
навигаторе проблем, который выдаст более подробную информацию о предуп­
реждении или ошибке, как будет показано в следующем разделе.
Справа на панел и инструментов содержатся два набора кнопок. Первый на­
бор кнопок позволяет перекл ючаться между тремя раз н ы м и конфигурация м и
редактора.
"' Кнопка Editor Агеа откры вает окно, п редназ наченное для редактирован ия
файла ил и параметров конфигураци и п роекта.
t'�
Кнопка Assistant Ed itor разделяет область редактирован ия на нескол ько
частей: левую, правую, верхнюю и н ижнюю. Правое окно обыч но испол ь­
зуется для отображения файла, связанного с файлом, отображаем ы м в ле­
вом окне, ил и для отображения файла, который может понадобиться при
редактировании файла, отображаемого в левом окне. Пол ьзовател ь может
самостоятел ьно задать, что именно должно отображаться в каждом из этих
окон, ил и предоставить п рограм ме Xcode самой принять опти мальное ре­
шение. Напри мер, есл и вы редактируете пол ьзовател ьски й и нтерфейс в
левом окне, то програм ма Xcode автоматически покажет в правом окне
код, с которым может взаимодействовать этот и нтерфейс. Этот режим ре­
дактора мы будем испол ьзовать на протяжении всей книги .
Кнопка Version Editor переводит окно редактора в режим работы, напом и­
нающий утилиту Ti me Mach ine, которая работает с системам и управления
, исходны м кодом, таким и как G it. В ы можете сравни вать текущую версию
исходного файла с предыдущей версией или сравни вать любые две пред­
шествующие версии одну с другой.
Набор кнопок редактора, расположенных справа, предназначен для того, что­
бы отображать и скры вать панел ь навигатора, а также область отладки в левом
и правом окнах области редактора.
44
ГЛАВА 2 � П ЕР В О Е ПРИЛОЖ Е Н И Е
На вига тор
Н иже панел и инструментов в левой части окна проекта находится навига­
тор (Navigator), предусматри вающий восем ь конфигураци й, соответствующих
раз н ы м п редставлениям вашего проекта. Для того чтобы перекл ючаться между
раз н ы м и конфигурация м и, необходимо щел кнуть на одной из переч ислен н ых
н иже пиктограм м .
Vli
Навигатор п роекта ( Project Navigator). Это п редставление содержит спи­
сок файлов, испол ьзуемых ваш им проектом (рис. 2 . 8). В ы можете хранить
ссыл ки на что угодно - от файлов исходного кода до рисунков, моделей
данн ы х, файлов списков свойств ( . p l i s t ), которые рассматри ваются в
этой главе н иже, и даже файлов других проектов. Хранен ие нескол ьких
п роектов в одной и той же рабочей области облегчает совместное исполь­
зование ресурсов. Есл и щелкнуть на каком- н ибудь файле в представлении
нави гатора, то этот файл отобразится в окне редактора. В ы можете не
тол ько просматри вать содержимое этого файла, но и редактировать его,
есл и програм ма Xcode знает, как это сделать .
•
� App0eieglt•.8Wft
1� vi...controtкewtft
;..J Maln.•loryЬoad
l!ll Aeмt•.ICQallИt•
/О
PAOJECT
Gflnf
li НellO wc
TAl\OlmS
� LIUnc:ЬScre8n,�
"
'.:...J tnto.plllt
Ptoduct8
Навигатор проекта
Рис . 2 . 8 . Н а в и гатор п роекта Xcod e . Дл я того чтоб ы п е ­
ре йти в другой н а в и гато р , необходи м о щел кнуть на од­
н о й из восьм и к н о п о к в ве рхн е й части п редставл е н и я
;:;; Навигатор символов ( Symbol Nav i gator). Как следует из назван ия этого
нави гатора, он следит за символами, определен н ы м и в рабочей области
(рис. 2 .9). С и м вол ы - это объекты, которые распознаются компилятором ,
например класс ы, перечисления, струкrуры и глобал ьные перемен н ые.
ГЛАВА 2 ::i П ЕР В О Е П Р И Л ОЖЕ Н И Е
'"'dEll!M' Flat
• 11 Appl)el8g
ate
-� ---
111 appfic«ti onL:didFl1rllahLaunch 11a\Yit.
111 apptlcatJ onDldВecomeActlVe(..:)
Ш appllcatl onOfdEnt818ackground(..:)
1'11 appllcatlonWlllEntett:oreground(.:) 1
11 applJcatlonWНIRntgМctlve(.;)
•.
[]
45
Gooe
PROJECТ
/iв H ello Wo
ТАЯGЕТ$
1 . H ell o W
fermtnat ).:
11 applk;at/onWltfe(.
11 ndow
" 11 YlewConttoUer
llJ clc:IRecefVeM emotyWamlngQ
11 vtewOklf..oad()
Н а в игатор сим вол ов
Рис . 2 . 9 . Н а в и гато р с и м вол о в Xcod e . Дл я того
чтобы и сследовать файлы и с и м вол ы , о предел е н ­
н ы е в каждо й груп п е , н е о бходи м о щел к н уть н а
треугол ь н и ке раскрыти я
•1.,
·_,;,
Навигатор поиска (Search Nav igator). Испол ьзуется для поиска всех фай­
лов в рабочей области (рис. 2 . 1 О). В верхней части этого окна рас поло­
жен м ногоуровневый элемент у правления, позволяющий выбрать команду
Replace вместо Find и применить критерии поиска к в веден ному тексту.
Под полем редактирования находятся другие элементы управления, по­
зволяющие вы пол нять поиск по всему проекту ил и по его ч асти, а также
' указы вать, следует ли при поиске уч иты вать регистр.
Нави гатор п роблем ( l ssue N av i gator). В этом нави гаторе отображаются
все сообщения об ошибках и п редуп реждения, возни кающие при сборке
проекта, а сообщения, детал изирующие ошибки, вы водятся в представле­
нии действий, расположенном в верхней части экрана (рис. 2. 1 1 ) . Щелк­
нув на ош ибке в окне навигатора проблем, вы перейдете в соответствую­
щую строку кода в области редактирования .
46
ГЛАВА 2 №1 П ЕРВОЕ П РИЛОЖЕ Н И Е
?! Не/lо World )
e:i � Q. & 0 !fi c:> �
IPl>one &
88 1 <
OJ
> il
Pf!OJECТ
7 rautt. 1n 1 fllf
" � �t•.awm ке11о Wцttc1
i, . ..wi- 1118 u.r qu!UI 1118 �
8l'ld 11 Ьeglna lhe 1Nln8ltlon to thtt '
� -·...
Gene
tiJ Hello Wo
А Hollo World �
TAROEТS
А н.11о Wo
Ш tunc ��
{eppl:lcatlon UIAppl)lc:atjan (
:::. 11 11 your арр!1са11О/\ IUPPOf1a
-� execlitlon, lhl8 melhocl 1s
се118с1 � ol lljlpllcetlonWlll .••
:=. /1 C8lted " pert ofthe traмltJon trom
tho �nd to the lnlCll\le ttato:
het&youcanundo rмny of lh8 ."
,=. . " 1а you см llfldo mllf'IV of lhe
Ch8nQМ l!l8de on enterlng the
lif<;�
U!) . '.plle1ltloo "" Pf'Мou*ly \о lhe
� optjonalty 1'8!1'8111 t1м1
il
IJyl'ype
--·------�-.,.-=·
� н.llo Wortct 1 /aJUll
"
vieweonttoter�
О ConМCllUve ttattm
О11 а tм
rnult Ье eeperated Ьу ';'
.- tnt81face•
.::::. .•• l8tmlnat8. Seve d8ta lf approprlat..
s.. а11ю 8PPllcatlonDldEntet
�111-1:
Навигатор поиска
Рис. 2 . 1 О. Н а в и гато р п о иска Xcod e .
Дл я того чтобы в ы п ол н ить п о и с к , ус ­
тан о в ите флажки рядом с команда­
Навигатор проблем
Рис . 2 . 1 1 . Н а в и гатор п р о б л е м
Xco d e . Здесь в ы в одятся сообще н и я
об о ш и б ках и п редупрежде н и я
ми вспл ы вающих м е н ю , скрытых под
сл овом " Fi n d " и к н о п ка м и , распол о ­
жен н ы м и н иже п о л я п о и с ка
i!f
Навигатор тестирования (Test N av igator). Есл и вы используете средства
отладки, и нтегрированн ые в среду Xcode (эта тема в книге не рассмат­
ривается), то в этом окне появятся резул ьтаты модул ьного тестирован ия.
Поскольку мы не вкл ючили модул ьное тестирование в свой проект, это
окно остается пустым (рис. 2 . 1 2).
��
Нави гатор отладки ( Debug N av i gator) . Этот нави гатор п редставл я­
ет собой основной и нструмент отладки вашей п рограм м ы (рис. 2 . 1 3 ) .
Есл и в ы впервые сталки ваетес ь с процессом отладки, рекомендуем об­
ратиться к доку ментации Xcode Overv iew, распол ожен ной по адресу
h t t p s : / / deve l op e r . a p p l e . com/ l i b r a r y / p r e r e l e a s e / c o n t e n t /
d o c ume n t a t i o n / T o o l s L a n g u a g e s / C o n c e p t u a l / X c o d e Ove rv i e w /
ГЛАВА 2 1t П ЕР В О Е П Р ИЛОЖЕ Н И Е
47
U s i ngthe Debugge r . html . Нави гатор отладки содержит фрейм стека для
каждого акти вного потока. Фрейм стека (stack frame)
это с писок ранее
вызван н ы х функций ил и м етодов, переч исленных в порядке их вызова.
Щел кнув на методе, вы увидите в окне редактора связанн ы й с н и м код.
Окно редактора содержит панел ь, с помощью которой можно управлять
процессом отладки, выводить на экран и изменять значения переменн ых,
а также получать доступ к н изкоуровневому отл адч и ку. Кнопка, рас по­
ложен ная в н ижней части окна навигатора отладки, позволяет управлять
визуал изацией стека фрейма. Другая кнопка позволяет выбрать, следует
ли показы вать все потоки управления ил и только потоки, выполнение ко­
торых было аварийно прекращено ил и остановлено в точке преры вания .
Для того чтобы понять предназ начение каждой из этих кнопок, наведите
на них курсор м ы ш и и оставьте неподвижн ы м на некоторое время.
-
Cliclt t
Н авигатор тестирова ния
Рис . 2 . 1 2 .
Н а в и гат о р тести р о в а н и я
Xcod e . Здесь в ы водятся резул ьтаты м о ­
дул ьного тести рова н и я
48
ГЛАВА 2 ;�� П Е Р В О Е П РИЛОЖЕ Н И Е
•
1
2
з
1\
s
6
• Network
.- · Thr• 1 Q11eue: oom.app1e.li'illin·UI
. о 1'tello_VtIOt'kt.App[)lteoat1J.*P
"
8
:Z.Ю КВI•
d (80fta�
9
10
11
(..
f] 1 � Нell_o Woltd.App081egal8.applic
D 2 ·(U\Al>J)lloatJon _hмdl.OlloQateeaUЬL
D З ·(UIAppllcatJo n _callli'\ltla llt.atlol\Del-o,a
D 4 ·tulAН/lcltlon .n.mWitllмatnSeeм:tra.
D S ·(UIAppllc atlo n �aceDld&drrana
� в ·{FВSSerialQueue _petformNext)
� 7 -{FBSSefialOueue .,petfonnNextFromR
g e _CFRUNLOOP.I S.CAШNG�ouт_"o. "
ll 9 _CFAunLoopDoSourcetlO
ll 10 _CFAWILoopRun
11 1.1 CFRunl.oopRunSpeflc
cl
rJ 12 ·(ШAppllcatlon ..Nn]
r:J 13 UIApplJcatlont.4aln
rJ 14 maln
1D 15 Wlrt
в 1 6 81art
••.
••
•••
•.
. •.
.••
Тh...ad 2 �: c:om.appl •.• h-manager fserlal)
"
Thfl08d з
"
Тhread 4
"
1>
-
6
-
•·
Тhroad 5
- - ------ --------
- -
%8�
·----�--·-- ----·-·- - ·-· ---
�
Рис. 2. 1 3 . Н а в и гатор отладки Xcode . Эл е ­
м е нт ы у п р а вл е н и я в н и ж н е й ч а ст и о к н а
п о з в ол я ют оп редел ить урове н ь детал и з а ­
ци и и н фо р м а ц и и об отладке , которую в ы
хотите видеть
ГЛАВА 2 '" П Е Р В О Е П Р И Л ОЖЕ Н И Е
•t;
49
Навигатор точек п рерывания ( B reakpoint N av igator) п озволяет увидеть
все установленные вам и точ ки п реры ван ия (рис. 2 . 1 4). Как следует из
названия, точ кам и прерыван ия назы ваются точки, в которых вы пол нение
кода останавл и вается ( п рерывается), чтобы вы могл и у видеть значения
перемен ных и вы пол н ить другие действия, необходи м ы е для отладки про­
грам м ы . С п исок точек преры ван ия в навигаторе связан с содержим ы м ис­
ходного файла. Щелкните на точ ке прер ы вания в списке, и в окне редак­
тора будет выделена соответствующая строка кода. Не забудьте щел кнуть
на кнопке + в левом н ижнем углу окна проекта при работе с навигатором
преры ван и й . Эта кнопка позволяет добавлять исключения четырех типов,
вкл ючая сим вол ьное, которое испол ьзуется чаще всего.
На в и гатор точе к п реры в а н ия
Н8f1о Wottd
... _!) �tt.twm
•cldF11'118ht.aunoh
IJ cppUca
+ 1 _.__._._,... ___"
•••
--··
IJNt 10
---�
0!
Aut
Рис. 2 . 1 4 . Н а в и гатор п р е р ы ва н и й Xcod e .
С п и сок точ е к п р е р ы в а н и я связан с соде р ­
жи м ы м исходн ого файла
•:'l
Нави гатор отчетов ( Report N av igator). Сохраняет историю предыдущих
сборок и попыток выпол нения приложения (рис. 2 . 1 5 ) . Щел кн ите на кон­
кретном журнале, и на панел и редактирования отобразятся команда сбор­
ки и вся связан ная с эти м информация.
50
ГЛАВА 2 lil П Е Р В О Е П РИЛОЖЕ Н И Е
"
11
1�......."""...""".....,. а
�
1
"' Е
Навигатор точек прерывания
$ ....._.
_
_
_
(9
_
CJ
_
_
J
Aut
Рис. 2 . 1 5 . Н а в и гатор отч етов Xcod e . Н а в и га­
тор отчетов в ы водит с п и с ки сборок , а также
детал и , с в я за н н ы е с в ы б р а н н ы м п р едста в ­
л е н и е м , отоб ражае м ы м на панели редактора
па нель быстрого переход а
Панель быстрого перехода (jump bar), расположенная в верхней части об­
ласти редактирования, позволяет одн и м щелч ком м ы ш ью перейти к конкретно­
му элеменrу в иерархии, по которой вы перемещаетесь в дан н ы й момент. На­
пример, на рис. 2 . 1 6 показан исходный файл, редактируем ы й в окне редактора.
Рис. 2 . 1 6 . Окно редактора Xcode с панелью б ы строго п е р ехода и выбра н н ы м
фа й л о м и сход н о го кода . В п одм е н ю п о казан сп и с о к м етодо в в в ы б ра н н о м
файле
ГЛАВА 2 111 П Е Р В О Е П РИ Л ОЖЕН И Е
51
Панель быстрого перехода появляется сразу над исходны м кодом . Покажем,
как она работает.
m;
Причудл и вая п и ктограм ма в левом кон це панел и быстрого перехода на
самом деле я вляется вспл ы вающим меню, откры вающим подменю, в кото­
ром переч ислены недавно откры вавшиеся файл ы, эквиваленты, суперклас­
сы и подклассы, категории, вкл ючения и т.д. Подменю позволяет открыть
любой код, связан н ы й с редактируем ы м кодом .
Справа от необычного меню расположен ы стрел ки, нап равленные влево
и вправо, которые позволяют переходить к предыдущему и следующему
файлам соответственно.
,,, Панел ь быстрого перехода содержит сегментированное вспл ы вающее
меню, отображающее иерархический путь к выбран ному файлу в проекте.
Щел кнув на л юбом имени группы ил и файла, можно увидеть другие фай­
лы и группы, расположенные на том же уровне иерархии. Последни й сег­
мент демонстрирует список элементов, содержащихся в выбранном файле.
В конце панел и быстрого перехода (рис. 2 . 1 6) расположено всплы вающее
меню, в котором переч исляются методы и другие символ ы, содержащие­
ся в файле, выделенном в дан н ы й момент. На панел и быстрого перехода
показан файл AppDe l egate . swi ft с подменю, содержащем список сим­
волов, определенных в этом файле.
С помощью панел и быстрого перехода можно перемещаться по разным эле­
ментам интерфейса среды Xcode.
ЗАМ ЕЧАН И Е . Как и бол ьши нство п риложе н и й дл я macO S , среда Xcode поддерживает
полноэкра н н ы й режи м . П росто щел кните на кнопке перехода в полноэкра н н ы й ре ­
жим , расположенной в правом верхнем углу окна п роекта , и попробуйте испытать
преимущества пол ноэкранного кодирован и я !
Комбинации клавиш XCODE
Если вы предпочитаете перемещаться по элементам и нтерфейса не с помощью
мыши , а используя комбинации клавиш , то среда Xcode вам понравится . Большин­
ство действий , которые вы можете регулярно выполнять в среде Xcode , имеют назна­
ченные им стандартные комбинации клави ш , например комбинация клавиш < Х+В>
вы � олняет сборку приложения, а комбинация клавиш < X + N > создает новый файл .
Вы можете изменить назначенные комбинации клавиш и задать собственные, кото­
рых нет среди стандартн ых комбинаци й , перечисленных на вкладке Кеу Binding .
Действительно удобной является комбинация <Shift+X+O>, выполняющая команды
быстрого открытия файла. Нажав ее, наберите имя файла, настройки или символа ,
и среда Xcode откроет список параметров . Когда вы сузите список до файла, кото­
рый вам нуже н , нажмите клавишу < Return >
и откроется панель редактирования.
Таким образом , вы сможете открыть файл всего нескольким и нажатия м и клави ш .
-
52
ГЛАВА 2 1 -1 П Е Р В О Е П Р И Л ОЖЕ Н И Е
Вс помога тельна я обла сть
Как указы валось ранее, предпоследняя кноп ка в правой части панели инстру­
ментов программ ы Xcode открывает и закры вает область утил ит. Подобно инс­
пектору, вспомогательная область я вляется контекстно-чувствител ьной и зависит
от содержимого панел и редактора. Примеры ее использования мы еще встретим
в книге.
Прогр а мма lnterface Builder
П редыдущие верс и и п рограм м ы Xcode включал и инструмент для разработки
и нтерфейса под названием "lnterface Builder" (IB), позволявший разрабаты вать
и настраи вать собственный пользовател ьский и нтерфейс. Одно из основных из­
менений в последних версиях програм м ы Xcode закл ючается в интеграци и ком­
понента I nterface B u i lder с самой рабочей областью. П рограм ма l nterface Bui lder
больше не я вляется самостоятел ьным приложением, т.е. пол ьзовател ю теперь не
приходится метаться между Xcode и l nterface B u i lder при разработке своего кода
и и нтерфейса.
Мы будем ш и ро ко испол ьзовать фун кциональную возможность разработки
интерфейса, которой обладает среда Xcode, загляды вая во все ее потаенные мес­
та. Фактически первая програм ма, которую мы нап и шем нем ного позднее в этой
главе, будет закл ючаться и менно в создан и и пол ьзовател ьского интерфейса.
Интегриров а нный компилятор и отладчик
Одни из наиболее важных изменений в програм ме Xcode 4 скрыты от посто­
ронних глаз: это принципиально новы й ком п илятор и низкоуровневы й отладч ик.
М ногие годы ком пания Apple использовала в качестве основного ком п илятор
GCC (GN U Cotnpi ler Col lectio11 ) . Однако в последн ие нескол ько лет ком пания
перешла на совершенно новый ком п илятор LLV M ( Low Level Virtual Mach ine),
которы й генерирует код, работающий быстрее, чем код, генерируемый компи­
лятором G C C . Ком п илятор LLV M не тол ько создает более быстрый код, но и
обладает более пол ной информацией о нем и поэтому может генери ровать более
содержател ьные сообщения об ошибках и предупреждения.
С реда Xcode тесно интегрирована с ком п илятором L LV M . Это обстоятел ьство
открывает ш и рокие возможности. В частности, среда Xcode также обеспеч ивает
более точ ное автодопол нение кода и может делать обоснован ные предположе­
н и я о реал ь ном п редназначен и и того или и ного фрагмента кода при генери­
рован и и предупреждений, откры вая при этом вспл ы вающее меню, содержащее
средства для исправления ошибок. Благодаря этому обнаружи вать и исправлять
такие ошибки, как опечатки в и менах сим волов, нарушение баланса скобок и
пропущенные точки с запяты ми, стало очень просто.
Ком п илятор L LV M содержит сложн ы й стати чески й анализатор (static
aпa l i zer), способ н ы й с ка н и ровать код в поисках разл и ч ных потен циал ь н ы х
проблем, включая проблем ы, связан ные с управлением памятью. Фактически
ком п ил ятор L LV M настол ько совершенен, что может самостоятел ьно решать
ГЛАВА 2 "� П ЕР В О Е ПР ИЛ ОЖЕ Н И Е
53
большинство задач управления пам ятью на основе простых правил, есл и при
нап исан и и кода вы будете соблюдать нескол ько п ростых п равил . Новый меха­
н изм автоматического подсчета ссылок (Automatic Reference Counting - A RC)
будет рассмотрен в следующей главе.
П р и с туп и м к п рое кту Hello World
Итак, изучив окно рабочей области Xcode, взгля нем на файл ы, образующие
проект He l l o World. Перекл юч имся в нави гатор проекта, щел кнув на крайней
слева пиктограм ме среди восьми пиктограм м нави гаторов, расположенных в ле­
вой части рабочей области (с м . раздел "П редставление навигаторов"), или на­
жав комбинацию клавиш <X+ I > .
ЗАМЕЧАНИЕ. Восемь конфигураций навигаторов можно открыть с помощью комбинаци й
клавиш < Х + 1 > - < Х + 8 > . Ч исла соответствуют номерам п и ктогра м м , считая слева н а ­
право , т а к ч т о комбинация < Х + 1 > соответствует пиктограмме навигатора проекта , а
< Х+8>
навигатору отчето в .
-
Первы й элемент в списке нави гатора проекта должен иметь такое же имя, как
и проект, в данном случае
He l l o W o r l d . Этот элемент представляет собой
весь проект, а также место для настройки его конфигураци и . Щел кнув на нем
один раз, вы сможете редактировать м ногоч ислен ные параметры конфигураци и
проекта с помощью редактора программы Xcode. Однако кон кретные параметры
конфигурации нас пока не будут и нтересовать. Нас в пол не устроят параметры,
установленные по умол чанию.
Взгляните на рис. 2 . 8 и обратите в н и мание на то, что треугольник раскрытия
слева от папки He l l o Wo r l d направлен вниз и у этой папки есть несколько вло­
женных папок, которые в среде Xcode назы ваются группой (group).
-
�
это первая груп па, которая всегда носит название
проекта. С ней вы будете работать м ного време н и . Именно здесь будет
хран иться бол ьшая часть написанного вам и кода в виде файлов, образу­
ющих пол ьзовател ьский и нтерфейс приложения. Вы можете создать вло­
женные папки в папке He l l o Wor l d, чтобы лучше организовать свою про­
грам му, и даже испол ьзовать другие группы, есл и предпочитаете другой
способ орган изации проекта. Хотя мы не план ируем касаться этих файлов,
пока не перейдем к следующей главе, оди н из них мы все же о п и шем в
следующем разделе, когда будем говорить о программе lnterface B u i l der.
Этот файл назы вается Main.storyboard и содержит элементы пол ьзова­
тел ьского и нтерфейса, относящиеся к контроллеру главного представле­
ния вашего проекта. Группа Hello World также содержит файлы и ресурсы,
не явля ющиеся исходным кодом на языке Swift, но необходимые для про­
екта. В частности, таким файлом я вляется файл I n fo . p l i s t, содержащий
важную и нформацию о приложении, например его название, требования к
Папка Hello World
-
54
ГЛАВА 2 � П ЕР В О Е П Р И Л ОЖЕ Н И Е
устройствам и т.д. В более ранн их версиях среды Xcode эти файл ы разме­
щались в отдел ьной гру п пе под названием Supporting Files.
%tl
Папка Hello WorldTests. Эта группа п редназначена для модул ьного тес­
тирования проекта (напом и наем, что в нашем проекте модульное тестиро­
вание не п редусмотрено). Она содержит файл ы , необходимые для созда­
ния модульных тестов для вашего приложения. В этой книге модул ьное
тестирование не расс матри вается, но это не знач ит, что оно бесполезно.
Это превосход н ы й инструмент, которы й необходим для любого проекта.
Как и в папке He l l o wo r l d, в папке He l l o Wo rdl t e s t s содержится свой
файл I n fo . p l i s t .
'N
Пап ка Prod ucts . Эта гру п па содержит п р иложение, которое создается
проектом во время комп иляци и . Если вы откроете файл Produc t s , то уви­
дите элемент He l l o Wo r l d . арр. Это приложение, которое создал дан ный
проект. Есл и п роект был создан при включен ном модул ьном тестирова­
нии, то пап ка P roduc t s будет также содержать файл He l l o Wo rldTe s t s .
xcte s t, представляющий тестовый код. Оба эти файла назы ваются целя­
ми сборки (build target). В дан н ы й момент и мена этих файлов выделены
красным цветом, потому что мы их еще не ком пилировал и . Выделяя имя
файла красным цветом, програм ма Xcode сообщает нам, что она не может
найти указанн ы й файл .
ЗАМ ЕЧАНИЕ. Папки в области нави гатора не обязател ьно соответствуют папкам файло­
вой системы вашего ком пьютера Мае . Они представляют собой логические группы в
среде Xcode , помогающие организовать файл ы , а также ускорить и облегч ить их поиск
при работе над приложением . Довольно часто элементы , содержащиеся в двух папках
проекта , хранятся прямо в корневом каталоге , хотя вы можете хранить их где угодно,
даже за п ределами папки п роекта . Иерархия в среде Xcode совершенно не зависит
от иерархии файловой систе м ы . Н апример, перемещая файл из группы He l l o Wo r l d
в среде Xcod e , вы не изменяете его физического расположе н и я на жестком диске.
В ведение в п рогра м м у l nterface Builder
Зайдите в навигатор п роекта вашей рабочей области, раскройте группу Hel­
lo World, есл и она еще не открыта, а затем выберите файл Ma i n . s t o ryboa rd.
В резул ьтате в окне редактора откроется файл (рис. 2 . 1 7). В центре вы увидите
область, напом инающую контур устройства iOS, которая очень удобна для ре­
дактирован и я и нтерфейса. Это и есть ком понент среды Xcode под названием
l nterface B u i lder, с помощью которого разрабатываются пол ьзовател ьские интер­
фейсы приложений.
Програ м м а I nterface B u i lder и м еет дол гую историю. Она поя вилась в
1 988 году и использовалась для разработки приложе н и й для операционных сис­
тем NeXTSTEP, OpenSTEP и macOS, а теперь и для устройств, работающих под
управлен ием системы iOS, таких как i Phone, i Pad, AppleTV и Apple Watch .
ГЛАВА 2 fl'. П ЕРВОЕ П РИЛОЖЕ Н И Е
55
Ф орматы файлов
Програм ма l nterface Bui lder поддержи вает два типа файлов: стары й формат,
испол ьзующий расширение . n ib, и новы й ХМ L-формат, который испол ьзует
расширение . x i b . Оба эти формата содержат одну и ту же информацию, но
версия . xib я вляется текстовой, что дает ей множество преимуществ, особен­
но при использовании программного обеспечения для контроля исходного кода.
На протяжении более двадцати лет существования програм м ы I nterface B u i lder
все ее и нтерфейсные файл ы и мел и расширение . nib, и в резул ьтате бол ьшин­
ство разработчи ков по привычке наз ывают их niЬ-файлами независимо от их
реал ьного расширения - . xib ил и . nib. Сама компания Арр\е в своей доку­
ментаци и испол ьзует терм и н ы nib и niЬ-файл.
-
-­
. �-""'"
• ._Jt c--4•
.___
-
.
--
0::-LWf'llll �$ �." �
�� �\IOUI Clu-
1 .... ...
Nfl 0J:c� Ht>1p
- --
.['). .
' iliOfYl)O..-c\l••...., Pootit
ll
'!'· ."
19
•
11 G1 n
·��- - ,..,,.···
... "
� - · - (""'-""'
...,. _.,......,.
Рис. 2 . 1 7 . В ы б ра в файл Ma i n . s t o r ybo a r d в н а в и гаторе п ро е кта , можно от­
крыть файл в п рограм м е l nterface B u i l d e r
Каждый niЬ-файл может содержать л юбое кол ичество объектов, но при ра­
боте с проектам и для системы iOS, он обычно содержит только одно представ­
ление (часто пол ноэкранное) и контроллеры или другие объекты, связан ные с
представлением. Это позволяет разделить приложения на части, загружая n i Ь­
файл только для того представления, которое требуется для вы вода на экран .
В резул ьтате м ы эконом им память при вы полнении приложения на устройстве
IOS с огран иченной памятью. Вновь созданн ы й проект для системы iOS содер­
жит niЬ-файл с именем LaunchS creen . x ib, содержащи й макет экрана, который
56
ГЛАВА 2 ;;• П ЕР В О Е П Р И ЛОЖЕ Н И Е
будет демонстрироваться по умол чанию п р и запуске приложения. О б этом м ы
подробнее поговорим в конце главы .
Второй формат файлов, который програм ма l nterface B u i lder поддержи вает
уже несколько лет,
раскадровка (storyboard). Раскадровку можно и нтерпре­
тировать как расширенн ы й n i Ь-файл, потому что она содержит нескол ько конт­
роллеров представления, а также и нформаци ю о том, как каждое из них связано
с другим и в ходе выпош1ен ия приложения . В отл и ч ие от n iЬ-файла, содержимое
которого загружается цел иком и сразу, раскадровка не может содержать изолиро­
ван ных представлени й и ни когда не загружает все их содержимое одновременно.
Все шаблон н ые проекты в среде Xcode 8 испол ьзуют раскадровки, поэтому все
при меры в книге начинаются именно с них. Рас кадровки можно испол ьзовать
по одной ил и сразу нескол ько. Вернемся к программе l nterface Bui lder и файлу
Ma i n . s t o ryboa rd для приложения Hello World (см . рис. 2 . 1 7).
-
Рас кадров ка
Рассмотри м основной инструмент для создания пол ьзовател ьских и нтерфей­
сов для приложен и й в системе i O S . Теперь допустим , что мы хотим создать
экзе м пляр кнопки. Его можно создать, нап исав код, но создать кноп ку, просто
перетащи в объект из библ иотеки и указав ее атрибуты , нам ного проще, а ре­
зул ьтат будет тот же сам ы й .
Файл Ma i n . s t o ryboard загружается автоматически п р и запуске приложения
(пока неважно, как и менно), поэтому именно в него следует поместить объек­
ты пол ьзовател ьского интерфейса вашего приложения. Когда вы создаете объек­
ты пользовательского интерфейса в програм ме I 11terface Bui lder, они возни кают
в вашей програм ме в тот момент, когда загружается добавлен ная вам и раскад­
ровка ил и n i Ь-файл . На протяжении нашего изложения м ы будем часто встре­
чаться с примерами этого процесса.
Каждая раскадровка состоит из одного или нескол ьких контроллеров пред­
ставления (v iew co11trol lers), причем кажды й контроллер представления имеет
по крайней мере одно представление (v iew). Представление - это графический
элемент, который можно видеть и редактировать в программе I nterface B u i lder, а
контроллер - это код приложения, которы й вы должн ы написать, чтобы прило­
жение реагировало на действия пол ьзователя . И менно контроллеры вы пол няют
реал ьные действия вашего приложения.
В програм ме l nterface B u i lder представление часто изображается в виде пря­
моугол ьника, им итирующего экран устройства iOS (на самом деле пря моугол ь­
н и к соответствует контроллеру представления, кон цепцию которого мы оп ишем
в следующей главе, но в дан ном конкретном случае контроллер представле­
ния охваты вает вес ь экран устройства, поэтому на такие тон кости можно не
обращать внимания). В н ижней части окна I nterface B u i lder рас положен рас­
кры вающийся элемент управления View as:, в котором указан тип устройства
по умолчан ию. Он позволяет выбрать устройство, для которого вы собираетесь
разработать макет экрана, как показано на рис. 2 . 1 8 .
ГЛАВА 2 �• П ЕР В О Е П РИЛОЖЕ Н И Е
1О
-
View as: iPhone 6s (·" С t>R)
- -
-
-
�
-
100%
+
57
1В fQj fAi
D D o o o o 11 О о
Otrvice
Otientatton
Рис. 2 . 1 8 . В п рогра м м е l nterface B u i l d e r среды Xcode 8 м ожно в ы брать т и п
у стройства и е го о р и е нтаци ю
Вернувшись в разметку, щел кн ите в л юбом месте макета - и вы увидите в
верхней части ряд из трех п и ктограм м (см . рис. 2 . 1 7). Наведите на них курсор
мыши - и поя вятся подсказки с их и менам и : View Controller, First Responder и
Exit. Пока не будем обращать внимание на п и ктограм му Exit и сосредоточи мся
на пиктограм мах View Controller и First Responder.
;.;, П и ктограмма View Controller представляет собой объект, загружающийся
из файла, связанного с п редставлен ием . Задача этой п и ктограм м ы - уп­
равлять тем, что пол ьзовател ь видит на э кране. Тип и ч ное приложе н ие
имеет нескол ько контроллеров представления, по одному для каждого эк­
рана. Разумеется, можно написать приложение с одн и м экраном, а знач ит,
с одни м контроллером представления, и м ы увидим в книге м ного таких
примеров .
.'ii
П и ктограмма First Responder
это, в общих чертах, объект, с которым
пользовател ь взаимодействует в дан н ы й момент. Есл и , напри мер, пол ь­
зовател ь в текущий момент в водит дан н ы е в поле редактирования, то
это поле я вляется первым реагирующим объектом . П р и взаимодействи и
пол ьзователя с и нтерфейсом перв ы й реагирующий объект изменяется и
п и ктограмма First Responder п редоставляет удобную возможность для об­
мена информацией с элементом управления или представлением, которое
в дан н ы й момент я вляется первы м реаги рующи м объектом и не создает
-
ДЛ Я ЭТО ГО КОД.
М ы обсудим эти объекты в следующей главе, поэтому пока не стоит беспо­
коиться о том, что их предназначен ие вам не совсем понятно.
Кроме этих п и ктограм м , область редактирования содержит пространство, на
которо'м можно размещать графические объекты . Однако, п режде чем мы пе­
рейдем к нему, отметим еще одно важное обстоятел ьство, касающееся области
редактирован ия, - иерархическое представление, или, точнее окно Document
outline, которое показано на рис. 2 . 1 9 .
58
ГЛАВА 2 tii П ЕР В О Е П РИЛОЖЕН И Е
ЕЕ i <
) , 19 Hello Wofld > U H�lo Wortd )
У IJ Vlew ContlOUll' Sctne
W.w Contlol tr
!Е[ тор Layout Gulde
fg; Вottom Layout G
[i view
• ..
$ Fl�t Ro11pondor
B Exlt
> StoryЬoard Entry Point
Окно Document Outline
Рис. 2 . 1 9 . Окно Document Outline соде ржит
п ол е з н о е и е р а р х и ч е с к о е п р едста вл е н и е
раскадровки
Если окно Document Outline скрыто, щел кните на маленькой кнопке в левом
н ижнем углу области редактирования. В открывшемся окне вы увидите содер­
жимое раскадровки, разделенное на сцены (scenes), содержащие фрагменты
связанного контента. В данном случае вы увидите всего одну сцену с именем
View Controller Scene. Она содержит элемент с именем View Controller, которы й,
в свою очередь, содержит элемент с именем View (а также другие элементы,
которые мы опишем позже). Это позволяет получить пол н ы й обзор элементов,
содержащихся в области редактирования .
Пиктограм ма View является объектом класса U IView. Объект класса U IView это область, которую видит и с которой взаимодействует пользователь. Позднее
мы будем разрабатывать более сложные приложения, и меющие нескол ько пред­
ставлений, а пока просто представьте себе, что это то, что видит пользовател ь,
когда работает с ваш и м приложением.
Если щелкнуть на пиктограмме View, то откроется окно, размер которого соот­
ветствует размеру экрана устройства iPhone (если это окно не было открыто ранее).
В этом окне вы можете графически разрабатывать пол ьзовательский интерфейс.
В спомогательная область
Вспомогател ьная область занимает правую часть рабочей области. Если она
еще не открыта, то щел кните на крайней справа кнопке View инструментальной
п анели, выберите команду Viewc::> Utilities c::> Show Util ities или нажм ите комби на­
цию клави ш <Optio11+X+O> (optio11-comma11d-zero). Н ижняя часть вспомогател ь­
ной области назы вается панелью библиотеки ( l ibrary pane) ил и просто библио­
текой ( l ibrary) (рис. 2 .20).
ГЛАВА 2 G
r
П ЕР В О Е П РИЛОЖЕ Н И Е
[:)
(}
59
@ []
Vl8W Contro
• A CO(ltmler
thet menages 1 Ylew.
-- --- ------
' StOl')IЬNrd � ; : Provldes а placeholdel tor 11 vlew
,·-:�"'· �ntto11tr ln an extemal atoryЬo " .
" ,
Nawlga tlorl Cantrol r · А
controtl« that manages navigatJon
t!Youg11 а hler&rcby of vill'N!I.
�- V.W Controller · А
controll« that manage& 11 tabl&
Ylew .
•
.
,
Библиотека
Рис . 2 . 20 . Б и бл и отека - это м е сто хра н е ·
н и я объектов и з ка р каса U I К i t , доступ ного
дл я и с п ол ьзо в а н и я в п ро г ра м м е l nte rfac e
B u i ld e r. Все , что расп ол оже н о в ы ш е би бл и о ­
те ки , н о н иже и н струме нтал ь н о й п ан ел и , на ­
з ы вается и н сп е кто ром
Библ иотека - это коллекция повторно испол ьзуе м ы х элементов, которые
можно испол ьзовать в програм ме. Четыре п и ктограм м ы на панел и, расположен­
ной вверху панел и библиотеки, соответствуют четырем разделам библ иотеки .
il!I
Библиотека файловых шаблонов (File Template Library). Этот раздел
содержит коллекцию файловых шаблонов, которые можно испол ьзовать,
когда необходимо добавить в проект новы й файл . Например, есл и вы хо­
тите
добавить в п роект новы й класс из языка Swift, перетащите в него
,
файл класса, который находится в библ иотеке файловых шаблонов.
i:1
�''
Библиотека сниппетов кода (Code Snippet Library). В этом разделе хра­
нится коллекция сниппетов кода, которые можно перетаскивать в свой ис­
ходный файл . Если вы не можете вспомн ить си нтаксис быстрого перечис­
ления в языке Swift, то просто перетащите нужны й сниппет из библ иотеки.
Библиотека объектов (Object Library). Этот раздел запол нен повторно
используемыми объектам и, например пол я м и редактирования, ползунками,
60
ГЛАВА 2 !ii! П Е Р В О Е П Р И Л ОЖ Е Н И Е
кноп кам и и просто л юбы м и объектами, которые в ы хотите испол ьзовать
при разработке своего пол ьзовател ьского интерфейса для системы iOS. М ы
будем и нтенсивно испол ьзовать библиотеку объектов на протяжении всей
книги для разработки и нтерфейсов наших илл юстрати вных прогrам м .
;:;;: Библиотека мульти медиа (Media Library). Как следует и з этого назва­
ния, здесь хранятся все медиафайл ы, вкл ючая изображения, звуковые фай­
лы и фильм ы .
ЗАМ ЕЧАН И Е . Элементы библиотеки объектов в основном извлекаются и з каркаса IOS,
представл яющего собой каркас объектов, испол ьзуемых дл я создания пользовател ь­
ского и нтерфейса приложе н и й . Каркас U I Кit и грает в среде Сосоа To uch такую же
рол ь, как каркас AppКit в среде Сосоа . Эти два каркаса принци пиально похожи , но из­
за различий между платформами между н и м и существует бол ьшое различие. С дру­
гой стороны , классы каркаса Fou пdation , такие как N S S t r i ng и NSAr r a y , явля ются
общи м и для каркасов Сосоа и Сосоа Touch .
Обратите внимание на поле поиска, расположенное в н ижней части библ ио­
теки . Вы хотите найти кно п ку? Наберите в поле поиска слово b u t t o n, и те­
кущая библ иотека покажет вам толь ко объекты, в и менах которых есть слово
but t o n . Когда закончите поиск, не забудьте очистить поле поиска.
Добавление метки на представление
Исп ытаем програм му l nterface Bui lder. Щел кн ите на п и ктограмме библиотеки
объектов (она выглядит как круг с в п исан н ы м квадратом ) в верхней части па­
нел и библ иотеки (рис. 2.20). Теперь просмотрите библиотеку в поисках объекта
ТаЫе View. Для этого можете прокрутить содержимое окна, но есть более эф­
фективное средство - наберите слова ТаЫе View в поле поиска.
СОВЕТ. Для перехода в поле поиска есть удобная комбинация клавиш - < "+Option+X+З > .
После этого достаточ но ввести в поле поиска и м я искомого объекта .
Найдите в библиотеке объект Label. Он должен находиться в верхней части
списка. Перетащите метку на представление, которое вы открыл и ранее. (Есл и
вы не видите это п редставление на панел и редактирования, щел кните на п и к­
тограмме View в окне Document Out l i ne в програм ме l пterface Bui lder.) Как тол ь­
ко курсор поя вится на представлен ии, отобразится стандартн ы й зелен ы й знак
"пл юс", которы й вам должен быть известен по работе с окном Finder и который
означает копирование. Перетащите кнопку в центр представлен ия. Когда будете
центрировать метку, на э кране поя вятся голубые вертикал ьная и горизонтальная
л и н и и . То, что м етка центри руется, не важно, но важно знать, что эти л и н и и
существуют. На рис. 2.2 1 показана рабочая область непосредственно после того,
как вы отпустил и кнопку м ы ш и .
ГЛАВА 2 � П Е Р В О Е П Р ИЛОЖЕ Н И Е
61
т 8 Vlew Controller Scene
""
Vlew Controllor
[jJ Т<>1> Loyoul Guide
О Bottom Layout Gulde
• [J! Vlow
IIJLIЬel
"
С1 Ffr1t Rotpondar
\! E•ll
StoryЬo1rd Entry POint
1
1
1
l
[)
- ., '"""' " '·' ."
[D D°"g o_o o ! �о
100%
+
17!!1 18 faj f<>! i
Vary lor т","
J
Рис . 2 . 2 1 . М ы н а шл и м етку в б и бл и отеке и п еретащили ее на п р едставл е н и е
Объе кты пол ьзовател ьского и нтерфейса я вл я ются иерархически м и . Бол ь­
ши нство представлений могут содержать дочерние п редставлен и я (subv iew),
хотя некоторые объекты, такие как кнопки и бол ь ш и нство других элементов
управления, не имеют дочерних представлен и й . П рограм ма l 11terface Bui lder ор­
ганизована разумно. Есл и объект не имеет дочерних представлений, то на него
нельзя перетаски вать другие объекты.
Добавим нашу метку на главное представление ( которое назы вается View).
В ре�л ьтате перетаски вания метки из библ иотеки на представление View в глав­
ное представление добавляется нов ы й объект класса U I Labe l , я вляющийся до­
черним представлен ием .
Давайте отредактируем метку, чтобы она сообщала что-то полезное. Дважды
щел кн ите на тол ько что создан ной метке и наберите текст He l l o , Wo r l d ! За­
тем щел кните на экране за пределам и метки, выберите ее снова и перетащите в
центр ил и в ту часть э крана, где хотите ее видеть.
62
ГЛАВА 2 w П ЕР В О Е П РИЛОЖЕН И Е
Как тол ько вы сохраните файл, работа будет завершена. Выберите коман­
ду Fileq Save ил и нажм ите комби нацию клавиш <X +S>. Зате м щел кн ите на
вспл ы вающем меню, расположенном в левом верхнем углу окна проекта Xcode.
По существу, это м ногосегментны й вспл ы вающи й элемент управлен и я . В его
левой части можно выбрать одну из м ногих целей ком пиляци и и еще несколько
важных аспектов, но нас в дан н ы й момент бол ьше и нтересует его правая часть,
позволя ющая выбрать устройство, для которого предназначено приложение.
Щел кн ите на правой части меню - и увидите список доступных устройств.
Есл и к вашему ком п ь ютеру подкл ючено какое-нибудь устройство iOS, то вы
увидите его в списке. В п ротивном случае вы увидите обобщенный пункт IOS
Divide. Под ним расположен раздел с заглавием IOS Simulator, в котором пере­
числены все виды устройств, предусмотрен ны х в си муляторе iOS. В ыберите в
последнем разделе пункт i Phone 6/6s, чтобы наше приложение было настроено
на устройство i Phone 6/бs.
Существует нескол ько с пособов запустить приложение. Напри мер, можно
выбрать команду Productq Run ил и нажать комби нацию клавиш <3€+R> ил и
щел кнуть на кнопке Run, расположенной слева от вспл ы вающего меню си муля­
тора. Среда Xcode ском п илирует наше приложение и запустит его в симуляторе
устройства i Phone, как показано на рис. 2.22.
!J» (jl ,_
Carr"" ?
l\1tlone 6f ·JOS 10!_���
1:21 РМ
-
Hello, World!
Рис . 2 . 2 2 . П рограм м а H e l l o World
н а устройстве i Ph o n e
ГЛАВА 2 � П ЕР В О Е П РИЛОЖ Е Н И Е
63
ЗАМЕЧАНИЕ. До появления с реды Xcode 8 текст не центри ровался автоматически , и
приходилось использовать и н струмент Auto Layout, чтобы обеспечить выполнение
указанных требований на всех устройствах.
Это почти все, что необходимо знать для создания первого приложени я . Об­
ратите вни мание на то, что мы до сих пор не нап исал и ни одной строки на
языке Swift.
И з менение атрибутов
Верн итесь к програм ме Xcode и оди н раз щел кните на метке Hello World, что­
бы выдел ить ее . Теперь обратите внимание на область, расположенную выше
панел и библиотеки. Эта часть вспомогательной панел и наз ы вается и н спекто­
ром ( i nspector). Как и библ иотека, окно и нспектора запол нено рядам и п и кто­
грамм, каждая из которых изменяет п редставление инспектора в зависимости от
конкрепюго типа дан ных. Для того чтобы изменить атрибуты метки, нам нужна
четвертая пиктограмма слева, которая открывает окно инспектора атрибутов, как
показано на рис. 2.23 .
СОВЕТ. И нспектор, как и навигатор п роекта , и меет свою комбинацию клавиш для каждой
из пиктограмм . Комбинаци и клавиш для пиктогра м м на панел и инспектора нач и нают­
ся с <Optioп + X + 1 > для крайней слева, < Optio п + X +2 > дл я следующей и т.д. В отл и ­
ч и е о т окна навигатора п роекта , кол ичество п и ктограм м в окне инспектора я вляется
контекстно-зависи м ы м и изменяется в зависи мости от того , какой объект выбран в
навигаторе и/или в редакторе.
-
Попробуйте измен ить внеш ний вид метки по своему вкусу. В окне и нспекто­
ра можно, например, изменить шрифт, размер и цвет текста. Обратите внимание
на то, что есл и вы изменяете размер текста, то вам, возможно, придется изме­
нить размер метки, чтобы она могла вместить более кру п н ы й текст. Для этого
выберите метку, а затем выберите команду Editorc:> Size to Fit Conteпt в меню
среды Xcode (рис . 2 .24 ). Закончив эксперименты, сохраните файл и выберите
команду Run снова. Внесенные вам и изменения отразятся на приложении, при­
чем и на этот раз вам не придется п исать ни одной строчки кода.
ЗАМЕЧАНИЕ. Не сл и ш ком беспокойтесь о назначен и и всех без исключения атрибутов
объектов. Читая книгу, вы еще м ного узнаете об окне инспектора атрибутов и о зна­
чении полей .
Позволяя вам разрабатывать свой интерфейс с помощью графических средств,
программа l nterface B u i lder освобождает вас от утом ител ьной необходимости
п исать код для реал изации пользовател ьского интерфейса, предоставляя возмож­
ность сосредоточ иться только на специфике приложения .
Большинство современных сред для разработки приложений и меют инстру­
мент графического проектирован ия и нтерфейса. Одно из отл и ч и й програм м ы
64
ГЛАВА 2 m П Е Р В О Е П РИЛОЖЕ Н И Е
l nterface Bui lder от м ногих и з этих сред разработки заключается в том, что она
не генерирует никакого кода, который требовал бы сопровождения. Вместо это­
го программа lnterface B u i lder создает объекты пол ьзовател ьского интерфейса
так, как будто вы их запрограмм и ровал и , а затем сериал изует их в раскадровке
ил и n iЬ-файле, чтобы загрузить в память во время вы полнения програм м ы . Это
позволяет избежать м ногих проблем, связанных с генерирован ием кода, 11, без­
условно, я вляется более мощн ы м методом разработки .
в
Тех! ' Pleln
Color ( Font
Oetault
Syatem_y.o
Alignment -------�__:::_.
1 :
Llnta
lleh8vlor rJ Enobled
о НlghJlghled
�8'е8U 1_����та11 ,
Buell ne
Autoehrtnk
Hfg/!llOШd
\..���1!!!!...._
l�xed F��":!._.
_8
_8
____
_ ___ _
__
О 11gllten Letter Spectng
JI
�� 0etau11
Инспектор атрибутов
-
lntemctlon О Uaer lnteroctlon EnaЬkld
'] Mulll� Touch
В.Ckground
Tll'll
Dofa�
В
��� --- --- в
cz::J
•
Orawlng О Opoque
Q Hidden
0 Ciee111 Graphlc8 ConttJCt
С Cllp Subvlewa
0 Autotealze SuЬvlewa
Stretclllng
)(
-Wldih
о :
1 • '
.
а lnat81i<ld
у
'
у
Ae/illit
о ,:
1 i:
Рис . 2 . 23 . О к н о и н с п е ктора , де м о н стри рующее
атри буты м етки
ГЛАВА 2 ·� П Е Р В О Е П РИ Л ОЖЕ Н И Е
liidt·M Product
odt Canvas
DeЬUg
з
Winclow Нвtр
----------
Source Control
:L
t:
Zoom
r
Hlde Document Outline
Reveal ln Document OUtline
Align
Arrange
•
•
•
*
../ Snap to Guides
Guldes
EmЬed ln
Unemoed
Localization Locklng
65
'
, ../ Automatically Refresh Views
Rt:frt'sh А!' Views
O>'oug Selected Vюws
"
"
"
...
...
".!:'"' �. $�7.!:'.zt.
C".r Scene i ·, V!ew Control
i
t
!С
�
m
t
1
...
Resolve Auto Layout lssues
Refactor ·to StoryЬoard".
-н �
�etlg. .. . g
Рис . 2.24 . И з м е н е н и е раз м е ра ш р и фта на б ол ь ш и й
в ы н удило н а с и з м е н ить огран и ч е н и я м а кета , в ы б ра в
команду Size to F it Content в в ы п адаю ще м м е н ю Ed itor
З аверша ю щие штрихи
Прежде чем закончить главу, придадим нашему приложению немного блеска,
чтобы сделать его похожим на аутентичное приложение дл я с исте м ы iOS. За­
пустите свой п роект. Когда на экране п оявится окно симулятора, щел кните на
кнопке Home си мулятора устройства i Phone (это черная кнопка с бел ы м квад­
ратом, расположенная в самом низу окна). Это вернет вас к домашнему экрану
устройства i Phone (рис. 2.25). Обратите вниман ие на то, что п и ктограмма при­
ложения выглядит, как обыч ное изображение, задан ное по умолчанию.
Взгляните на пиктограмму Hello World в верхней части экрана. Для то го чтобы
заменить ее стандартную скучную пиктограм му новой, необходимо создать новую
пиктограмму и сохранить ее в файле, и меющем формат PortaЫe Network Graphic
( . png ) . Лучше всего создать пять п и ктограм м : размером 1 80х 1 80, 1 20 х 1 20,
87х 87, 80х80 и 5 8 х 5 8 пикселей . Есл и вы планируете запускать свое приложе­
ние на iPad, понадобятся еще четыре пиктограм м ы . Для i Pad Pro допол нител ьно
потребуется изображение 1 87 х 1 87 п и кселей . Дело в том, что эти п и ктограм м ы
66
ГЛАВА 2 ш П ЕР В О Е П РИЛОЖЕ Н И Е
будут демонстрироваться н а главном экране, в настрой ках Settiпgs и в списке
резул ьтатов поиска Spotlight. Эти м вариантам соответствуют первые три пикто­
грамм ы . Еще три пиктограмм ы потребуются для устройства i Phone 6/бs, которое
имеет более крупный экран с более высоким разрешен ием . К счастью, размеры
одной из этих пиктограмм совпадают с размерами одной из предыдущих, поэто­
му на самом деле нам понадобятся пять вариантов пиктограм м ы приложени_я для
i Phone. Есл и пропустить одну из маленьких пиктограмм, то более крупные будут
автоматически масштабированы . Однако для достижения наилучших резул ьтатов
это масштабирование желательно предусмотреть заранее.
Рис. 2 . 25 . П р ил оже н и е H e l l o
World н а гл авном экране
ЗАМЕЧАНИЕ. На самом деле п роблема размеров п и ктограм м еще сложнее . До появле­
ния системы iOS 7 размеры п и ктограм м для всех современных устройств i Phone были
равны 1 1 4х 1 1 4 п икселей . Есл и же вы захотите обеспечить поддержку более старых
моделей , не имеющих экрана Retin a , то вам будут нужны пиктграммы вдвое меньшего
размера
57х57 . Кроме того , существует устройство i Pad , имеющее совсем другие
размеры пиктограм м как для экранов Retiпa, так и для других экранов , как в системе
iOS 1 0 , так и в более ранних версиях iOS.
-
ГЛАВА 2 � П Е Р В О Е П Р ИЛОЖЕН И Е
67
Не пытайтесь и м итировать стиль кнопок, которые уже есть на экране; ваше
устройство i Phone или i Pad автоматически о кругл ит угл ы . Создайте простые,
квадратные изображения. Вы найдете набор подходя щих п и ктограм м в папке
пиктограм м проекта 0 2 - He l l o Wor l d .
ЗАМЕЧАНИЕ. Для создания п и ктограм м в своем приложе н и и испол ьзуйте файлы с рас­
ширением . png . Система Xcode автоматически оптимизирует изображен и я . png во
время сборки приложения . Благодаря этому и спользование изображений в формате
. png является сам ы м быстрым и эффективным способом работы с пиктограммам и .
Несмотря н а т о что изображения в других распространенных форматах также отоб ­
ражаются правильн о , основным я вл яется формат . png, а дл я использован и я других
форматов должны существовать весомые причи н ы .
Нажм ите комбинацию клавиш <X+ I >, чтобы открыть навигатор проекта, а
затем откройте группу Hello World и найдите папку As s e t s . xca s s e t s . Иногда
ее назы вают катало гом ресурсов (asset catalog). По умолчанию каждый новый
проект Xcode создается с каталогом ресурсов, содержащим п и ктограм м ы и дру­
гие вспомогательные файл ы . Выберите папку As s e t s . xca s s e t s и перекл ючи­
тесь на область редактирования.
В левой части окна редактирован ия в ы увидите столбец, содержащий эле­
мент с именем Applco n . Выберите его - и справа от него вы увидите область
с текстом App i co n в левом верхнем углу и пунктир н ы м и квадрати кам и для
пиктограм м, о которых м ы говорил и выше (рис. 2 .26). Именно сюда вы будете
перетаски вать свои новые п и ктограм м ы .
\!; СО •' D .:J li
��
�
D Ф 9
- 1 ... - - - - -1
. .... " w.\d
1
· -- ---
- --
-- ­
"" .
-
... #llCl>ll:ool
_. _,,
� ,,. \.....,...
' ..-;r.os t.O '"C.1'�
..... "
..... . Q ,.O lf'd C.-.
IOt", . �
""- & 1О1 1ь ... �
· os 1,, _, .._
._ ...
''" .
""
." ...,,,.
108 •·•
'"'
-­
\0$ 1·1
'''"
D i1 0 о
Рис . 2 . 26 . П и ктограм м ы Applco n в катал оге ресурсов п роекта . Здесь м ожно
настроить п и ктогра м м ы п риложе н и я
68
ГЛАВА 2 n П Е Р В О Е П Р И Л ОЖЕ Н И Е
Откройте пап ку п и ктограм м проекта 0 2 - He l l o Wo r l d, выберите все файл ы
и перетащите их в програм му l nterface B u i l der. Бол ь ш инство п и ктограм м будут
автоматически вставлены с соответствующи м и и м енам и . Возможно, на экране
останется нескол ько пустых квадратов. Их придется запол н ить по-отдельности .
Для этого необходимо сравнить размер файла с размерам и квадрата. Если под
квадратом написано 2 х или Зх, то вам понадобятся двойной и трой ной ра�меры
файлов. Напри мер, на рис. 2 .2 7 квадрат для i Phoпe Spot l i ght IOS 7-9 остался
пустым и имеет размер З х . Это знач ит, что вам нужно найти файл, соответству­
ющий 1 20 п и кселям, т.е. З х40 п и кселя м .
Applcon
Арр ICOfl
EJ EJ 1� 1
1х
2х
Зх
IPhone
2•
, iCloud Orlve
·
AppПcations
1 UtlYtles
1 Oesktop
Oocuments
,..., ,
IPhone Арр
Ц'\С ?-О
Зх
02 - Hello World - icons
• •
• AirDrop
мгс r .
EJ EJ
2х
All Му Files
,...., ,
IPhoм 17 1
40pt
SeШngs • iOS 5·9
29pt
DropЬox
Зх
iPhone Spatllght
IOS 7·11
Spot1ight • iOS 6,6
rita
,-. '
с"1>1ау � •
IPICI .i' 1
lcon-29. png
�
lcon-40.png
!!!1 lcon -58. png
lcon-76.png
11 lcon-80.png
lcon-87.png
l:J ICOn- 1 20 Pn\J
lcon - 1 52 .png
'3 lcon - 1 67.png
lcon - 1 80.png
�
О
О
О
icon-120.png
Рис . 2 . 27 . Убедите с ь , что файл ы с расш и р е н и е м . png и м е ют п равильные раз­
меры
Теперь с ком пилируйте и вы пол н ите приложе н ие. Когда си мулятор закончит
п роцесс запус ка, в ы пол н ите команду < S h i ft+ X + � >, верн итесь к домаш нему
э крану и посмотрите на п и ктогра м му, показанную на рис. 2 . 2 8 . Дл я того что­
бы посмотреть, как выглядят более мелкие п и ктограм м ы , проведите пал ьцем
ГЛАВА 2 '� П Е Р ВО Е П РИЛОЖЕ Н И Е
69
сверху вниз (swipe down) по главному экрану, чтобы на нем поя в илось окно
Spotlight, и начн ите вводить слово He l l o . Вы сразу же увидите новую п и кто­
грам му приложения .
Рис . 2 . 28 . Те п е р ь в а ш е п р и л оже н и е
и м е ет эффектную п и ктогра м м у !
ЗАМЕЧАНИЕ. В ходе работы над книгой наш главный экран симулятора оказался захл а м ­
ленным п и ктограммами выполняемых нами п р и м е р о в . Есл и вы хотите стереть старые
пиктогра м м ы с гл авного экрана , выберите команду IOS Simu latorq Reset Content
and Settings в меню симулятора приложений дл я систе м ы IOS.
. . .
Э кр а н з а п уска приложен и я
Запуская свое приложен ие, вы м ного раз могл и в идеть бел ы й экран, который
возникает при загрузке приложения . Приложения iOS всегда должны иметь эк­
ран запуска. Поскол ьку процесс загрузки приложения в память зан имает опре­
делен ное время (и чем кру п нее прил ожен ие, тем бол ьше времени необходимо
для его загрузки), экран запуска должен как можно быстрее продемонстриро­
вать пол ьзовател ю, что происходят некие действия. До поя вления версии iOS 8
70
ГЛАВА 2 1;1 П ЕР В О Е П Р И Л ОЖЕН И Е
н а экран можно было вывести изображение (фактически нескол ько изображений
разных размеров), которое и грало рол ь заставки . Система iOS могла загрузить
правил ьное изображение и немедлен но в ы вести его на экран до загрузки ос­
тал ьной части приложения. Начиная с версии iOS 8 ком пания Apple настоятел ь­
но рекомендует использовать не заставку, а файл запуска, а заставку применять
для более ранних версий.
Файл запуска - это раскадровка, содержащая п ол ьзовател ьский интерфейс
для э крана запус ка. На устройствах, работающих под управлен ием системы
iOS 8 и более поздних версий, приоритет отдается файлу запуска, а не застав­
ке. Посмотрите в навигатор проекта - и вы у видите, что в вашем проекте
уже есть файл запуска с именем LaunchS c r e e n . s t o r yboard. Есл и открыть
его в програм ме B u i lder, то п оя в ится пустое п редставлен ие, показанное на
рис. 2 .29.
r -
1
1." .
-
-
IPhone 6s 1 Portrait
1
iPhone SE 1 Landscape
. . _J
Рис . 2 . 29 . Файл запуска п р иложе н и я , п р едусм отре н н ы й по умол ч а н и ю
Ком пания Apple предполагает, что разработчи к и будут создавать заставку с
помощью п рограм м ы l nterface B u i lder точ но так же, как л юбую другую часть
пол ьзовател ьского и нтерфейса. Ком пания Apple рекомендует не п ытаться созда­
вать сложные ил и визуал ьно п ы ш н ые заставки, поэтому м ы последуем их со­
ветам . Мы просто добавим метку в раскадровку и изменим цвет фона главного
представления, чтобы можно было отл и ч ить заставку от самого приложения .
Как и раньше, перетащите метку на раскадровку, измен ите ее текст на He l l o
ГЛАВА 2 !'!; П ЕР В О Е П РИЛОЖЕН И Е
71
Wo r l d, а затем с помощью инспектора атрибутов (см . рис. 2 .23 ) измените его
шрифт на System Bold 3 2 . Выберите метку и выберите команду Editoгq S ize to
Fit Content в меню Xcode. Затем отцентруйте метку в представлении и выберите
команду Ed itorq Resolve Auto Layout lssuesqдdd Missing Constra i nts, чтобы доба­
вить необходимые огран ичения макета. Далее выберите главное представление,
щел кнув на раскадровке или в окне Document Outl ine, и с помощью инспекто­
ра атрибутов измените цвет его фона. Для этого найдите элемент управления
с меткой Backg rou n d и выберите цвет, который вам нравится (мы рекоменду­
ем наш любим ы й желтый цвет). Теперь просто запустите приложение еще раз .
Сначала поя вится заставка, которая постепенно будет гаснуть по мере того, как
будет поя вляться само приложен ие (рис. 2.3 0).
8 Watch .
2:4\I PM
-
Hello World
Рис . 2 . 30 . Экран заставки п р и л о ­
же н и я H e l l o World
Бол ьше и н формаци и о файле запуска, застав ках и п и ктограм м ах п р и ­
ложе н и й можно найти в доку м е нте ком пан и и A p p l e iOS H uman l nterface
Guidelines, расположен ном на веб-стран и це https : / / deve l ope r . app l e . сот/
l i bra ry / i o s / docume nt a t i o n / U s e rE xpe r i e nce / C o n c e p t u a l / Mob i l e H I G /
Launchima g e s . html .
72
ГЛАВА 2 м П ЕР В О Е П Р ИЛОЖЕН И Е
З а п уск приложе н ия н а устройстве
П режде чем завершить главу, м ы должны сделать еще кое-что. Загрузите
приложение и запустите его на реал ьном устрой стве. С начала соедин ите уст­
ройство iOS с ком п ьютером зарядны м кабелем. После этого среда Xcode должна
рас познать устройство и некоторое время считы вать с него и н ф ормаци ю . _ В ы
можете увидеть сообщение систем безопасности н а ком п ьютере Мае и н а своем
устройстве, спраш и вающее вас, доверяете ли вы друг другу. П одождите, пока
среда Xcode закончит обработку с и м вольных ф айлов, полученных от устройства
(чтобы видеть это, откройте представление Activity View), и откройте селектор
устройств на панел и инструментов. Вы увидите сп исок устройств, показанный
на рис. 2 . 3 1 .
Editor
Product
.
.
e:J
�
....
0.
Oebug
.
6
•1Н.110 Yi;id ---У ._J Нollo World
0
В•1 , O"IY Ot'Vlco
?- Genoric IOS Dovice
!!!
-
iPad Alt
W AppDelogete.swift
IPad Alr 2
_;; VlewControlter.ewift
IPad Pro (9.7 inch)
i_
: :n Мaln.storyЬoard
• Assets.xc.ssots
Q L��d
IPad Pro (12.9 inch)
1
'°
iPed Rotina
1Phone 5
' lnfo.pllst
iPnone Ss
11> L j Products
1Phol1e 6
IPhone 6 Plus
1Phono 6s
1
iPhone 6s Plus
IPhone SE
Add Addltlonal Simulators.­
Oownload Slmutatora�.
Рис . 2 . 3 1 . С п и с ок у строй с тв и с и мул ято р о в , в ко ­
то р ы й входит i Ph o n e 6/бs , п р и н адл ежа щи й одн ому
и з авторов
Выберите устройство и щел кн ите на кнопке R u n , расположенной на панел и
инструментов, чтобы начать процесс инсталляции и запуска приложения на нем .
Среда Xcode заново соберет приложение и выпол н ит его на вашем устройстве.
Поскол ьку в работе над книгой испол ьзовалась бета-версия среды Xcode 8, на
экране может поя виться окно, показанное на рис. 2 . 3 2 .
ГЛАВА 2 "" П ЕР В О Е П РИЛОЖЕ Н И Е
73
1110 World 1 Bulld Hello World: Fllhd 1 Today at 7:49 РМ
Falled to code 8ign •Нeflo World•.
No vatid algn1ng fdentitiм �.е. certifioate and private
key paJr) were found.
Xoode oan attempt to flx this isaue. Тhis will reset
yout code slgnlng and proviaionlng setting.s to
l'8COIТlmended valuea and resolve lasues with slgning
ldentitlea and provisioning profilea.
r cancel .j мщзм
Рис . 2 . 32 . Е с л и п редварител ь н ы е усл о в и я н е в ы п ол н я ются , н а
экране может п о я в ить с я п редуп режде н и е
ЗАМЕЧАНИЕ. Компания Apple внесла улучшения в систему контроля испол ьзования вер­
сии Xcode 8 , и м ногие из проблем был и решен ы , так что п роцесс загрузки стал более
гладким и простым . Мы п ривели этот пример тол ько для демонстрации важности пра­
вильной подготовки приложе н и я к запуску на реальном устройстве .
Перед тем как и нсталл ировать п р иложение на устройстве iOS, необходимо
создать его п рофил ь ресурсов и подпись. П одпись приложения позволяет уст­
ройству идентифи цировать автора и п роверять, не был л и б инарн ы й код иска­
жен после его создания. Профил ь ресурсов содержит и нформацию для систе м ы
i O S о том, какие фун кциональные возможности нужны приложению, например
доступ к службе iC \oud, и на каких устройствах оно может работать. Для того
чтобы подписать п риложение, среда Xcode должна получ ить сертифи кат и за­
крыты й ключ .
СОВЕТ. Бол ьше информации о созда н и и подписи кода , п рофилей ресурсов и закры ­
тых кл ючей содержится в документе Distribution Workflows, входя щем в спра вочн и к
Арр Distribution Guide , расположенный по адресу h t t p s : / /deve l ope r . app l e . сот/
l ibr ary / i o s /docume n t a t i on / I DE s /Conceptual /App Di s t r i bu t i onGu i de .
Раньше вы должны были подписаться на п рограм му разработки и вручную
создать профиль и подпись, а затем зарегистрировать тестовые устройства, на
которых вы хотите инсталли ровать приложение. Это был сложн ы й и утом и­
тельный процесс. Среда Xcode 7 была настоль ко усовершенствована, что дела­
ла это автоматически, а версия Xcode 8 еще бол ьше улучшила с итуацию, так
что програм мисту достаточно всего л и ш ь загрузить приложение на устрой­
ство для тестирован и я . В некоторых случ аях, когда для разных пол ьзователей
74
ГЛАВА 2 ti П Е Р В О Е П РИЛОЖЕН И Е
предназначаются разные сборки, процесс создания профиля можно настраивать, но
для обучения достаточно использовать механизм, предусмотренн ы й по умолчанию.
М ногое может пойти неправильно. Напри мер, увидев сообщение о том, что
ваш идентификатор Арр I D недосrупен, вы должн ы в ыбрать другой. Иденти­
фи катор Арр 10 состоит из названия п роекта и идентификатора орган изаци и,
которы й вы выбираете при создани и проекта (см. рис. 2 .4). В ы увидите это со­
общен ие, есл и испол ьзовал и идентификатор com . beg i nn i ng iphone ил и другой
идентифи катор, который кто-то уже зарегистрировал . Для того чтобы исправить
сиrуацию, откройте навигатор проекта и выберите узел Hello World, расположен­
н ы й на вершине дерева проекта. Затем щел кните на узле Hello World в разделе
TARG ETS в окне Docu ment Outline. В заключение щел кн ите на кнопке General в
верхней части области редактирования (рис. 2 . 3 3 ).
!1Э <
···Ш\!1···· [l
•11§1Жloo.Will\O
'{;)�.­
�')�""""
0-..,,._
.
��
,а....
-
) " ..... ......
PAOJICТ
�_.
lli l<tlto Wo<ld
ТAЯQlfl
CIJ)8Ьllltlм
· -
Retouroe Т9
lnfo
Вulld S.Ctfnot
&lk:I Ph•...
&lld A!illм
v.rtiOn 1 .0
Вullcl 1
Тмm
Nont
В
Рис . 2 . 33 . И з м е н е н и е иде нтифи като ра ко м пл е кта п р иложе н и я
Идентификатор Арр I D, который среда Xcode испол ьзует дл я подписи при­
ложений, образуется из содержания поля Bundle ldentifier в редакторе. Это поле
содержит идентификатор организации, выбранн ы й вам и при создан ии проекта
(эта часть поля на рис. 2 . 3 3 выделена подсветкой). Выберите другое значение и
поп ытайтесь снова. В кон це кон цов вы должны найти идентификатор, которы й
еще никем не испол ьзовался. Когда вам это удастся , отметьте его и запол ните
поле Organ ization ldentifier для нового проекта. После того как вы сделаете это
правил ьно, среда Xcode запомнит идентифи катор, и вам больше не придется
повторять этот процесс.
Другая возможная проблема показана на рис. 2.34.
В ы увидите это сообщен ие, тол ько есл и в ы не присоединил ись к програм ме
разработчиков. Это знач ит, что ваше устройство iOS не доверяет вам запуск
приложений, 11одписан ных ваш и м идентификатором Apple 1 0 . Для того чтобы
исправить этот недостаток, откройте на устройстве приложение Settings и вы­
пол ните команду General � P rofile. В ы увидите страницу с таблицей, содержащей
ваш идентифи катор Apple 1 0 . Коснитесь строки табл и цы, чтобы открыть дру­
гую стран ицу, показанную на рис. 2 .3 5 .
ГЛАВА 2 � П Е Р В О Е П Р И ЛОЖЕ Н И Е
Finished runnlng Hello Wor1d on Klm Topley's IPod
1
--- ·· ii
Could not launch "Hello Wortd11
Capal
··�
Вu
рюсма Jauneh falllld: Securlty
_ ,
......
l!."'S!!'!«�I
·
•..,,""'
J=.!
д�
:!: 11"1'
1.,..
. """'�'"""�..,..
"'
�,,..
"'""
"'"'i"":.�
·�'��
ч:::
•=
·=�
tш�
m::�::=
:t=i
t«�
1·�
1 t::
Рис . 2 . 34. Н е воз м ожность запустить п р иложе н и е в с и стеме
IOS 9 и л и 1 0
iPod ?
(
10:09 РМ
Ьeginning.iphonedev@gmail . ...
Apps trom developer "iPhone Developer:
Ь[email protected]
(AGQ5TWZ 57З)- are not trusted on thls iPod
and wlll not run unt11 the developer is trusted.
Trust " beginning. iphonedev@gmail . . . .
APPS FROM DEVELOPER "IPHONE
DEVELOPER:
[email protected]
(AGQ5ТWZ573)"
Hello World
Verified
Рис. 2 .35. В с и сте м е IOS 9 и более п озд­
них вер с иях раз работч и к и , н е п одп и с а в ш и ­
е с я н а п рогра м м у раз работки , п о умол ч а ­
н и ю н е и м е ют до верия
75
76
ГЛАВА 2 ю П Е Р В О Е П РИЛОЖЕН И Е
Р е зюме
М ы должны быть удовлетворен ы прогрессом, достигнуты м в этой главе. Не­
смотря на то что, на первы й взгл яд, мы сделал и не сл и ш ком м ного, на самом
деле мы освоил и п рактически все основы разработки п рограм м . В ы изучил и
шаблоны проектов iOS, создал и приложение, получ или ключевые знан ия о, сре­
де Xcode 8, п ристу п ил и к испол ьзовани ю програ м м ы l nterface B u i lder, узнали о
том, как настроить п и ктограмму приложения и запустить приложение на симу­
ляторе и реал ьном устройстве.
И все же, программа Hello World
сл и ш ком одностороннее приложение.
Мы показы ваем пол ьзователя м какую-то информацию, но не получаем данных
от них. В следующей главе мы покажем, как обеспеч ивать ввод дан ных от поль­
зователя на устройство iOS и вы пол нять действия, основы ваясь на этих дан ных.
-
ГЛ АВА 3
• •
О сн о в ы в з а и м о де й ст в и я
Наше приложение H e l lo World было хорошим в ведением в разработку при­
ложений для системы iOS с помощью и нтегрирован ной среды Xcode и каркаса
Сосоа Touch , но в нем не было очень важной фун кционал ьной возможности :
взаимодействия с пол ьзователем. Без этого приложение имеет очень ограни чен­
ное применение.
В этой главе мы нап и шем нем ного более carrler •
11:06 АМ
Left button pressed
сложное приложение, в котором будут две
кноп ки и метка, как показано на рис. 3 . 1 .
Когда пол ьзовател ь нажмет одну из кнопок,
текст метки измен ится . Этот пример может
показаться сл и ш ком у п роще н н ы м , но о н
де монстрирует кл ючевые кон це п ц и и , связан ные с реал изацией взаи модействия пол ьзователя с приложен и я м и для систе м ы iOS.
П аради г ма " модел ь ­
контроллер - п редста вление "
Кон цепция "модель-контроллер-п ред­
ставление" (Model-View-Control ler
МУС)
представляет собой очен ь логи ч н ы й способ
разделения кода, лежащего в ос нове прило­
жений с графическим пол ьзовател ьским и н ­
терфейсом . В настоя щее время практически
все объектно-ориенти рован н ы е среды раз­
работки в той ил и иной степен и испол ьзу­
ют концепцию MVC, но л и ш ь некоторые из
них действ ител ьно п ол ностью воплощают
парадигму MVC, как это делает среда Сосоа
Touch .
Lett
R1ght
-
Рис . 3 . 1 . П ро с тое п р иложе н и е
с двум я к н о п ка м и , кото рое м ы
разработаем в это й гл аве
78
ГЛАВА 3 � О С Н О В Ы В ЗА И М ОДЕ ЙСТВ И Я
Шаблон MVC разделяется п о фун кциональны м возможностям н а три категории.
�
�
*li
Модель . Состоит из классов, в которых хранятся дан ные приложени я .
Представление. Создает окна, элементы управления и другие элементы,
которые пол ьзовател ь видит и с которы м и взаимодействует.
Контроллер. С вязы вает модел ь и представлен ие, реал изует логи ку при­
ложения, в соответстви и с которой оно обрабаты вает дан ные, введе � ные
пол ьзователем.
Назначение концепции MVC
создать как можно более независимые один
от другого объекты, реал изующие эти три типа кода. Л юбой объект, создавае­
м ы й вам и, должен четко идентифицироваться как объект, принадлежащи й одной
из переч исленных выше категори й . При этом он должен вообще не иметь или
иметь как можно мен ьше фун кциональных возможностей, которые можно было
б ы отнести к остал ь н ы м двум категория м . Напри мер, объект, реал изующий
кнопку, не должен содержать код для обработки данных в момент ее нажатия, а
реал изация банковского счета не должна содержать код для рисован ия табл ицы
для демонстрации транзакци й .
Концепция M V C обеспеч ивает максимал ьное повторное испол ьзование кода.
Класс, реал изующий обобщенную кноп ку, можно испол ьзовать в любом прило­
жени и . Класс, реал изующий кнопку, выполняющую кон кретн ые вычисления при
ее нажатии, можно испол ьзовать тол ько в том приложении, дл я которого он был
написан изначал ьно.
Когда в ы пишете приложения в среде Сосоа Touch, вы в основном создаете
компоненты представления, испол ьзуя визуальный редактор I nterface Builder, хотя
и ногда вы также модифицируете свой и нтерфейс с помощью кода ил и создаете
подклассы для существующих видимых деталей и элементов управления.
Ваша модел ь будет создана на основе классов языка Swift, разработанных
для хранения дан н ы х прил ожения . Мы не собираемся создавать объекты мо­
дел и в этой главе, поскол ьку не план и руем хран ить или собирать дан ные, и
описываем их для того, чтобы испол ьзовать в последстви и при разработке более
сложных приложений.
Ваш контроллер будет состоять из классов, создаваем ых вам и, а также от­
нося щихся к вашему приложению. Контроллер может пол ностью состоять из
обы ч н ы х классов, но чаще они я вл я ются п одкл ассам и одного из существую­
щих обобщенных классов контроллера из библиотеки U I K it, например класса
U IVi ewCon t ro l l e r, с которы м мы встретимся в следующем разделе. Создавая
подклассы одного из существующих классов, вы получаете в свое полное распо­
ряжение множество фун кциональных возможностей и эконом ите время за счет
того, что не изобретаете велоси пед.
По мере углубления в среду Сосоа Touch вы быстро убедитесь, что классы
каркаса U I Kit следуют при н ципам M VC. Есл и вы будете последовател ьно при­
держи ваться этой кон цеп ции в процессе разработки, то в резул ьтате создадите
более ясн ы й и легко эксплуатируе м ы й код.
-
ГЛАВА 3 11 О С Н О В Ы ВЗАИ МОДЕ Й СТВ И Я
79
Созд ание прило жения ButtonFun
Настало время создать следующий проект Xcode. М ы собираемся использо­
вать тот же шаблон, который исследовал и в предыдущей главе : S i ng l e View
Appl i c a t i on. Оттал киваясь от этого простого шаблона, нам будет легче уви­
деть, как взаимодействуют объекты представления и шаблона в рам ках п рило­
жения для системы iOS. В следующих главах мы будем испол ьзовать другие
шаблон ы .
Запустите програм му Xcode и выберите команду F i l e r::> N ew r::> N ew P roject
ил и нажм ите комби нацию клавиш < X +N>. В ыберите шаблон S i n g le View Ap­
pl ication и щел кн ите на кнопке Next.
Вы увидите тот же сам ы й л ист настроек, которы й в идел и в предыдущей гла­
ве. В поле Prod uct N a me в ведите назван ие нового приложения
B u t t o n Fun.
Поля Organization N a me, Company ldentifier и La ng uage идентификатора пакета
должно содержать те же значения, которые м ы испол ьзовал и в предыдущей гла­
ве, поэтому трогать его не следует. М ы план ируем испол ьзовать механ изм Auto
Layout, чтобы наше приложение работало на л юбых устройствах iOS, поэтому в
поле Devises выберите значение U n iversal . Полый сп исок настроек представлен
на рис. 3 .2.
. . .
-
Choose optlons for your new project:
Product Name:
теаm:
Organlzat/on Name:
Organlzation ldentlf/er:
Bundle ldentifler:
Language:
Devices:
J
Butt
o,;'F un
Molly мaskrey
MollyMaskrey
:J
в
com. mollymaskrey
com.mollymaskrey.ButtonFun
Swift
Universal
в
в
Use Core Data
lnclude Unit Tests
lnclude UI Tests
Cancel
Previous
Рис. 3 . 2 . В ы б о р и м е н и п роекта и е го параметров
MS§
80
ГЛАВА 3 rcx ОС Н О В Ы В ЗА И М ОД Е Й СТВ И Я
Щел кн ите н а кноп ке N ext и выберите место хранен ия своего проекта. Ос­
тавьте флажок Create Git repository сброшен н ы м ил и установленным на свое ус­
мотрение. Сохраните проект среди остал ьных проектов нашей книги.
С о зда н ие контролл ера п редста вле н ия
Нем ного позднее м ы разработаем представление (т.е. пол ьзовател ьскИй ин­
терфейс) для нашего п риложения, испол ьзуя п рограм му I nterface Bui lder, как это
было сделано в п редыдущей главе. А пока м ы собираемся внести изменения в
файлы исходного кода, создан ного для нас шаблоном проекта. Да, м ы действи­
тел ьно собираемся написать часть кода в этой главе. Но прежде чем вносить ка­
кие-л ибо изменения, взглянем на файлы, сгенерирован ные шаблоном . Для этого
следует раскрыть навигатор проекта, в котором уже раскрыта группа Button Fun.
Есл и это не так, ее следует открыть, щел кнув на треугол ьнике раскрытия, рас­
положенном рядом с ее именем (рис. 3 .3 ) .
8
ButtonFun
0 ;ш о @)- l
- - -
"'
ButtonFun
"'
)
-·-
-·�
Buttonfun
� AppDelegate. swlft
D ViewCon troller. swift
Main.storyboard
Assets.xcassets
LaunchScreen.storyboard
_..
Jt:. lnfo.plist
Products
Рис . 3 . 3 . Н а в и гато р п ро е кта , де м о н ст р и рующи й
фа й л ы кла сс ов , созда н н ы е шабл о н о м проекта . Об ­
рат ите в н и м а н и е на то , ч т о н а ш п р е ф и к с кла сс а а в ­
томати ч е с ки и н ко р п о р и рован в и м е н а кла сс а
Груп па But t o n Fun должна содержать два файла с исходны м кодом, один
файл раскадровки, файл заставки, каталог ресурсов, содержащий все изобра­
жения, необходимые для приложения, и файл I n f o . p l i s t, которы й будет рас­
смотрен в последующих главах. Два файла исходных кодов содержат реал иза­
ции классов, необходимых для приложения : делегат приложения и контроллер
представления приложения, и м еющего тол ько одно п редставление. Делегат
ГЛАВА 3 !\i О С Н О В Ы ВЗАИ М ОДЕ Й СТВ И Я
81
приложения будет рассмотрен позднее в этой главе, а пока исследуем контрол­
лер создаваемого нам и представления.
Класс контроллера, ответствен н ы й за управление этим представлением, на­
зывается ViewCont ro l l e r . Это имя означает, что класс я вл яется контроллером
представления. Щел кните на файле View. Controller. swift в окне навигатора проек­
та, и вы увидите на экране содержимое этого файла (л исти н г 3 . 1 )
.
Л исти нr 3 . 1 . Код класса Vi ewCont ro l l e r , сгенерирован ного по шаблону
i mp o r t U I K i t
c l a s s V i ewCon t r o l l e r : U I V i e w C o n t r o l l e r
ove r r ide f u n c vi e w D i dLoad ( ) {
s up e r . v i e w D i d L o a d ( )
1 1 Допол н и т е л ь ные н а с трой ки п о сл е з а г ру з ки предст а вл е н и я ,
1 1 к а к п р а вило , и з n i Ь - ф а йл а .
ove r r ide f u n c d i dRe c e i veMemo r yW a r n i n g ( )
s up e r . d i dRe c e i veMemo r yW a r n i n g ( )
1 1 О с в о б ожда ем любые в о с с т а н а вли в а емые ре сурсы
Поскол ьку этот файл сгенерирован по шаблону, он имеет не очень богатое
содержание. Vi ewCont ro l l e r
это подкласс класса U IVi ewCon t ro l l e r, од­
ного из обобщенных классов контроллера, которые м ы упом и нал и выше. Он я в­
ляется частью библиотеки U I Kit и предоставляет в наше распоряжение м но­
жество функциональных возможносте й . С реда Xcode не знает, какие именно
функциональные возможности должно и меть наше приложение, но ей известно,
что мы собираемся сделать нечто, поэтому она создала этот класс, в котором
будут реализован ы требуемые функциональные возможности .
-
В ыходы и действия
В главе 2 для разработки пользовательского интерфейса м ы использовали про­
грамму I nterface Builder, а в л истинге 3 . 1 мы видели оболочку класса контроллера.
Рассмотри м способ, с помощью которого наш код в классе контроллера представ­
ления будет правил ьно взаимодействовать с объектам и (кнопками, метками и пр.),
соде Rжащим ися в раскадровке. Класс контроллера может ссылаться на объекты в
раскадровке, используя особый вид свойства под названием выход ( outlet). В ыход
можно интерпретировать как указатель, ссылающийся на объект в пользователь­
ском интерфейсе. Например, допустим, что вы создали текстовую метку с помо­
щью програм мы Interface Bui lder (как это было сделано в главе 2) и хотите изме­
нить ее текст, модифицируя исходный код. Объявив выход и связав его с объектом
метки, вы можете испол ьзовать эту переменную в своем коде для изменения текс­
та, изображенного на метке. М ы покажем, как это сделать, ниже в этой главе.
82
ГЛАВА 3 !fl О С Н О В Ы ВЗАИ М ОДЕ Й СТ В И Я
Перейдем на проти воположную сторону. Объекты и нтерфейса в нашей рас­
кадровке или n i Ь-файле моrут быть связаны со специальными методам и в клас­
се контроллера. Эти специал ь н ы е методы н аз ы ваются действи я м и (actions).
В ы даже можете сообщить п рограмме I nterface Bui lder, что, когда пол ьзовател ь
касается кнопки, она должна вызвать один метод, а когда пользовател ь отн имает
палец от кнопки, должен быть вызван другой метод действия .
С реда Xcode поддержи вает разные способы создания выходов и действий .
Напри мер, можно указать их в заголовочном файле контроллера представления
и лишь после этого откры вать програм му I nterface B u i lder и приступать к свя­
зыванию выходов и действий, однако представление помощни ка (assi stant v iew)
в программе Xcode позволяет быстрее и проще создавать и связы вать выходы и
действия одновременно. Этот процесс м ы также вскоре рассмотр и м . Но прежде
чем приступать к установке связей между выходами и действиями, поговорим о
них нем ного подробнее. Выходы и действия - два основных элемента, исполь­
зуемых при создани и приложений для операцион ной системы iOS, поэтому нам
важно понимать, что они собой представля ют и как работают.
В ыходы
Выход (outlet) - это обы ч ное свойство в языке Swift, объя вляемое с помо­
щью атрибута @ I BOut l e t . Объя вление выхода в заголовоч ном файле контрол­
лера должно выглядеть примерно следующи м образом :
@ I BOu t l e t we a k va r myBu t t o n : U I B u t t o n !
Этот пример демонстрирует выход с и менем myBut t on, который можно свя­
зать с л юбой кнопкой пол ьзовател ьского и нтерфейса.
В идя атрибут @ I BOu t l e t , ком п илятор Swift не делает н и чего особен ного.
Его еди нственное назначение - подсказать програм ме I nterface Bui lder, что это
свойство, которое будет связано с объектом в раскадровке или niЬ-файле. Любом
свойству, которое вы создадите и захотите связать с объектом в n i Ь-файле, дол­
жен предшествовать атрибут @ I BOut l e t . К счастью, програм ма Xcode теперь
создает выходы автоматически при перетаскиван и и объекта на свойство, с кото­
рым вы хотите его связать, и даже при перетаскиван и и его на класс, в котором
вы хотите создать новый выход.
У ч итателей может возникнуть вопрос, почему объя вление свойства myButton
завершается воскл и цател ьным знаком . По п равилам языка Swift все свойства
должны быть пол ностью и н ициал изированы до завершения работы всех ини­
циализаторов, есл и они не были объя влены как свойства необязательного типа.
Когда контроллер загружает раскадровку, значения свойств выходов определяют­
ся и нформацией, содержащейся в раскадровке, но это происходит после запуска
и н и циализатора контроллера представления. В результате, есл и явным образом
не определить фиктивные значения ( что нежелател ьно), то свойства выхода необ­
ходимо объявить как свойства необязател ьного типа. Таки м образом, существует
ГЛАВА 3 i.� О С Н О В Ы ВЗАИ МОДЕЙСТВИЯ
83
два способа объя вления свойств выходов - с помощью символов ! и ?, как по­
казано в л исти нге 3 .2.
Листинг 3 . 2 . Д в а способа объявления переменных необязател ьного типа
@ I BOu t l e t wea k va r myBu t t o n l : U I Bu t t o n ?
@ I BOu t l e t w e a k va r myB u t t o n 2 : U I B u t t o n !
Второй способ проще первого, потому что не требует я вной распаковки пере­
менной необязател ьного типа, когда она впоследстви и понадобится в коде кон­
троллера представления (л истин г 3 .3 ).
Л исти нг З . З . Исключен и е необходимости явно
распаковывать переменные необязательного типа
l e t buttonl
=
myButtonl !
let button2
=
myBut ton2
/ / Переменную необязательного типа
1 1 необходимо явно распаковать
/ / Переменная myButton2 распакована неявно
ЗАМЕЧАНИЕ. Спецификатор we a k перед объявлением свойства выхода означает, что
данное свойство не обязано создавать сильную ссылку на кнопку. Объекты автомати­
чески удаляются из пам яти , есл и на н их больше нет сильных ссылок. В данном случае
нет никакого риска , что кнопка будет удалена из памяти , ведь на нее всегда будет
указывать сильная ссылка , поскол ьку кнопка является частью пол ьзовател ьского и н ­
терфе йса. Объя вление слабой ссылки позвол яет удалять п редставление из памяти ,
если оно бол ьше не нужно , одновременно искл ючая его из пол ьзовательского интер­
фейса . При этом ссылка устанавливается равной ni l.
Действия
Действия (actions) - это методы, возвращающие объекты с атрибутом
@ I BAct i on, которые сообщают п рограмме I nterface B u i lder, что данн ы й метод
может быть активизирован элементом управления в раскадровке или n i Ь-файле.
Как правило, объявление действия выглядит примерно так:
@ I BAc t i o n f u n c d o S ome t h i n g ( s e n de r : U I B u t t o n )
{ }
Или так:
@ I BAc t i o n f u n c d o S ome t h i n g ( ) { }
Ре � ьное имя метода может быть л юб ы м . Обы ч но действие л ибо не и ме­
ет аргументов, л ибо получает один аргумент, которы й , как правило, имеет имя
s ende r. При вызове метода действия аргумент sender содержит ссыл ку на вы­
звавший его объект. Таки м образом, например, есл и действие было вызвано в
резул ьтате нажатия кнопки, аргумент s ende r содержит ссыл ку на кон кретную
кнопку, на которой произошло нажатие. Благодаря аргументу s e nder сущест­
вует возможность отвечать нескол ьким элементам управления, испол ьзуя оди н
84
ГЛАВА 3 '�1 О С Н О В Ы ВЗАИ М ОДЕ Й СТВ И Я
и тот же метод действи я . Он позволяет идентифицировать элемент управления,
вызвавший метод действи я .
СОВЕТ. На самом деле существует третье , редко используемое объявление метода
действия , которое выглядит так:
@ I BAct ion func doSome t h i ng ( s ende r : U I Bu t t o n ,
forEvent event : U I Event ) { } ;
Этот вид объявл е н и я целесообразно испол ьзовать, если вам нужна дополн ител ьная
и нформация о событи и , порожде н н о м вызва н н ы м методом . Управл яющие события
рассматриваются в следующей главе .
Нет н и чего плохого в том , что м ы объя вил и метод действия с аргументом
s ende r, а потом прои гнорировал и его. М етоды действия в каркасе Сосоа и сис­
теме NeXTSTEP должны получать аргумент s e n d e r независимо от того, ис­
пол ьзуют они его ил и нет, поэтому м ногие програм м ы для систе м ы iOS напи­
саны и менно так.
Разобравшись в том, что такое действия и выходы, перейдем к их примене­
нию при разработке пользовательского и нтерфейса. Однако, прежде чем начать,
необходимо удел ить немного времени воп росам, связан н ы м с наведением по­
рядка.
Разработка контроллера представления
Щел кн ите на файле ViewCoпtro l l e r. sw ift в нави гаторе проекта, чтобы от­
крыть файл реал изаци и . Как види м , выбран н ы й нам и шаблон проекта сгене­
рировал совсем немного шаблонного кода в виде методов vi ewD i d l o a d ( ) и
d i dRe c e i veMemo ryWa r n i ng ( ) Эти методы обы ч но испол ьзуются в подклас­
сах класса U IVi ewCon t ro l l e r, поэтому програм ма Xcode п редоставила нам их
шаблонную реализацию и м ы должн ы просто добавить сюда свой код. Однако
бол ьшая часть этих шаблонных реал изаци й для нашего проекта не нужна, так
что они л и ш ь увел и ч и вают размер файла и затрудня ют чтение. Для того чтобы
при вести реал изацию в порядок, удал и м л и ш н ие фрагменты . В резул ьтате со­
держание файла должно стать таким, как показано в л исти нге 3 .4 .
.
Л истинг 3 . 4 . Упрощен н ы й файл V i e wCont rol l e r . swi ft
i mp o r t U I K i t
c l a s s ViewCon t r o l l e r : U I V i ewCont r o l l e r {
ГЛАВА З � О С Н О В Ы ВЗАИ М О ДЕ Й СТВ И Я
85
Разработка пользовательского интерфейса
Сохран ите в несе н н ы е измене н и я , а затем щел к н ите н а пункте Mai n . story­
board, чтобы открыть п редставление вашего приложения в окне I nterface B u i ld­
er (рис. 3 .4). Как было у казано в п редыдущей главе, белое окно, открывшее­
ся в области редакти рован ия, я вляется еди нстве н н ы м представлением нашего
приложения . Вернувшись к рис. 3 . 1 , легко убедиться, что м ы должн ы добавить
в это представление две кнопки и одну метку.
� • .._ "
'--·-""-"''
•''-"''-·"=..,
ci 11 а. � е ... о • 1:t <
• ......_""'
" 1t�
· · -- �-.-
" ·�-�.�
,,.....
·
"....\О'\
lwtt""""
.....
,� . ,.... ,,,.
• --� 1 -.-.,...,. ia-t ' ts v..w c--. 1c-
"
r 7.,.i:a
ts"•_
"___
. .i:и
1
. .....
.....
... [l'\t� ,_
о • •
Loll...,..,...,_�
-
-
..
• •� v.. e--.
• ....,... 1'"'81 \fllw ­
� ..._ ... ... """'
. ...... .,,.. ,,_ ,,..
u.,. ,... � !�
to- ken · l.llW l'-. lw•
. U!W ..._ ....
(_
.., _
1) !} () u
i c ...... ". ""'°"'8 8t l· C · IQ
-
7t"
+
Рис . З . 4 . Отк р ытие файла Ma i n . s t o r yb o a r d в п р ог р а мме l nte rface B u i l d e r
с р еды Xcode
Подумаем секунду о нашем приложен и и . Мы собираемся добавить в и нтер­
фейс две кнопки и одну метку. Этот процесс очен ь похож на то, что мы делали
в предыдущей главе. Однако теперь м ы хотим испол ьзовать выходы и действия,
чтобы наше приложение стало и нтерактивны м .
Кнопки должн ы запускать методы действия нашего контроллера. М ы могл и
бы сделать так, чтобы вызывал ись разные методы действия, но, поскол ьку о н и
будут вы полнять, по существу, одно и то ж е задание (обновлять текст метки),
нам необходимо вызы вать оди н и тот же метод. Мы будем разл ичать кноп ки с
помощью аргумента s e nder, которы й рассмотрел и выше. Кроме метода дей­
ствия, нам также нужен выход, связан ный с меткой, чтобы мы могл и изменять
текст, отображаем ы й на метке.
Сначала добави м кнопки, а затем разместим метку. Разработав и нтерфейс,
добавим к нему соответствующие действия и выходы. Кроме того, мы могл и
бы вручную объя вить действия и в ы ходы, а затем соедин ить их с элементам и
интерфейса, но среда Xcode сделает это автоматически .
86
ГЛАВА 3 lli О С Н О В Ы ВЗАИ М ОД Е Й СТВ И Я
Добавление кнопок и метода действия
Сначала добави м в и нтерфейс две кнопки. Затем среда Xcode создаст пустой
шаблон н ы й метод действия и м ы с вяжем с н и м обе кно п к и . После того как
пол ьзователь щелкнет на кнопке, будет вызван метод действия и вы пол нен лю­
бой код, который будет в нем записан.
Выберите команду View q Util ities q Show O bject Libra ry или нажм ите ком б ина­
цию клавиш <Control+Option+ X + 3>, чтобы открыть библ иотеку объектов. Вве­
дите в поле поиска б ибл иотеки строку U I B u t t o n . На самом деле достаточ но
ввести тол ько первые буквы u ibu, чтобы сузить сп исок (лучше вводить буквы
в н ижнем регистре, чтобы избежать путаницы при случайном нажатии клавиши
<Sh ift>). После ввода этой строки в окне библ иотеки объектов должен появить­
ся тол ь ко оди н объект: Button (рис . 3 . 5 ) .
�
{ } @ []
Button - lntercept.s touch events and
B utton sond• an action message to а target
object when lt'S tapped.
u -----�
88 � ui ь_
Рис . 3 . 5 . В окне библ и отеки объектов
появляется элемент B utton
Перетащите объект Button из библ иотеки и оставьте его в белом окне облас­
ти редактирован ия, чтобы добавить кно п ку в представление нашего приложе­
ния . Разместите эту кно п ку возле левого края представления на достаточ ном
расстоянии, испол ьзуя вертикаль ную голубую л и н и ю разметки. Для того чтобы
выровнять кно п ку по в ысоте, разместив ее посередине представления, испол ь­
зуйте гор изонталь ную голубую л и н и ю разметки . Есл и это вам поможет, ориен­
тируйтесь на рис. 3 . 1 .
ЗАМЕЧАНИЕ. Голубые л и н и и разметки , которые появл я ются при перемеще н и и объек­
тов в окне п рограм м ы l nterface B u ilder, помогут вам освоить принципы руководства
IOS H u man l nterface G u idelines ( H I G ) . Ком па н и я Apple разработала руководство HIG
дл я л юдей , п роектирующих приложе н и я дл я устройств iPhone и i Pad . Руководство
H I G регламентирует, как следует (и не следует) п роектировать пользовател ьский и н ­
терфейс . Вам необходимо п рочитать его , потому что оно содержит цен ную и нформа­
цию , которую должен знать каждый разработчик приложений дл я устройства i Phone.
Это руководство можно найти на веб-стра н и це h t t p s : / / d e ve l ope r . app l e . сот/
l i b r a r y / i o s / do c ume n t a t i o n / U s e rExpe r i ence /Conceptua l /Mob i l e H I G / .
ГЛАВА З •:i< О С Н О В Ы ВЗАИ М ОДЕЙСТВИЯ
87
Дважды щел кн ите на добавленной кноп ке. Это даст возможность отредакти­
ровать ее название. Назовем эrу кнопку Left.
Выберите команду View q Assistant Ed itorq Show Assistant Ed itor или нажм ите
комбинацию клавиш <Option+X+Return>. В ы можете показывать и скрывать по­
мощн ик редактора, щел кая средней кноп кой в груп пе кнопок Editor, входя щей
в коллекцию из семи кнопок, расположенных в правом верхнем углу окна про­
ектирован ия (рис. 3 .6).
D Ьd О
Button
Рис. 3 . 6 . Кнопка Show the Assistant Ed itor (две ок р ужности )
Помощн и к редактора п оя вля ется в п равой ч асти окна редакти рован и я .
В окне редактирован и я помощни к редактора автоматически откры вает файл
Viewcont ro l l e r . swi ft, я вляющийся файлом реал изаци и контроллера пред­
ставления, владеющего представлением, которое вы видите на экране.
ПОДСКАЗКА. После открытия помощника редактора вам , возможно, понадобится изме­
нить размеры окн а , чтобы было достаточно места для работы . Есл и хотите работать с
маленьки м экрано м , как , например, на ком пьютере MacBook Air, возможно, п ридется
закрыть вспомогательное представление и/или навигатор проекта , чтобы эффективно
работать с помощником редактора ( р и с . 3 . 8 ) . Это легко сделать с помощью трех кно­
пок, расположенных в п равом верхнем углу окна проекта ( с м . рис. 3 . 6 ) .
Среда Xcode знает, что н а ш контроллер представления отвечает з а демон­
страцию представления в раскадров ке, поэтому помощн и к редактора знает, что
должен показать нам реализацию класса контроллера представления, в котором,
скорее всего, будет происходить связывание выходов и действи й . Однако, есл и
все же вы не видите файла, которы й вам нужен, можете перейти на панель быст­
рого перехода в верхней части окна помощника редактора и устран ить проблему.
Сначала найдите сегмент панел и быстрого перехода Aut oma t i c и щел кн ите на
нем . На экране поя вится вспл ы вающее меню, в котором необходимо выбрать
команду ManuaJ q B utton F u n q ViewController. swift. Теперь на экране должен поя­
виться правильный файл .
Попроси м програм му Xcode автоматически создать новый метод действия
для нас и связать его с тол ь ко что созданной кно п кой. Мы добави м эти опре­
деления в расширение класса контроллера представления . Для этого щел кните
на кнопке, добавленной в раскадровку, чтобы она оказалась выбранной. Нажм и­
те и удержи вайте клавишу <Control>, а затем щел кните м ы ш ью и перетащите
курсор с кноп ки на окно помощн и ка редактора. В ы увидите голубую л инию,
88
ГЛАВА 3 1;; О С Н О В Ы ВЗАИ М ОДЕ Й СТВ И Я
которая будет следовать з а курсором (рис. 3 . 8). Эта л и н ия связы вает объекты с
кодом ил и други м и объектами. Когда вы будете nеремещать курсор в nределах
оnределения класса, как nоказано на рис.3 . 8, на экране nоявится всnлы вающее
меню, которое будет информировать вас, что отnускание кноn ки м ы ш и nриведет
к вставке выхода, действия ил и коллекци и выходов.
•
� <
•
"
.itrr ...� • ._.. «
•
"_
11. �
·
... • lot � a w... t!l ·A.. •
�
•"
ГJ О CJ
[\ ('; • (> 8 0
- ..... с.,. 0.1-
• •
8
•
"... _._ ,t.o
Y• C.. - o.fM
...,_ °'""' c;::::i �
---.
-
11
о:
_
-
!!) :
в
в
.
D
о:
... _
..... .'-"'°"...,,..,..
· � А41*. .....
. ......., ,..... _.,.
о :
-
о :
•
8
о ;
о ;
D п 0 а
..... . ...... .... _ ...
&Aton ... " __._.. • • ,...
.-.i ... ... ...
Рис . З . 7 . Для того чтобы видеть окна р едакти р ован и я на небольших дис­
плеях, возможн о , п р идется зак р ыть д ругие п р едставл е н и я
� Вuttonfun /
ВuttotiFun
г
-711
1
IPNine se
B-un , 11 llCl'd
•
g :;;:Q
QO
•
• М.ме) CJ \li_.ne /
VL18'1'
lksttonfun. Roady 1 TOday at i 20 Ptr.t
. '
vi... t 8 L8tt 1 iJi (
) <е. Al.ltom•tic ) • Vi..м:ontro/lilr.l'llllift 1 fl VlitwComto&tr
-·
./
Рис . 3 . 8 . Пе р етаскиван ие ку р со р а в и сходн ый код п р и нажатой клавише
<Contro l > дает возможность создать выход, действие ил и коллекци ю выходов
ГЛАВА 3 ;•,i О С Н О В Ы ВЗАИ М ОДЕ Й СТВ И Я
89
ЗАМЕЧАНИЕ. В настоящей книге мы испол ьзуем действия и выходы , но не колле кции
выходов. Коллекци и выходов позвол я ют соединять несколько однородных объектов с
одни м и тем же свойством N SAr ray, а не создавать отдельное свойство для каждого
объекта .
Д,Ля того чтобы законч ить соединение, отпустите кнопку м ы ш и , и на экране
поя вится вспл ы вающее меню (рис. 3 .9).
V1ew Controller
""""" -----!!!1
Туре i UIButton
Nаом
Storae•
. Гёёnё8СJ
-1
Llt!!•k _:
__
::::::1}
__
Рис. 3 . 9 . Всплы вающее м е н ю , которое поя вляется после перетас­
кивания курсора в исходн ы й код при н ажатой кла в и ш е < Contro l >
Это окно позволя ет настроить новое действие. Щелкните на меню Con nection
и измен ите выбор команды с O utlet на Action . Тем самы м вы сообщите программе
Xcode, что хотите создать действие, а не выход. В результате окно при мет вид,
показанный на рис. 3 . 1 О. В ведите в поле Name строку but ton Pre s s ed. Когда за­
кончите ввод, ие нажимайте клавишу <Retum>. Нажатие клавиши <Retum> при­
ведет к завершению процесса создания выхода, а мы пока не собираемся этого
делать. Вместо этого нажм ите клавишу <ТаЬ>, перейдите в поле Туре и в ведите
в нем строку U I Button, заменив значение AnyOb j ect, заданное по умолчанию.
Outlet
Outlet Collectlon
ObJ '-�Q:l:lli:
:::i::ao=;=--�
Рис . 3 . 1 О. Изменение типа соедин е н и я с Outlet на Action
90
ГЛАВА З fi О С Н О В Ы ВЗАИ М ОДЕ Й СТ В И Я
Н иже поля Туре расположены два поля, которые м ы остави м заполненными
значениями, заданн ы м и по умолчанию. Поле Event позволяет указать, когда бу­
дет в ызван метод. Значение по умолчанию Touch Up I n s ide означает событие,
когда пол ьзователь отнимает палец от экрана над кнопкой. Это стандартное со­
бытие для кнопок. Оно дает пол ьзователю возможность передумать. Есл и, перед
тем как поднять палец, пол ьзовател ь переместит его за предел ы кнопки, метод
не будет вызван .
Поле Arguments позволяет в ыбрать одну из трех разных сигнатур, испол ьзуе­
мых для методов действи я . М ы в ыбрал и аргумент s ender, так что можем ука­
зать, какая кнопка вызвала метод. Это значение задается по умолчанию, поэтому
оставим его неизменным.
Нажмите клавишу <Retum> ил и щелкните на кнопке Con nect, и программа
Xcode вставит метод действия. Для файла Vi ewCont ro l l e r . swi ft в окне по­
мощни ка редактора это будет выглядеть так, как показано в листи нге 3 .5 .
Л истинг 3 . 5 . Файл Vi ewCont r o l l e r . swi ft с добавлен н ы м действием I BAc t i on
i mp o r t U I K i t
c l a s s V i ewCo n t r o l l e r : U I V i ewCon t r o l l e r {
@ I BA c t i o n f u n c b u t t o n P r e s s e d (
)
s e n de r : U I Bu t t o n ) {
П рограм ма Xcode не только добавила объя вление метода в код, но и связала
кнопку с эти м методом, сохран и в эту и нформацию в раскадровке. Это знач ит,
что нам не надо делать что-л ибо еще, чтобы кнопка вызвала этот метод при
выпол нен и и приложения .
Вернитесь к файлу Ma i n . s t o r ybo a r d и перетащите на его окно другую
кнопку, на этот раз поместив кнопку в правой части экрана. На экране появятся
голубые л и н и и, помогающие сориентировать кнопку по отношению к правому
краю и другой кнопке. Помести в ее в требуемое место, дважды щел кните на
ней и измените ее и м я на Right.
ЗАМЕЧАНИЕ. Вместо перетаскивания нового объекта из библиотеки можно нажать кла­
вишу <Option > и перетащить на представление оригинальный объект ( в данном при­
мере это кнопка Left ). Удерживание кнопки < O ption > заставляет п рограмму lnterface
B u i lder скопировать перетаскиваем ы й объект.
Пока м ы не хотим создавать нов ы й м етод действ ия . В место этого свяжем
эту кноп ку с существующим методом , создан н ы м програм мой Xcode. Изме­
н и в имя кнопки, н аж м ите клав ишу <Contro \>, щел кн ите на новой кнопке и
снова перетащите ее на заголовоч н ы й файл . На этот раз, когда ку рсор до­
сти гнет объя вле н и я метода but t o n P r e s s e d ( ) , этот метод будет подс вечен
91
ГЛАВА 3 11 О С Н О В Ы ВЗАИ М ОДЕ Й СТ В И Я
и н а экране поя в ится вспл ы вающее о к н о Connect Action ( р и с . 3 . 1 1 ). Есл и вы
не у в идите это окно сразу, перетаски вайте у казател ь мыши по кру гу до тех
пор, пока оно не поя вится . Когда у видите это окно, отпустите кноп ку м ы ш и,
и программа Xcode соеди н ит эту кноп ку с существующи м методом действи я .
В резул ьтате при н ажатии к н о п к и будет в ызван тот ж е метод, что и для дру­
гой кнопки.
•
� <
•
A, l!Мч>nf.... " .._ 6(
• ..,._,.,_.
&- . ..... " . .... ...1 8 ""--"-
•
•
-
в
в
•
-�
-- -
Jwot 8w1itМt 1'.0
т.... с-
ф:
в
в
- °"""'"
-
), ".
•
•
о:
о:
_"_
_......, � '-"()\ ......
· � .... ....
�--
. ..... ..... .....
тt-.- lololW
... c:i.nttlll
•
-
о:
е:
-
- p -q
tJ ... о
D О G> о
8
8
о�
о :
в
"
о
Рис. 3 . 1 1 . Перетаскивая существующее де й ств и е , можно установить связь
между н и м и кноп кой
Добавление метки и выхода
Находясь в библ иотеке объе ктов, введите в поле поиска слово lab, чтобы
найти элемент интерфейса Label (рис. 3 . 1 2). Перетащите метку на свой пол ьзо­
вател ьский интерфейс и поместите где- н ибудь между двумя кноп кам и . Затем,
используя маркеры масштабирован ия, растя н ите метку от левого края ( отме­
чен ного голубой л и н ией) до правого. Это обеспечит достаточно места для тек­
ста, которы й будет вы веден для пол ьзователя .
П о умолчанию метки выравни ваются п о левому краю, н о нашу метку м ы
хотим отцентровать. В ыберите команду ViewQ UtilitiesQ Show Attributes l nspector
(или нажм ите комби нацию клавиш <Option+X +4>), чтобы открыть окно и н ­
спектора атрибутов (рис. 3 . 1 2 ). Выберите метку, а затем найдите в и нспекторе
атрибутов кнопки Alignment. Выберите среднюю кнопку Alignment, чтобы отцен­
тровать текст метки .
92
ГЛАВА 3 п О С Н О В Ы ВЗАИ М ОДЕ Й СТВ И Я
La bel statlc text.
Label - А varlaЫy slzed amount of
88
�-1 а_ь
_
_
_
_
_.__
о
_
Рис. 3 . 1 2 . М етка в библиотеке объектов
о ЬJ о
LaЬel
_в
Text ( Plaln
�;;i;e 1 _ ==
- J Default
- _в
Color 1
+
,..----- !!.:О
Font 1 System
_
::в1
Alignment , !В"
Llnes
[
___ _
Behavlor 8 EnaЫed
("' Hlghlighted
Align B��!n e�-
Basellne
-·-·_JJ
,_8
Llne Breaks l_!r�_!'Ca.!!_ Tall ___
�
Autoshrlnk
Fixed Font Size
О Tlghten Letter Spacing
+
+
Hlghlighted ,
Shadow
\ Defa�. _.8
C2::J 1 D efault
__
R
Рис . 3 . 1 3 . Испол ьзова н и е инспе ктора атр и ­
буто в м етки дл я центри рова н и я те кста м етки
Мы не хотим, чтобы на кнопке было что-нибудь написано, пока пол ьзователь
ее нажмет, поэтому дважды щел кн ите на метке (чтобы выбрать текст) и нажм ите
клави шу <Delete>. В результате текст, приписан н ы й к кнопке в данный момент,
будет удал е н . Нажм ите клав ишу <Return>, чтобы подтвердить исправления .
ГЛАВА З 1" О С Н О В Ы ВЗАИ М ОДЕ Й СТВИЯ
93
Даже есл и вы не видите метку, когда она не выбрана, не бесnокойтесь - она
на месте.
СОВЕТ. Если и нтерфейс содержит невиди м ые элементы , например пустые метки , и в ы
хотите и х увидеть , выберите команду Canvas из меню Editor, а затем во всплывшем
подменю установите флажок Show Bounds Rectangles. Есл и вы просто хотите вы­
дел ить невиди м ы й элемент, щел кните на п и ктограмме в окне Document Outline.
Осталось тол ько создать выход для метки . Эта процедура ничем не отл ича­
ется от предыдущей. Откройте помощн и к редактора и файл ViewContro l l e r .
s w i f t . Есл и возни кнет необходимость перекл юч ать файл ы , воспол ьзу йтесь
вспл ы вающим меню на панел и быстрого перехода, расположенным над помощ­
ником редактора.
Затем выбер ите метку в програм ме l nterface B u i lder и, нажав клавишу
<Control>, перетащите курсор от метки к заголовоч ному файлу. Установите его
точ но на требуемом методе действия. Увидев окна, показан ные на рис. 3 . 1 4, от­
пустите кнопку мыши, и вы с нова увидите вспл ы вающее окно (см . рис. 3 .9).
В.UttonFun
B."n ' t M ... d ·
IPhone 81
M".J
!! Vl".e
ButtonFun: Ready 1 Today at 8:Н5 АМ
Vl."r
View
L L1bel 1 В8
�' Autamatlc
,,.
VJewControllec.swift , No Se1ection
8 ID
u
о
Рис . З . 1 4. Свя з ы ва ние выхода U l label
М ы хотим создать выход, nоэтому оставим ти п C o n n e c t i o n дл я объек­
та Out l e t , задан н ы й по умолчанию. Для того чтобы выбрать информативное
имя для выхода, вспом ним его н азначение. В ведите слово s t a tus Label в поле
Name. Оставьте в поле Туре значение U I LaЫe. В последнем поле Storage значе­
ние можно оставить по умолчанию.
Нажм ите клави шу <Return>, чтобы nодтвердить изменения, и програм ма
Xcode вставит свойство выхода в ваш код. Заголовочн ы й файл контроллера бу­
дет содержать код, представлен н ы й в листин ге 3 .6 .
ГЛАВА З !S! О С Н О В Ы ВЗАИ М ОДЕ ЙСТВ И Я
94
Л и стинг 3 . 6 . Добавление выхода метки в класс Vi ewcont ro l l e r
irnpo r t U I K i t
c l a s s V i ewCon t r o l l e r : U I V i ew C o n t r o l l e r {
@ I BOu t l e t w e a k va r s t a t u s Labe l : U I L ab e l !
@ I BAc t i on f u n c b u t t o n P r e s s e d ( s e nde r : U I B u t t o n )
}
Теперь у нас есть выход, и п рограм ма Xcode должна автоматически соеди­
н ить с н и м нашу метку. Это знач ит, что есл и мы изм е н и м значе н ие вы хода
s t a t u s Labe l в коде, то это отобразится на метке в пол ьзовател ьском и нтер­
фейсе. Есл и м ы изменим свойство te xt для выхода s t a t u s Labe l, то на экране
изменится текст на метке.
АВТОМАТИЧЕС КИЙ ПОДСЧЕТ ССЫЛО К
Если вы знаете язык Objective-C или читали предыдущие издания настоящей кни ­
ги , т о могл и заметить, что м ы не использовал и м етод de a l l o c . Мы никогда н е
удалял и из памяти н а ш и переменные экземпляров.
Комп илятор LLVM , который компания Apple встроила в программу Xcode, настоль­
ко разумен , что освобождает объекты самостоятельно, используя новую функцио­
нальную возможность под названием Automatic Reference Counting (ARC ) .
Механизм ARC применяется только к объектам языка Swift и структурам , н о н е к
объектам каркаса Core Foundation или объектам , размещенным в памяти с помо­
щью функции rna l l o c ( ) или подобных ей функци й . Есть еще несколько тонкостей
и ловушек, но в целом управление памятью вруч ную осталось в прошлом .
Более полную информацию о механизме ARC можно найти по адресу h t t р : / /
d e v e l o p e r . a p p l e . c orn / l i b r a r y / i o s / # r e l e a s e n o t e s / Ob j e c t i v e C /
RNT r an s i t i o n ingToARC /
Механизм ARC хорош , но не всемогущ. Необходи мо хорошо понимать основные
правила управления памятью в языке Objective-C, чтобы избежать неприятносте й .
П равила управления памятью в языке Objective-C можно найти в документе Memory
Management Programming Guide, который ком п а н и я Apple поместила на веб­
странице h t tp s : / / deve lope r . app l e . сот/ l i b r a r y / i o s / docurne n t a t i o n /
Cocoa/Conceptual /Merno r yMgrnt /Art i c l e s / Merno ryMgrnt . h trnl .
Создание метода действия
Итак, мы разработал и пол ьзовател ьски й и нтер ф ейс и связал и между собой
его выходы и действи я . Осталось только применить эти действия и выходы для
того, чтобы измен ить текст на кнопке при ее нажатии . Щел кните м ы ш ью в окне
навигатора проекта на ф айле ViewCont ro l l e r . swi ft, чтобы открыть его. Най­
дите пустой метод buttonPre s s ed ( ) , создан н ы й програм мой Xcode.
ГЛАВА 3 !f О С Н О В Ы ВЗАИ М ОДЕЙ СТВИЯ
95
Дr�я того чтобы наш и кнопки отличались одна от другой, будем испол ьзовать
параметр s e nde r. М ы извлечем название нажатой кнопки из параметра s ender,
создадим строку на основе этого значения и присвоим его тексту метки. Изме­
ним метод bu t t o n P re s s ed ( ) так, как показано в л истин ге 3 . 7 .
Листи нг Э . 7 . Завершение метода действия
@ I BAc t i o n f u n c b u t t o n P r e s s e d ( s e nde r : U I Bu t t o n )
l e t t i t l e = s ender . ti tl e ( for :
let text =
. se l e c ted) !
" \ ( ti tl e ) but ton pre s sed"
s ta tus LaЬel . text = text
Это довол ьно просто . Первая инструкция этого фрагмента извлекает на­
зван ие кнопки из параметра s e n d e r . Поскол ьку кнопки могут и меть раз­
ные названия в зависимости от текущей с итуаци и , м ы испол ьзуем параметр
U I Cont r o l S t a teNorma l , чтобы указать, что нам нужно название кнопки в ее
нормал ьном, не нажатом состоя н и и . Это тип и ч н о для всех элементов управ­
ления (а кноп ка - это оди н из элементов управления). Состоя ния элементов
управления рассматриваются в главе 4.
СОВЕТ. Возможно, вы заметил и , что при вызове метода t i t l e ( for : ) м ы использова ­
ли аргумент . s e l e c t e d , а не U I Co n t ro l S t a t e . s e l e c t ed. По правилам языка Swift
аргумент должен быть одн им из значений перечисления U I Cont r o l S t a t e , поэтому
мы можем пропустить имя перечислени я , чтобы сэконом ить кол ичество набираемого
текста .
Следующая инструкция создает новую строку, добавляя к назван и ю кнопки
слова but ton pre s s ed. Таки м образом, если речь идет о левой кнопке, которая
имеет назван ие Left, то при ее нажатии эта строка програм м ы создаст строку
Le ft but t on Pre s s ed. Эта новая строка присваивается свойству метки t e x t .
Вот так изменяется текст на метке п р и е е нажати и .
Тестирование п риложения Button Fun
Выберите команду Productr:::> Run. Есл и ком п илятор ил и редактор связей вы­
даст ошибки, верн итесь в окно редактирования и сравните свой код с текстом
в главе . Есл и ком п иля ция прошла без ош ибок, то программа Xcode запустит
симулятор устройства i Phone и выпол н ит приложение. Когда вы нажмете левую
кноп кJ', то экран должен выглядеть так, как показано на рис. 3 . 1 5 .
На первый взгляд, все в порядке, но есл и пригл ядеться, то обнаружится,
что чего-то не достает. Для того чтобы увидеть, чего и мен но, измените теку­
щую схему, как показано на рис. 3 . 1 6, на i Phone SE и снова запустите прило­
жение.
Снимок экрана, rюказанный на рис. 3 . 1 7, свидетельствует о проблемах. Левая
кнопка работает, как надо, но сдвинута вправо, а правая кнопка вообще исчезла.
96
ГЛАВА 3 �1; О С Н О В Ы В ЗА И М ОД Е Й СТВ И Я
"
Carrler •
left
iPhone 6s - IOS 10.О (14A5261u)
8:47 АМ
Left button pressed
-
Right
Рис. 3 . 1 5 . Запуск приложе н и е на i P h o n e бs
Для того чтобы понять, почему это происходит, перейдите в среду Xcode
и щел кните правой кнопкой в нижней части окна l nterface Bui lder, чтобы вы­
дел ить его и увидеть макет, а затем под окном в ыберите команду View As for
i Phone SE, как показано на рис. 3 . 1 8 . Поскол ьку м ы настроили наш макет на
устройство с более кру п н ы м экраном, при переходе на устройство с меньшим
экраном некоторые элементы управления смещаются со своих позиций на но­
вом дисплее.
Решение п роблем с п омощью механизма Auto Layout
Левая кнопка находится на правильном месте, а метка и другая кнопка нет. В главе 2 м ы исправил и подобную проблему с помощью механ изма Auto
Layout. Идея механизма Auto Layout закл ючается в испол ьзован и и огран ичений,
задающих место расположения элемента управления. В дан ном случае м ы хо­
тим добиться следующего.
ГЛАВА 3 :�; О С Н О В Ы ВЗАИ М ОДЕЙСТВИЯ
Doiif�C
>
8uttonfun )
'
ButtonF\
1
!
о
.J
•
1
1
1 МoilyalPhone 6$
'tl. Hd Or-!}' O@ '
}' Generlc IOS Devlce
roduct
�rd
1
Debug
Sc
Finished ruмlng But
(В.sе) ) No Selectlon
iPad Ak
IPad Ak 2
IPad Pro (9. 7 lnch)
8 iPad Pro (12.9 lnch)
IPad ReUne
IPhone Б
IPhone бs
1Phone 6
IPl\one 6 Plus
iPhone 6s
IPhone 88 Plua
Add Addltlonal Slmulators."
Download Slmul1tora".
Рис. З . 1 6 . Изменение схе м ы и целе вого устройства
на устройство с други м и размерами и формой
Carrler ?
- � 10,0 114A5281u)
9:1О АМ
Left button pressed
Left
Рис . 3 . 1 7 . На другом устрой ­
стве макет и скажается
97
98
ГЛАВА 3 lli О С Н О В Ы ВЗАИ М ОДЕ ЙС Т В И Я
8
А ButtonFun )
IPhone SE
8._n ) 1 M".d ) 1 М".) ) m Vl".e )
•
Vi".r )
Flnlshed runnlng В•
View ) В Right
lil
-
LeH
[]
Vlew as: iPhone SE (wC h R)
D D,.g o o o 1 9..2
75%
+
е!!3 IB foj fдi
Vary for Traits
Рис. 3 . 1 8 . На э кране с м е н ь ш и м экраном п равая кнопка
становится невидимой
��
Кнопка Left должна быть отцентрована по верти кал и и располагаться бл и­
же к левому краю экрана.
�
Кнопка Right должна быть отцентрована по верти кал и и рас полагаться
бл иже к правому краю экрана.
ГЛАВА 3 �! О С Н О В Ы В ЗА И М ОДЕЙСТВИЯ
99
Метка должна быть отцентрована no горизонтал и и нем ного отстуnать от
верхнего края экрана.
Каждое из nриведенных в ы ше утвержден и й содержит два огран ичения одно касается огран ичения no верти кал и, а другие - no горизонтал и . Есл и nри­
менить эти три огран ичения ко всем трем наш и м nредставлениям, то механ изм
Auto Layout автоматически разместит эти элементы в правил ьных местах л юбо­
го экрана. Как же нам это сделать? Мы можем добавить огран ичения механизма
Auto Layout в nредставления, создав э кземnляры класса N S LayoutCon s t ra i n t .
В некоторых ситуациях это еди нстве н н ы й способ создания nравил ьного макета,
но в дан ном случае (как и во всех остал ьных примерах, при веденных в книге)
nравил ьный макет можно создать с помощью програм м ы I nterface Bui lder. Эта
nрограм ма nозволяет визуально добавлять ограничения с nомощью nеретаски ва­
ния и щел чков м ы шью. Перейдите в окно View As, расположенное под окном 1 8,
и снова выберите устройство бs в качестве целевого, чтобы увидеть все элемен­
ты уnравления. Затем задайте коэффициент м асштабирован ия, наnример 75%.
Механ изм Auto Layout можно nри менять и для настройки макетов на другие
устройства (см . рис. 3 . 1 9).
Начнем с nозиционирован ия метк и . Выберите nун кт Main. storyboard в окне
навигатора nроекта и откройте окно Document Outline, чтобы увидеть иерархию
nредставлен и й . Найдите n и ктограмму с меткой View. Она с и м вол изирует конт­
роллер главного nредставления по отношению к которому м ы должны nозици­
онировать другие nредставления . Щелкните на треугол ьнике раскрытия, чтобы
открыть n и ктограмму View, есл и она еще не открыта, и найдите две кноnки
(с метками Left и Right) и метку. Проведите соединительную линию от метки к
родител ьскому nредставлению, как nоказано на левой nанел и рис. 3 .20.
Перетаски вая указател ь м ы ш и с одного nредставления на другое, вы сооб­
щаете nрограм ме I nterface B u i lder, что хотите применить к н и м огран ичения
механизма Auto Layout. Отnустите кноnку мыши - и на экране nоя вится серое
вспл ы вающее окно с множеством команд (рис. 3 .20). Каждая из этих команд
nредставляет собой отдел ьное огран ичение. В ыбрав л юбую из этих команд, вы
nрименяете соответствующее огран ичение. Однако, как нам известно, нам не­
обходимо nримен ить к метке два ограничения, причем оба о н и есть в сnиске
команд всnлы вающего меню. Для того чтобы nрименить сразу нескол ько ог­
раничений, необходимо нажать и удерживать клавишу Shift, выбирая соответ­
ствующие команды . Итак, нажм ите клавишу Shift и выберите команды Center
Horizontally in Container и Vertical Spacing to Тор Layout Guide. Для того чтобы эти
ограничения были действительно применены, щелкните м ы ш ью в любом месте
за nределам и вспл ы вающего меню или нажм ите клавишу <Retum>. После этого
созданные вам и огран ичения nоя вятся в разделе Constraints в окне Document
Outline, а также будут nредставлены визуал ьно в раскадровке, как показано на
рис. 3 .2 1 .
1 00
ГЛАВА З �' О С Н О В Ы ВЗАИ М ОД Е Й СТВ И Я
•
fJ8
<
) 11 ButtonFun )
А ButtonFun )
В." ) 1 ".
) 1 . ) !m . ) (} ". ) .
"
11
"
§
о
о
IJ
Lcf\
75%
View as: iPhone 6s (wC n R)
000000 Оо
Device
View ) L Status LaЬel
"
•
�
Finlshed running 81
IPhone se
+
_J
_va_ry for Tralts
Orlenюtiof\
Рис. З . 1 9 . Дл я настройки м а кета на друг и е устройства с п о м ощью
меха н и з м а Auto Layo ut мы и спол ьзуе м то устро й ств о , дл я которо­
го мы и з начал ь н о созда вал и свое п р иложе н и е
•
•
•
8 <
>
ButtonFun
А ButtonFun )
)_
ButtonFun
' 1!!1 Vlew Controller Scene
т (
Vlew Controller
:
.
.
в,
L
ф First R
(G Exlt
ГЛАВА З t� О С Н О В Ы ВЗАИ М ОДЕЙСТВИЯ
iPhone SE
Finished
) 1 Main.storyboard ) 1 Main.storyboard ( Base)
§
Leading Space to Container Margin
·rгa1li11g Spaco tu Container Margi"
Ve rtical Spacing to Тор Layo1Jt Guide
Vertical Spacirig t o Bottom Layout GtJicfe
Center Horizontally in Coritainer
Center Vm1ic a l l y 1n Con t a 1 11er
t: q u a l Wid ths
Equal Hcights
Aspec l Ratio
-7
1
Left
Рис . 3 . 20 . П о з и ци о н и рова н и е м етки с п о м о щью о гран и ч е н и й
Auto Layo ut
. -t,.,.. llDr ."WI WN" ... "
.,,.
. ""' ...
.... �"
•
• ll Yltw c.t,.., 1"'"8
"
".. �
- - ----- -
Ttci LWOlll Oulde
. -
• 11
' ""
11 •:;111
L '�LtUiei
• 8Gonti:•-i•
. ""\Мtl,.ancier
111 •"
$C8ytlo8r1f •мr, P.iм
- -]
�-----т----;�
о !
Q
1
1�
�1
Left
Rtght
Рис. 3 . 2 1 . Два огран и ч е н и я Auto Layo ut, п р и м е н я е м ы е к м етке
1 01
1 02
ГЛАВА З �. О С Н О В Ы В ЗАИ М ОД Е Й СТВ И Я
ПОДСКАЗКА. Есл и , создавая ограничен и е , в ы сделали ошибку, удалите его , щел кнув на
его представлении в окне Document Outline, или удал ите его из раскадровки , нажав
клавишу < Delete> .
Вероятно, вы заметил и, что кнопка имеет оранжевый контур. Этим цветом
програм ма I nterface Bui lder отмечает возникновение проблем ы в механизме,Аutо
Layout. Существует три вида типичных проблем, о которых сообщает програм­
ма l nterface, рисуя оранжевый контур.
i l<
В ы задал и недостаточ ное количество ограничений для того, чтобы точ но
указать позицию ил и размер представления.
N.
Вы задал и неоднозначные ограничения, т.е. они задают размер ил и пози­
цию не единственным образом .
м
Ограничения я вляются правиль н ы м и, но позиция и/ил и размер представ­
ления во время вы пол нения программы не совпадает с соответствующей
позицией и/ил и размером в программе in l nterface Builder.
Получ ить более подробную и н формацию о проблеме можно, щел кнув на
оранжевом треугол ьнике в окне Activity View в нави гаторе проблем (см . левую
часть рис. 3 .2 1 ). В резул ьтате вы увидите строку "Fгame fог ' Label' will Ье different
at run time" ( Рамка объекта ' Labe l ' во время выпол нения приложения будет дру­
гой), сообщающую о проблеме третьего вида. Это сообщение можно стереть,
сделав так, чтобы программа l nterface B u i lder переместила метку на правил ьную
позицию и задала ее правильные размеры. Для этого обратите вни мание на ре­
дактор раскадровок, расположе н н ы й в правом н ижнем углу. Вы видите четыре
кнопки, показанные на рис. 3 .22.
Vary fo r Tra its
--
-
-
.
Рис . 3 . 22 . К н о п к и м ехан и з м а Auto Layo ut в
п равом н иж нем углу редактора раскадровок
Вы можете узнать, что делает каждая из этих кнопок, задержав указател ь
м ы ш и над н и м и . Левая кнопка связана с элементом управления U I StackView, ко­
торую м ы будем рассматривать в главе 1 О. Переходя слева направо, переч ислим
их фун кци и .
1 . Кнопка Align позволяет выровнять выбран ное представление относител ьно
другого представления. Щел кнув на этой кнопке, вы увидите вспл ы вающее
ГЛАВА З �: О С Н О В Ы ВЗАИ М ОДЕЙСТВИЯ
1 03
меню, содержащее разные варианты в ырав н и ван и я . Одна из этих кно­
пок
Horizontal Center in Container
соответствует ограничению, которое
уже применялось к метке в окне Document Outl ine. Как правило, одну и
ту же фун кцию механизма Auto Layout в программе l nterface Bui lder мож­
но вы пол н ить нескол ькими способам и . По мере чтения книги вы узнаете
ал ьтернативные способы выполнения задач, связан ных с использованием
механизма Auto Layout.
-
-
2. Вспл ывающее меню для кнопки Pin содержит команды, позволяющие зада­
вать позицию представления относител ьно других представлений и приме­
нять ограничения размеров. Например, можно задать огран ичение, требую­
щее, чтобы высота одного представления совпадала с высотой другого.
3. Кнопка Resolve Auto Layout lssues позволяет решать проблемы, связанные
с макетом . Меню, соответствующее этой кнопке, содержит команды, позво­
ляющие удалять все ограничения, установленные для представления (или
всю раскадровку), выяснять, какие ограничения пропущены, и добавлять
их, а также уточ нять рам ки одного ил и нескольких представлений, которые
должн ы применяться на этапе выпол нения приложения.
Изменить рам ку метки можно, выбрав ее в окне Document Outline или в рас­
кадровке и щел кнув на кнопке Resolve Auto Layout lssues. Вспл ы вающее меню
для этой кнопки содержит две идентичные группы операций (рис. 3 .23).
S,1>fe\.. I li\d V 1t>'l'I
U pd ate Frames
U pdate Constraints
Add M 1ss1нg Constramts
Reset to Suggested Co nst ra ints
Clear Constraints
'\': -0-81=
Alt Views in View Controller
U pdate Frames
U pdate Constraints
Add M issing Constraints
Reset to Suggested Constraints
Clear Constraints
Рис . 3 . 23 . Вспл ы вающее м е н ю для кнопки
Resolve Auto Layout l ssues
ПОДСКАЗКА. Если все команды вспл ывающего меню недоступ н ы , щел кните на м етке в
окне Document Outl ine, чтобы обеспечить возможность их выбора .
ГЛАВА 3 � О С Н О В Ы В ЗАИ М ОДЕ Й СТВ И Я
1 04
Команды из верхней части м е н ю относятся тол ько к текущему представле­
н и ю, а команды из н ижней части меню - ко всем представлен иям, связанным
с контроллером п редставлен и й . В данном случае нам просто необходи мо испра­
вить рам ку метки, поэтому м ы выберем команду U pdate Frames в верхней части
меню. После этого выберем оранжевый контур и треугольник предупреждения в
окне Activity View, потому что теперь во время выпол нения програм м ы метка бу­
дет находиться на правил ьной позици и и иметь правил ь н ы й размер. Фактически
ширина метки будет уменьшена до нуля и будет представлена в раскадровке как
маленький пустой квадрати к (рис. 3 .24) .
'
I
•
CS Vltw Controler Sc.n•
т
Vlew Con1rohr
Тор L•yout Guide
8o«om Leyout Gulde
•
Vtew
в ..."
8 Rlght
•
Lf1§bl66.I
(; Constr•lnts
В1 Stalut LAЬel.c:.nt8tX • с,_
• Statvs laЬel.iop • Тор L .
ф Arst Responder
IJ: Exit
7 S1orytюard Entry Poln1
-
Рис . 3 . 24 . П осле и с п ра вл е н и я контура ш и ри н а к н о п к и ум е н ьш илась до нул я
Можно л и это считать правил ь н ы м ? О казы вается, можно. Многие из пред­
ставлений, поставляемых в библ иотеке U I K it, вкл ючая класс U ! Labe l, позволя­
ют механ изму A uto Layout выч исл ять их размер по их реал ьному содержимому.
Это возможно благодаря вычислению естественного (natural), ил и действител ь­
ного (intriпsic), размера их содержи мого. С точ ки зрения действител ьного разме­
ра ш ирина и высота кно п ки вполне достаточ ны, чтобы на ней поместился текст
ее назван ия. Пока у кнопки нет н азвания, высота и ширина кнопки действител ь­
но равны нулю. Когда мы запустим прил ожение и щел кнем на одной из кнопок,
ее действител ь н ы й размер будет изменен и м ы увидим весь текст.
Исправ и в недостатки метки, перейдем к уточ нению позиций двух кнопок.
Выберите кнопку Left на раскадровке и щел кн ите на кноп ке Al ign в правом ниж­
нем углу окна редактора раскадровки (последняя слева кнопка на рис. 3 .22).
Мы хоти м, чтобы кнопка была отцентрована по вертикали, поэтому выберем
команду Vertical Center in Container во вспл ы вающем меню и щел кнем на кнопке
Add 1 Constraint (рис. 3 .2 5 ) .
Это ж е огран и чение необходимо применить к кнопке Right, поэтому выберем
ее и повторим оп исан н ы й процесс. В этом случае програм ма I nterface Bui lder
выявит нескол ько новых проблем, которые будут выделены оранжевым цветом
ГЛАВА Э 11.1 О С Н О В Ы ВЗАИ М ОДЕ Й СТВ И Я
в раскадров ке
1 05
и отмечены треуголь н и ком предупреждения в окне Activity View .
Щел кн ите на этом треугол ь н и ке. чтобы узнать о причинах ошибок, обнаружен­
ных навигатором проблем (рис. 3 .26).
Add New Allgnment Constralnts
m .. .eading <.dgt:s
1) Гra11ir1g l:: d ges
f!'iD Тор Eages
1!1!1 Bottom Edgc1$
"'
9 Horizontal Centers
(i8 Vertical Centers
(i8 8ase!ines
"'
"'
1 9 Horlzontally in Contalner
J LI (i8 Vertically in Container
U pdate Frames (}furie
"'
"
:!
l с=
Add 1 Constraint
Рис . 3 . 2 5 . Центрова н и е п редста вл е н и я по в е р ­
ти кал и с п о м о щью вспл ы вающе го м е н ю Align
•
•
' ' А ButtonFun )
•
l:фjAifфM Runtime
А ButtonFun 2 lssues
•
AmЫguous Layout
Horizontal posltion is amЫguous
tor "Left•.
Main.�torybo�rd
Horizontal po sltion is amЫguous
for "Right".
Main.storyЬoard
Рис . 3 . 2 6 . П редуп режде н и е п рогра м м ы l nte rface
B u i l d e r об отсутств и и огран и ч е н и й
1 06
ГЛАВА 3 � О С Н О В Ы ВЗАИ М ОДЕ Й СТВ И Я
П рограмма l nterface B u i lder предупреждает о том, что горизонтал ьные по­
зиции обеих кнопок заданы неоднозначно. Фактически у нас нет ограничений,
управляющих горизонтал ь н ы м и позиция м и кнопок, поэтому предупреждение не
ДОЛЖНО нас уди вл ять.
ЗАМЕЧАНИЕ. Задавая ограничения Auto Layout, вы будете часто получать подобные ,пре­
дупреждения . Они необходимы дл я того , чтобы вы задал и пол н ы й набор ограничений .
П о завершении п роцесса разметки вы не должны получ ить н и одного предуп режде ­
н и я . Большинство примеров в этой книге содержат и нструкции для задания огран иче­
ний разметк и . Добавляя эти ограничен и я , вы, конеч но , должны учиты вать предупреж­
ден и я , но беспокоиться стоит, тол ько есл и они появляются после завершения всего
п роцесса разметки . Это будет значить, что вы пропустил и какой-то шаг, выполнили
его неправильно или в книгу в кралась ош ибка ! В последнем случае , пожалуйста , со­
общите об ош ибке по адресу www . apres s . с о т .
Мы хоти м, чтобы кнопка Left находилась на фиксирован ном расстоя нии от
левого края родител ьского представления, а кнопка Right
на том же расстоя­
нии от его правого края . Эти огран и чения можно задать с помощью вспл ы ваю­
щего меню, связан ного с кнопкой Pin (следующей за кнопкой Align на рис. 3 .22).
Выберите кнопку Left и щел кн ите на кнопке Pin, чтобы открыть ее вспл ы ва­
ющее меню. В верхней части меню вы найдете четыре поля редактирован ия,
связанных с маленьким квадратиком с помощью оранжевых пунктирных линий,
показанных на левой части рис. 3 .2 7 . Маленький квадратик представляет кноп­
ку, для которой задаются ограни чен ия . Четыре поля редактирован ия позволяют
задать расстоя ние он кнопки от бл ижайших соседей над и под ней, а также
слева и справа от нее. Пунктирная л и н ия означает, что соответствующего огра­
ничения пока нет. Мы хотим , чтобы кнопка Left находилась на фиксированном
расстоя н и и от левого края своего родител ьского представления, поэтому щел к­
нем на пунктирной оранжевой л и н и и , идущей влево от квадрата. В этом слу­
чае она станет сплошной оранжевой л и н ией, означающей, что соответствующее
огран ичение уже установлено. Затем введем ч исло 3 2 в левое поле редактиро­
вания, чтобы задать расстоя ние от кнопки Left до его родител ьского представ­
ления . Вспл ы вающее меню должно стать таким, как показано на правой части
рис. 3 .22. Нажмите кнопку Add 1 Constraint, чтобы применить это огран ичение
к данной кнопке.
Для того чтобы исправить позицию кнопки Right, выберите ее, нажм ите
кнопку Pin, щелкните на пунктирной оранжевой л и н и и , идущей вправо от квад­
рата (поскол ьку м ы хотим зафиксировать расстоя ние от кнопки до правого края
ее родител ьского представления), в ведите ч исло 3 2 в поле редакти рован ия и
нажм ите кнопку Add 1 Constraint.
Теперь мы применили все необходимые ограничения, но предупреждения в
окне Activity View не исчезл и . Анализ показы вает, что на этапе вы пол нения при­
ложения кнопки будут располагаться неправил ьно. Для того чтобы исправить эту
проблему, необходимо нажать кнопку Resolve Auto Layout l ssues. В резул ьтате
-
ГЛАВА 3 � О С Н О В Ы В ЗАИ М ОДЕ Й СТВ И Я
1 07
откроется вспл ы вающее меню, в котором надо выбрать команду U pdate Frames
в нижнем разделе. Это ограничение будет касаться рамок всех представлений в
настраиваемом контроллере представлен и й .
j
1
J
!
l
298
13�
j
I
� : О . 264
319
Spaclng to nearest neighbor
11 Constraln to marglns
(i) Width
J 'i WJ Helght
1
1
Add New Conatralnts
�·
30
30
&il Eq11al Wldth&
11) fq<Jal He1ghts
П 1§1 Aspect Ratlo
lm Al:gn 1 i:ёё"�nqEdges
Update Frames (�N=on=e===========
1
. q
, ;гёofiSi�iinis -
-
Рис . З . 27 . В ы ра в н и ва н и е п р едставл е н и я по го ри з о нтал и с п о м ощью вспл ы ­
вающе го м е н ю P i n
ПОДСКАЗКА. И ногда в о всплы вающем м е н ю не в с е ком а нды я вля ются доступ н ы м и .
В этом случае выберите п и ктограмму View Controller в окне Document Outl i ne и
попытайтесь снова .
Теперь предупреждения должн ы исчезнуть и разметка будет, наконец, завер­
шена. Запустите свое приложение на симуляторе устройства i Phone
и увидите
резул ьтат, очень похожий на рис. 3 . 1 , помещенный в начал е главы . Коснувшись
правой кнопки, вы должны увидеть заголовок кнопки Right button pressed . Кос­
нувшись левой кнопки, вы должны увидеть заголовок кнопки Left button pressed .
Запуетите приложение на си муляторе i Pad, и обнаружите, что макет все еще
работает, хотя кнопки расположе н ы далеко одна от другой, потому что экран
i Pad шире, чем экран i Phone.
-
ПОДСКАЗКА. П ри запуске приложе н и я на и м итируемых устройствах с большими экра­
нами иногда невозможно увидеть весь экран сразу. Эту проблему можно исправить ,
выбрав команду Wiпdowc:> Scale в меню програ м м ы IOS Simulator и выбрав коэффици ­
ент масштабирования дл я своего экрана.
1 08
ГЛАВА 3 i!! О С Н О В Ы ВЗАИ М ОДЕ Й СТВ И Я
Взгляну в н а рис. 3 . 1 , вы увидите, что одну вещь м ы пропустил и . Заглавие
выбранной кнопки должно в ыводиться на экран полужирным шрифтом , а пока
м ы видим обы ч н ы й текст. Немного позже м ы исправим это с помощью класса
NSAt t r ibutedS t r i ng, а сначала ознакоми мся с другой полезной функцией сре­
ды Xcode - предварител ь н ы м просмотром макета.
П редварительный п росмотр макета
Вернитесь в програм му Xcode и выберите узел Main. storyboard, а затем от­
кройте окно помощн и ка редактора, если оно закрыто (как это сделать, показано
на рис. 3 .6). В левой половине панел и быстрых переходов, расположенной в
верхней части окна помощника редактора, вы увидите, что в дан н ы й момент
выбран атрибут Automatic (есл и вы не изменил и его на Manual, чтобы выбрать
файл в окне помощни ка редактора). Щел кн ите на сегменте панел и быстрых пе­
реходов, чтобы открыть всплы вающее меню, и увидите нескол ько команд, пос­
ледняя из которых наз ы вается Preview. Есл и установить на нее указател ь мыши,
поя в ится меню, содержащее имя раскадровки приложения. Щел кн ите на нем,
чтобы открыть раскадровку в окне Preview Editor.
Когда откроется окно Preview Ed itor, вы увидите внеш н и й вид приложения
на устройстве i Phone в книжной ориентаци и . Это всего лишь предварител ьный
просмотр, поэтому н и каких реакци й на касание кнопок нет, а знач ит, вы не
увидите метку. Есл и вы переместите м ы ш ь на область, расположен ную н иже об­
ласти предварител ьного просмотра, где нап исано i Phone б s , поя вится элемент
управления, позволяющий поворачи вать телефон и переводить экран в ал ьбом­
ную ориентацию. Этот элемент управления изображен в левой части рис. 3 .28.
Щел кнув на нем, вы выпол ните вращение телефона по часовой стрел ке.
Благодаря механ изму A uto Layout при вращении телефона кнопки перемеща­
ются так, чтобы их центров ка и расстоя ния были такими, как в книжной ориен­
тации . Если метка остается видимой, то ее пози ция также будет правил ьной .
Кроме того, помощн и к предварител ьного просмотра можно испол ьзовать для
того, чтобы увидеть, что произойдет, есл и запустить приложение на другом ус­
тройстве. В левом н ижнем углу окна помощника предварител ьного просмотра
(и на рис. 3 .28) вы увидите кнопку +. Щел кн ите на ней, чтобы открыть список
устройств, а затем выберите пун кт i Pad, чтобы иметь возможность предвари­
тел ьного просмотра экрана i Pad в окне помощн и ка предварител ьного просмот­
ра. Экран i Pad зан имает м ного места, поэтому, возможно, вам придется закрыть
окна Document Outline и Utility View, чтобы можно было в идеть и экран i Phone,
и экран i Pad . Есл и вы все еще не видите пол н ы й экран устройства i Pad, то мо­
жете масштабировать окно Preview Assistant, испол ьзуя разные способы. Проще
всего дважды щел кнуть на панел и Preview Assistant - и оно станет знач ител ь­
но меньше. Есл и вы хотите задать кон кретны й коэффициент масштабирования,
то можете вы пол н ить жест щипка на мул ьтисенсорной панел и (к сожалению,
м ы ш ь Magic Mouse эту возможность не поддержи вает). Окна предварител ьно­
го прос мотра экранов i Phone и i Pad, уменьшен н ы е так, чтобы их было видно
ГЛАВА 3 *' О С Н О В Ы В З А И М ОДЕ Й С Т В И Я
1 09
nолностью, nоказаны на рис. 3 .29. Обратите вни мание на то, что механизм A uto
расnоложил кнопки правил ьно. Поверн ите окно предварител ьного просмотра
экрана i Pad, чтобы убедиться в том, что приложение правильно работает в аль­
бом ном режиме.
•
Yleow c-tnllliн kil"
't\f-.COnU'0118•
4- '
fop L � Ou JcМ
.
'°"*" 1..f'\18Ut �
. .....
"....
•
� li.twut.f
• 8Coм1teint1
. ...... �11 · •
8 Stttu. l..ьtl too • fCIJI �
8 LAtt.-""'ll · �
8Lln.-!..-Y • �ltf'r
·"""'·'*"'"' "' �
· � - •19111м._
· k� -.._..
В •"'
• $1�'11 trrtry l'olr'lt
--) �-�-
П П п п .., ,..,
1 о Vle'w •.: IPrloiм &t t"c •Jtl
1
n
1&%
•
-
Lt>lt
--!
+ °' IS \01 \А!
1
Рис. 3 . 28. П р едвар ител ьн ы й п росмотр разм етки на экра н е устрой ства i Ph o n e
альбом н о й о р и е нтаци и
-
-
....
.....
-
iPhone SE 1 Landsc ape
IP hone 6 s 1 Portralt
Рис. 3 . 29 . Одно в ре м е н н ы й п редварител ьн ы й п росмотр э к ­
р а н о в i P h o n e и i Pad
1 10
ГЛАВА 3 11 О С Н О В Ы В ЗА И М ОД Е Й СТВ И Я
ЗАМЕЧАНИЕ. Когда м ы работали н ад к н и го й , панель Preview Assistaпt некорректно
отображала макеты для i Pad с экранами 9,7 и 1 2 ,9 дюй м а . Возможно , это связано с
ошибка м и бета - версии Xcode 8 . Однако выполнение соответствующих п риложений на
симуляторе показы вает, что они работают корректно .
И зм енение стиля текста
Класс N SAt t r ibutedS t r i n g позволяет добавл ять информацию о формате,
например о шрифтах и вырав н и вании абзацев. Эти метаданные можно приме­
нять ко всей строке, причем разные атрибуты можно применять к разным частя м
и нтерфейса. Для того чтобы понять, как работает класс NSAt t r ibutedS t r i ng,
достаточ но вспомн ить, как форматируется текст в текстовом редакторе. Бол ь­
ш и нство элементов управления в библ и отеке U I K it позволяют испол ьзовать
строки с атрибутами . В случае класса U I Labe l, который м ы испол ьзуем в своем
приложении, можно просто создать строку с атрибутам и и передать ее метке с
помощью ее свойства a t t r ibutedText.
Итак, выберем файл Vi ewC o nt r o l l e r . s w i f t и обнови м метод b u t t o n ­
Pre s sed ( ) так, как показано в листин ге, удал и в перечеркнутую строку и доба­
вив строки, приведенные в л исти нге 3 .8 .
Листинг 3 . 8 . Обновление метода but t onPre s s ed ( ) дл я полужирного ш р ифта
imp o r t U I K i t
c l a s s V i ewCon t r o l l e r : U I V i ewCon t r o l l e r (
@ I BOu t l e t we a k va r s t a t u s Labe l : U I Lab e l !
@ I BAc t i o n f u n c b u t t on P r e s s e d ( _ s e nde r : U I Bu t t o n )
let title
s e nde r . t i t l e ( f o r : . s e l e c t e d ) !
let text
" \ ( t i t l e ) button pressed"
l e t s ty ledText
N S M u t a Ы eAt t r i b u t e dS t r i n g ( s t r i n g : t e x t )
l e t a t t r ibute s
[
N S fontAt t r i b u t e N ame :
U i f o n t . b o l d S y s temfont ( o f S i z e : s t a t u s Lab e l . f o n t . p o i n t S i z e )
=
=
=
=
l e t name R a n g e
( text a s NSString ) . range ( o f : t i t l e )
s t y l e d T e x t . s e tAt t r i b u t e s ( a t t r ib u t e s , r a n g e : nameRa n g e )
=
s t a t u s Labe l . a t t r i b u t ed T e x t
=
s t y l edText
С начала новый код создает строку с атрибутам и, в частности объект класса
NSMu t a Ь l eAt t r ibutedS t r i ng, на основе строки, которую вы хотите вы вести
на экран. Нам нужна строка с атрибутам и , допускающая изменения, потому что
мы собираемся изменять ее атрибуты .
ГЛАВА 3 iil' О С Н О В Ы ВЗАИ М ОДЕЙ СТВ И Я
111
Далее м ы создаем словарь для хранения атрибутов, которые будут приме­
няться к строке. На самом деле у нас пока только оди н атрибут, поэтому словарь
содержит еди нственную пару "кл юч-значен ие". Ключ N S FontAt t r ibu t eName
позволяет задать ш рифт для части строки с атрибутам и . З начение, которое м ы
передаем, иногда назы вают "полужир н ы й системный шрифт". Оно означает, что
размер шрифта строки с атрибутам и должен совпадать с размером шрифта, ко­
торы й в дан н ы й момент испол ьзуется для метки . Такое задание шрифта я вля­
ется более гибким, чем указание шрифта по названию, поскольку система сама
знает, как правил ьно испол ьзовать полужирны й шрифт.
Теперь м ы попросим строку p l a i nText сообщить нам диапазон (состоящий
из начал ьного и ндекса и дл и н ы ) подстроки, содержащей название метки . При­
меним эти атрибуты к строке с атрибутами и передадим ее метке. Рассмотрим
строку, задающую коорди наты строки заголовка.
let name R a n g e
=
( t e x t as NS S t r i n g ) . r a n g e ( o f : t i t l e )
Обратите вни мание на то, что тип переменной p l a i nT e x t при водится из
типа S t ring языка Swift в тип N S S t r i ng каркаса Core Foundation. Это необ­
ходимо, потому что оба класса, S t r i n g и N S S t r i ng, и меют метод range ( o f :
S t r i ng ) . Метод класса N S S t r i n g задает диапазон в в иде объекта N S Range,
потому что и менно его ожидает метод s e tAt t ribut e s ( ) в следующей строке
программ ы .
Теперь можно щел кать н а кнопке R u n ; вы увидите, что приложение показыва­
ет название нажатой кнопки с помощью полужирного шрифта, как на рис. 3 . 1 .
Ис поль зо ва н ие д елега т а п риложе н и я
Теперь, когда наше приложение работает, прежде чем переходить к новой
теме, удел им нескол ько м и нут изучению исходного файла, который мы еще не
просматривал и : AppDe l eg a t e . swi f t . Этот файл я вляется реализацией делегата
приложения (appl ication delegate).
Делегаты ш ироко ис пол ьзуются в каркасе Сосоа Touch. Они представляют
собой классы, решающие определенные задач и от имени другого объекта. Де­
легат приложения позволяет в ыпол нять определенные действия в заранее ус­
тановлен ное время от имени класса U I App l i ca t i o n. Каждое приложение для
системы iOS имеет оди н и тол ько оди н э кземпляр класса U I App l i ca t i on, обес­
печивающи й вы пол нение приложения и реал изующи й его фун кциональные воз­
можности, такие как направление входных дан н ы х соответствующему классу
контроллера. Класс U IApp l i ca t i on я вляется стандартной частью библиотеки
U I K it и вы полняет свою работу практически незаметно, так что в бол ьшинстве
случаев о нем не приходится беспокоиться .
В определенные точно заданные моменты времени в ходе выпол нения прило­
жения класс U IApp l i cat ion вызы вает установленные методы делегата, при усло­
вии, что делегат, реализующий этот метод, действител ьно существует. Напри мер,
112
ГЛАВА 3 .ix О С Н О В Ы ВЗАИ М ОДЕ Й СТВ И Я
если у вас есть код, который должен сработать непосредственно перед заверше­
нием програм мы, м ожете реал изовать метод app l i ca t i onWi l l T e rmina t e ( ) в
делегате своего п риложения и поместить этот код в него. Дан н ы й тип деле­
гирования позволяет вашему приложению реал изовать обы ч ное поведение без
создания подкласса класса U I App l i ca t i on и даже без информации о том, как
он работает.
Щел кните на файле AppDe l egate . swi f t в окне навигатора проекта, и увиди­
те содержимое заголовочного файла делегата своего приложения (листи нг 3 .9).
Листинг 3 . 9 . П ервоначальны й код делегата приложения
i mp o r t U I K i t
@ U I Appl i ca t i onMa i n
c l a s s App De l e g a t e : U I Re s p onde r ,
UIAppl i c a t i onDe legate {
va r w i ndow : U I W i ndow ?
В ыделен ная полужирн ы м шрифтом часть строки означает, что класс под­
держи вает п ротокол U I Ap p l i c a t i o n D e l e g a t e . Н ажм ите и удержи вай­
те клавишу <Option>. Ваш курсор имеет вид ножниц. Переместите курсор
на слово U I App l i c a t i o n De l e g a t e . Он и м еет вид знака воп роса, а слово
UIApp l i c a t i onDe l e g a t e будет в ыделено как ссыл ка браузера (рис. 3 .30).
9
10
11
'2
13
н"
impo rt U I K i t
@UIApp t icat ionНain
c t a s s AppDe tega t e :
v a r w indow :
U I Re s p o 11 d e r ,
Ц:t_Д.ppJ.J.j:_a_t.\,QQ J.�.9.��� {
U I W i n dow?
1�
Рис. 3 . 30 . Посл е того как в ы н ажал и кла в и ш у < Option > в среде Xcode
и указал и на с и м вол в н а ш е м коде , этот с и м вол стал выдел е н н ы м , а
курсор п р и н ял вид з на ка воп роса
П родолжая удерживать нажатой клавишу <Option>, щел кните на этой ссыл­
ке. Откроется маленькое вспл ывающее окно с кратким оп исан ием протокола
UIApp l i c a t i onDe l e g a t e (рис. 3 .3 1 ) .
П роходя по вспл ы вающему м е н ю с верху в н из, в ы найдете д в е ссылки
(см . рис. 3 .3 2 ) .
Обратите внимание на две ссылки, расположенные в н ижней части вспл ы ва­
ющего окна документации . Щел кните на ссыл ке More, чтобы увидеть пол ную
документацию для этого сим вола, или на ссыл ке Declared, чтобы увидеть опре­
деление символа в заголовоч ном файле. Аналоги ч н ы й трюк работает и для имен
классов, протоколов и категори й, а также для методов, отображаем ы х на панели
редактирования . Просто дважды щел кните на слове, и программа Xcode найдет
для вас это слово в браузере документаци и .
ГЛАВА 3 ''' О С Н О В Ы В ЗА И М ОД Е Й СТ В И Я
1 13
The UIAppli c a t ionOe l e g a t e protocol deflnes methods that аге called
Ьу the slngleton U!Application object ln response to lmpoгtant events ln
the llfetlme of уоuг арр.
The арр delegate works alongslde the арр object to ensure уоuг арр
interacts p rope rly with the system and with other apps. Specifically, the
met hods of the арр delegate give you а chance to re s po nd to important
changes. Fог example, you use the m et h od s of the арр d el eg a te to
respond to state transltlons, such a s when your арр moves from
foreground to background executlon, a nd to respond to incomlng
notlficatlons. ln many cases, the methods of the арр delegate are the
only way to re c e lve t hese important notlflcatlons.
Xcode pгovides an арр delegate class for every new project, so you do
not need to define one yourself inltially. When your арр launches, UJКit
automatically creates an instance of the арр delegate class provlded Ьу
Xcode and uses it to execute the first Ыts of custom code in your арр.
All you have to do is take the class that Xcode provldes and add your
custom code.
The арр delegate ls effectlvely the root ob)ect of your арр. Llke the
UIApplication object itself, the арр delegate is а singleton object and
ls always present at runtlme. Although the UIApplication object does
most of the underlylng work to manage the арр, you declde уоuг app's
overall behavior Ьу providlng approprlate implementations of the арр
delegate's methods. Although most methods of this protocol are
optlonal, you should implement most or all of them.
The арр delegate performs several cruclal roles:
•
lt contalns y ou r app's startup code.
Рис . 3 . 3 1 . Посл е того как вы н ажал и кл а в и ш у < O pti o n > и щел кнул и
н а ссыл ке U t Appl i cati o n D e l egate в и сход н о м коде , п ро г ра м м а Xcode
открыла панель Q u ick Help с о п и с а н и е м требуе м о го п ротокола
""" V l l \V l ffo
t. l lU \ Y V � WI l l V \ l l Q 'l 'O L H I
'"' '' l lH I � Y I "" ' ' "'Vl f \ I V l l '"' I •
For more information a bout the ro le of the арр delegate and how it fits
into the арр architecture, see Арр Programming Guide for iOS. For more
information about the UIApplicat ion singleton class, see
UIAppfication .
iOS (8.0 and later), tvOS (9.0 and later)
UIKit
Protocol Reference
1 Рис . 3.32. Ссылки на допол н и тел ьную и нфо рмацию о выдел е н н ом
эле м е нте
Умение быстро находить нужную информаци ю о протоколе в документаци и,
безусловно, важно, но еще важнее иметь возможность видеть определение про­
токола. Именно здес ь вы можете узнать , какие методы делегата приложения
можно реал изовать и когда эти методы будут вызваны . Вероятно, стоит потра­
тить время на изучение описания этих методов .
1 14
ГЛАВА 3 11 О С Н О В Ы ВЗАИ М ОДЕЙСТВИЯ
Вернитесь в окно навигатора проекта и щелкните н а файле App De l egate .
swi ft, чтобы увидеть делегат приложения. Содержимое файла должно в ыгля­
деть так, как показано в листинге 3 .1О.
Л и ст и н г 3 . 1 О. Файл AppDelegate . swift
imp o r t U I K i t
@ U I App l i c a t i o nMa i n
c l a s s App De l e g a t e : U I Re s p o n de r ,
U I App l i c a t i o n De l e g a t e
{
v a r w i ndow : U I W i ndow ?
f u n c a pp l i c a t i o n (
a p p l i c a t i o n : U I App l i c a t i o n ,
d i d F i n i s h L au n c h i n gW i t h Op t i o n s
l a u n chOp t i o n s : [ N S O b j e c t : An yOb j e c t ] ? ) - > B o o l {
/ / Т о ч к а з амеще ния дл я н а с т р о й ки п о сл е з а пу с ка приложени я .
return true
f u n c app l i c a t i on Wi l l Re s i gnAc t i ve (
a p p l i c a t i o n : U I App l i c a t i o n )
/ / Вызыв а е т с я , е сли приложение должно п е р е й т и из а к т и в н о г о
состояния
в н е а к т и в н о е . Э т а н е о б х о димо с т ь в о з н и к а е т п р и выполне нии
прерыва ний определенного типа ( на приме р , при входящем звонке или SMS )
или к о г д а п о л ь з о в а т е л ь выходит и з приложе н и я и выпол н я е т к а кие - т о
дей с т в и я в ф о н о в ом р ежиме .
/ / Э т о т ме т о д и с п ол ь зуе т с я дл я о с т а н о в ки выпол н я емых з а д а ч ,
о т ключения т а ймеров и замедления прори с о в ки кадров OpenGL E S , а т а кже
в и г р а х дл я о р г а н и з а ции паузы .
f u n c app l i c a t i o n D i d E n t e r B a c kg r o u n d (
a p p l i c a t i o n : U I Ap p l i c a t i o n ) {
/ / Э т о т м е т о д и с п о л ь зуе т с я для ос в о б ожде ния общих р е с ур с о в ,
сохранения поль з о в а т ел ь с ких да нных , обнуления т аймеров и сохранения
информации о с о с т о я нии приложения , дост а т очно дл я его в о з обновления
1 1 Е сли в аше прил оже н и е п о ддержи в а е т р а б о т у в ф о н о в ом р ежиме ,
э т о т ме т о д вызыв а е т с я при выходе п ол ь з о в а т е л я вме с т о ме т ода
ap p l i c a t i o nW i l l T e rm i n a t e : .
f u n c app l i c a t i onW i l l E n t e r Fo r e g r o u n d ( app l i c a t i o n : U I App l i c a t i o n )
/ / Э т о т ме т од вызыв а е т с я к а к ч а с т ь п е р е х о да из ф о н о в о г о
с о с т о я н и я в а к т и в н о е ; зде с ь можно о т м е н и т ь и з ме н е ни я ,
сдела нные в ф о н о в ом режиме .
f u n c app l i c a t i o n D i d B e comeAc t i ve ( ap p l i c a t i o n : U I Ap p l i c a t i o n ) {
1 1 В о з о б н о вл я е т выпол н е н и е о с т а н о вл е нных з а д а ч ( или з а п у с ка е т
еще не стартовавшие ) , оставляя приложе ние н е а кти вным . Е сли приложение
р а б о т а л о в ф о н о в ом р ежиме , п ол ь з о в а т ел ь с кий и н т е р ф е й с може т быт ь
прори с о в а н з а н о в о .
ГЛАВА 3 "' О С Н О В Ы В ЗА И М ОДЕ Й СТВ И Я
115
f u n c appl i c a t i o nW i l l T e rm i n a t e ( a pp l i c a t i on : U I App l i ca t i on )
1 1 Вызыва е т с я в о время пре краще н и я работы приложе н и я .
Сохра н я е т д а н ные , е сли е с т ь в о зможно с т ь .
См . т а к ж е a pp l i c a t i on D i d E n t e r B a c k g r o u n d : .
В начале файла можно увидеть, что делегат нашего приложения реал изовал
оди н из методов п ротокола app l i c a t i o n ( _ : d i d F i n i shLaunc h i n gWi thOpt
i o n s : ) , которы й, как легко догадаться, в ы п олняется, как тол ько приложение
завершает этап настрой ки и готово к взаимодействи ю с пол ьзователе м . Этот
метод часто испол ьзуется для создания л юбых объектов, которые должны су­
ществовать на всем протяжении в ыпол нения приложения.
В остал ьных частях книги, особенно в главе 1 5 , м ы узнаем, насколько важ­
ную рол ь играют делегаты в жизни приложений. М ы п росто хотели кратко опи­
сать делегаты и показать, как тесно они связаны между собой .
Р е зюм е
Простое приложен ие, рассмотрен ное в настоя щей главе, позвол ило вам оз­
накомиться с кон цепцией МУС, создать и связать между собой выходы и дей­
ствия, реал изовать контроллеры представлений и испол ьзовать делегаты прило­
жений . Вы научились инициировать действия при нажатии кнопки и узнали, как
измен ить метку кнопки во время в ыполнения п рограм м ы . Несмотря на простоту
созданного приложения, основные концепции, рассмотренные нами, совпадают
с кон цепция м и , лежащи м и в основе всех других элементов у п равления в сис­
теме iOS, а не тол ько кнопок. С п особ использован ия кнопок и меток, проде­
монстрирован н ы й в главе, прекрасно работает и со все м и други м и элементам и
управления в системе IOS.
Чрезвычайно важно, чтобы вы понял и, что и почему м ы делал и в этой главе.
Есл и это не так, то вернитесь к началу и повторя йте все действия, пока не пой­
мете. Есл и вы не разобрал ись во всех деталях, то еще бол ьше запутаетесь при
создан ии более сложных и нтерфейсов в последующих главах книги.
В следующей главе мы изу ч и м стандартн ы е элементы у п равления iOS .
Вы также узнаете, как выдавать предупрежден ия и уведомления пол ьзователя м
и предоставлять им выбор с помощью л истов действ и й .
ГЛ А В А 4
• •
Н о в ы е у п р а жн е н и я
с и н те р ф е й с о м
)
_/
_
_
_
_
_
_
В главе 3 мы обсудили концепцию МУС и написали приложение, воплощающее
ее в жизнь. Вы ознакомились с выходами и действиями и испол ьзовали их для свя­
зывания кнопки с текстовой меткой. В настоящей главе мы планируем создать при­
ложение, которое повысит уровень ваших знаний об элементах управления (рис. 4. 1 ).
лpress·
Рис . 4 . 1 . П р иложе н и е с нескол ь­
к и м и эл е м е нта м и уп равле н и я
1 18
ГЛАВА 4 "" Н О В Ы Е УП РАЖН Е Н И Я С И НТЕРФЕЙСОМ
Мы создадим графическое представлен ие, ползунок, два разных поля редак­
тирован ия, сегментирован н ы й элемент управления, нескол ько перекл ючателей
и кнопку с исте м ы iOS (до верси и 7). М ы покажем, как задать и определ ить
значения раз н ы х элементов управлен и я ; как испол ьзовать список действий,
чтобы заставить пол ьзователя сделать выбор, а также преду п реждения, обес­
печ и вающие обратную связь с пол ьзователем . Вы ознаком итесь с состоя ниями
элементов управления и науч итесь испол ьзовать растя ги ваемые изображения
для создания кнопок желаемого размера.
Поскольку в этой главе испол ьзуется м ного разных терм и нов, обозначающих
элементы пол ьзовател ьского и нтерфейса, мы посту п и м немного иначе, чем в
двух предыдущих главах, а именно: разобьем наше приложение на части, раз­
работаем каждую из них по отдельности, настрои м и вы пол н и м в среде Xcode
и си муляторе iOS, тестируя каждую часть, прежде чем перейти к следующей.
Разделяя процесс построен ия сложного и нтерфейса на более мел кие части, мы
упрощаем задачу и приближаемся к реал ьному процессу проекти рован ия при­
ложен и й . Ци кл "кодирование-ком п ил я ция-отладка" зан имает бол ьшую часть
рабочего времени разработчи ка программ ного обеспечения.
Наше приложение будет испол ьзовать тол ько одно представление и контрол­
лер, но, как показано на рис. 4. 1 , это представление намного сложнее приложе­
ния, написанного в главе 3 .
Логотип н а экране устройства iPhone наз ы вается графическим представле­
нием (image view). В этом приложе н и и графическое представление просто вы­
водит на экран статическое изображение. Н иже логотипа расположены два поля
редактирования (text field): одно из них позволяет в водить буквы и цифры, а
второе - тол ько цифр ы . Ниже текста находится ползунок (sl ider). Когда пол ь­
зовател ь перемещает ползунок, значение метки, следующей за ним, изменяется
и всегда отображает его значение.
Под ползунком расположены сегментированный элемент уп равления (seg­
mented contro l ) и два переключателя (switches). Сегментирован ный элемент
управления будет перекл ючать приложение между двумя разн ы м и типами эле­
ментов управления . При первом запуске приложения под сегментирован н ы м
элементом управления появляются два переключател я . Изменение значения од­
ного из н их приводит к соответствующему изменению другого. Это не совсем
то, чего мы хотим от реального прил ожения, но это позволяет продемонстри­
ровать, как изменить значение элемента управления програм м н ы м путем и как
ани м и ровать некоторые действия с помощью каркаса Сосоа Touch, не при кла­
ды вая н и каких усил и й .
На рис. 4 . 2 показано, что происходит, когда пол ьзовател ь нажимает сегмен­
тированный элемент управления. Переключатели исчезают и заменяются кноп­
кам и .
ГЛАВА 4 <'1 Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
1 19
Есл и нажата кно п ка Do Something, на э кране вспл ы вает список действи й
(action sheet), с помощью которого приложение с праши вает у пользователя , что
он имел в виду, кода нажимал кнопку (рис. 4.3).
Apress·
Name:
NurnЬer:
50
Рис . 4 . 2 . В резул ьтате н ажат и я
Рис. 4 . 3 . Дл я того чтоб ы заста ­
с е г м е н т и рован н о го контрол л е р а ,
расположе н н о го сл ева , н а экране
появл я ю т ся два п е р е кл юч ател я , а
после нажатия с е г м е нти рован н о ­
г о контролл е ра , расп оложе н н о го
в и т ь п о л ьзо вате л я дать отве�
п р и л оже н и е и с п ол ьзует с п и со к
де й ств и й
с п рава , поя вля ется к н о п ка
Это стандартн ы й способ ответа н а действие пол ьзователя, которое я вляется
потенциально опасным или может иметь серьезные последстви я . Он дает пол ь­
зователя м возможность остановить потенци ал ьно опас ное разв итие событи й .
Если пол ьзователь выберет команду Yes, l ' m Sure!, приложение в ыведет н а экран
предупрежден ие, сообщающее, что все в порядке (рис. 4 .4).
1 20
ГЛАВА 4 �' Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСО М
Рис . 4 . 4 . Для уведо м л е н и я п ол ьзовател я о важных со­
бытиях испол ьзуются п редупрежде н и я . Здес ь показан о
п редупрежде н и е , сообща ю ще е , ч т о в с е идет хорошо
А кти вн ы е , с тати ч еские и п а ссивн ы е
э л емен ты уп ра вления
Су ществу ют три основные категории элементо в управле ния и нтерфейсом :
акти в н ые, статические (неакти в н ые ) и пассивные. Кнопки, испол ьзованные в
предыдущей главе, представляют собой классически й при мер акти вных элемен­
тов управления. В ы нажимаете их, и что-то 11роисходит - обы ч но вы пол няется
часть програм м ы .
Хотя м ногие элементы у правления, которые в ы будете ис11ол ьзовать, непо­
средственно вызывают какой-нибудь метод действия, не все элементы управле­
ния работают именно так. Графическое представлен ие, которое мы реал изуем
в этой главе, всего л и ш ь демонстрирует изображен ие; несмотря на то что его
можно настроить на заг�уск действий, пол ьзовател ь ни чего не сможет с ним де­
лать. Поля редактирования и изображения часто испол ьзуются таким образом .
ГЛАВА 4 •lt Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
1 21
Некоторые элементы управления носят пассивный характер. Они просто хра­
нят какое-то значение, введенное пол ьзователем, пока вы его не проч итаете. Эти
элементы управления не и н и циируют н и каких действий, но пол ьзовател ь может
взаимодействовать с н и м и и изменять их значения. Классический пример пас­
сивного элемента управления - поле редактирования на веб-странице. Несмотря
на то что может существовать некий код проверки, которы й в ыпол няется, когда
вы перекл ючаетесь на поле редактирования, подавл яющее бол ь ш и нство полей
редактирования на веб-стран и це просто я вл я ются контей нерам и для хранения
дан н ых, посылаемых на сервер, когда вы щел каете на кнопке Submit. Сами по
себе поля редактирован ия не я вляются и н и циаторам и вы пол нения какого-л ибо
кода, но, когда пол ьзовател ь щел кает на кнопке Submit, дан н ые, которые в них
содержатся, отправл я ются по назначению.
На устройствах с системой IOS бол ь ш и нство элементов управления можно
использовать во всех трех режимах как в активном, так и в пассивном режимах в
зависимости от потребностей пол ьзователя . Все элементы управления в системе
IOS представля ют собой подклассы класса U I Control и поэтому способны и н и­
циировать действия. М ногие элементы управления могут также испол ьзоваться
пассивно, причем все они могут быть пасс и в н ы м и и невиди м ы м и . Например,
использование одного элемента управления может приводить к и н и циированию
другого неакти вного элемента управления, которы й становится акти в н ы м . Одна­
ко некоторые элементы управления, такие как кнопки, действител ьно не могут
быть полезными, есл и они не акти в н ы .
Между элементами управления в системах I O S и Мае существует разница в
поведении. Рассмотри м нескол ько примеров.
i:<
Благодаря мул ьтисенсорному и нтерфейсу все элементы управления в сис­
теме iOS могут инициировать несколь ко действи й в зависимости от того,
как вы пол нено прикосновение к н и м . П ол ьзовател ь может и н и ци и ровать
разные действия, скользя пал ьцем поперек элемента управления или прос­
то касаясь его.
;,�
Можно инициировать одно действие, когда пол ьзовател ь при касается к
кнопке, и другое - когда отнимает палец от кнопк и .
Один элемент управления может и н и циировать нескол ько действи й в от­
вет на одно событие. Напри мер, в ответ на прикосновение к внутренней
области кнопки можно инициировать два разных действия , т.е. оба дей­
ствия будут вы полнены, когда пол ьзователь отн имет палец от этой кнопки.
�1'
ЗАМЕЧАНИЕ. Несмотря на то что эле менты управления в системе IOS могут вызывать
сразу нескол ько м етодов, вероятн о , было бы луч ш е реализовать оди н м етод дей ­
стви я , который делает все , что необходимо п р и определенном состо я н и и эле мента
управления . Обычно такая возможность не нужна, но ее следует и м еть в виду, ра­
ботая с п рограм мой lnterface B u i l der. Установление новой связи м ежду событием и
действием не разры вает предыдущую связь с други м действием этого же элемента
1 22
ГЛАВА 4 � Н О В Ы Е У П РАЖ Н Е Н И Я С И Н ТЕРФЕЙСОМ
управления . Это может привести к неожида н н ы м отклонен и я м в работе вашего при­
ложен ия , поэтому, устанавл и вая связи между событи я м и и действия м и , следует про­
являть осторожность.
Другое важное разл ичие между системам и iOS и М ае я вляется следствием
того факта, что, как правило, устройства с системой iOS не имеют физи че�кой
клавиаrуры (есл и, конечно, вы не присоединили внеш н юю клавиаrуру). Стан­
дартная клавиаrура систе м ы iOS я вляется обыч н ы м представлением, запол нен­
ным рядом кнопок. Ваша програм ма, скорее всего, никогда не будет взаи модейс­
твовать с клавиаrурой систем ы iOS напрямую.
С о здание п риложен ия Control Fun
Откройте среду Xcode и создайте новый проект с и менем C o n t r o l Fun.
Мы снова собираемся испол ьзовать шаблон Single View Appl ication, чтобы со­
здать проект точно так же, как в предыдущих двух главах.
Создав проект, найдите изображен ие, которое мы будем испол ьзовать в
качестве нашего графического представления. Это изображение должно быть
и мпортировано в среду Xcode, чтобы быть досrупным для испол ьзован ия в про­
грамме l nterface B u i lder, поэтому сначала и м портируем его. Вы найдете три фай­
ла
apre s s_logo . png, apre s s l o go @ 2 x . png и apre s s_logo @ З x . png
в
папке 0 4 Logo s , содержащей исходные файл ы проекта. Эти файл ы представ­
ляют собой стандартную версию и две верси и Retiпa одного и того же изобра­
жения. Мы добавим эти файл ы в каталог ресурсов и предостави м приложению
самостоятел ьно выбирать соответствующее изображение на этапе выполнения.
Есл и вы будете ис пол ьзовать изображение, в ыбран ное самостоятел ьно, убеди­
тесь, что его размеры соответствуют размеру досrупного пространства, а файл
имеет расш ирение png. Его размер должен быть не бол ьше 1 00 пикселей в
высоrу и 3 00 п и кселей в ширину, чтобы можно было заполнить верхнюю часть
представления на самом узком экране устройства i Phone без изменения его раз­
меров. На более крупных экранах испол ьзуются версии удвоенного и утроен но­
го размеров.
Н аходясь в среде Xcode, выберите папку As s e t s . xc a s s e t s в окне нави­
гатора проекта, откройте пап ку 0 4
Logo s в окне Finder и выберите все три
графи ческих изображения. Затем перетащите эти изображения в область ре­
дактирован ия Xcode и отпустите кнопку м ы ш и . Среда Xcode испол ьзует имена
изображений для того, чтобы оп редел ить, что вы добавляете три версии изоб­
ражения с именем apre s s _ l ogo, и остальную работу сделает автоматически
(рис. 4.5). В левом столбце области редактирования под элементом Appl con по­
я в ится элемент apre s s_logo. Теперь имя apre s s_logo можно использовать в
коде или в программе l nterface B u i lder для ссылки на данный набор графичес­
ких изображений и их загрузки во время вы полнения приложен ия.
-
-
-
.
-
ГЛАВА 4 .� Н О В Ы Е УП РАЖН Е Н И Я С И НТЕРФЕЙСОМ
"
1'!1
, . c;;.rol
. Fun
• ._ Ool'lttd Fun
-� �hl •..мtt
• Vleweonetoltt..wМ
. ...fn._
�
-1
t
111 <
)
• """"" '"" '
Control Fun: Rмdr j TodfV tl l:'t& РМ
��-
1 23
�"""""""-�-�·----
....:: -....iooo
211
Зх
Рис. 4 . 5 . Добавл е н и е изображе н и й apre s s l ogo в п роект Xcode
Р еали з аци S1 графи ч е ского п редста вле н и S1
и поле й ре д а кти рова н и S1
Добавив изображение в проект, реал изуем пять элементов и нтерфейса в вер­
хней части экрана: графи ческое представление, два поля редактирования и две
метки (рис. 4.6).
лpress·
Name:
NumЬer:
Рис. 4 . 6 . Графическое представл е н и е , м етки и поля
редакти рова н и я реал и зуются в п е рвую оче редь
Добавление графического п редставления
Перейдите в окно навигатора проекта, щелкните на файле Ma i n . s t o ryboa rd,
чтобы открыть его в среде l пterface B u i lder. Вы увидите знаком ы й бел ы й фон и
единствен ное квадратное представлен ие, на котором можно разместить интер­
фейс вашего приложения. Как и в предыдущей главе, под окном IB выберите в
списке View as: пункт i Phone бs.
ЗАМЕЧАНИЕ. Этот раздел , расположе н н ы й н иже макета , является новшеством в среде
Xcode 8 и называется View Dimension . Он позвол яет выбрать, как мы будем видеть
сцену, работая с макето м .
Есл и библиотека объектов не открыта, выполните команду Viewq Utilitiesq Show
Прокрутите при мерно четверть списка и найдите пун кт l mage
View (рис. 4. 7). Запом н ите, что библ иотека объектов откры вается с помощью
третьей пиктограм м ы в верхней части панел и библиотеки.
Object Libra ry .
ГЛАВА 4 '/.j Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФ Е Й С О М
1 24
•
•
•
•
A � n.n . ...... .
е1 fi: о. !.А ф jJ о 111
�
-
il! <
t c-.. ,....
C:.W�*"Мr
� ,...
�
• &1 "81w � --..
·
--
T.М, •t17Pt,1,
....,..,.,
.....__.,.._. ..... ... 1-..:'t1811
r. �....... �
� L...- �
. ".... ......
8 Ь•
....... ilЧf'/' l°'oll'lt
� () ф D
...... \11- · 0tмllJrt • ......
; -... " ... ...... _.... ...
" " ..." - ......
о
Рис. 4. 7. Элемент l mage Vlew в библ и отеке объектов програм м ы l nte rface Builder
Перетащите графическое представление в окно редактора раскадровок и ос­
тавьте его поблизости от верхнего края, как показано на рис. 4 . 8 . Пока не стоит
беспокоиться о точ ном пози ционирован и и ; в следующем разделе мы еще вер­
немся к этому вопросу.
""""" "'
11! <
•
. с.ос... ....
fJ Ylew Ccмttrolм Щм
•
'1-..W Contf�
Top Layout Q\llOI
•
COnlro! Fun
м.lrl.ttotyЬoerd ) . ММrt.tt-d jВ.MI С1 V\tw c...• �
•
lllow
ф F"w11 �
Yi.w ,
-
,...., _ 1
1
_D Ф • Q> В е
--
•
а
-
·-
.... - ­
11 t".�
·• StoryЬOwdf.nttyPolnt
lfJ
... <0 �" о Q о
Vltw �
а
тао
int.r111:taon
в
в
о :
U.. '"ttrtcllon ENЬl«I
1 :
Nofll
! + 8ectf'cм.N
nм
- o.taufl
- 0 °"""'8
• СМ111 OJюhlr:t Comext
�8 Аи1О1..а �
о :
.......
-
1 :
"_
Рис . 4 . 8 . Добавл е н и е объе кта кл асса U I ImageVi ew в рас кадровку
-
1
В
о :
, :
ГЛАВА 4 -� Н О В Ы Е У П РАЖ Н Е Н И Я С И Н ТЕРФЕЙСОМ
1 25
Выбрав графическое представлен ие, вызовите и нспектор атрибутов объекта,
нажав комби нацию клавиш <Option+3€ +4>. В резул ьтате отобразятся редактиру­
емые атрибуты класса U I ImageView. Сам ы м важны м атрибутом нашего пред­
ставления изображений я вляется верхний элемент в окне и нспектора, и меющи й
имя Image. Есл и щел кнуть на маленькой стрелке, находящейся справа от поля,
на экране поя вится вспл ы вающее меню с досту п н ы м и изображени я м и, которые
должн ы содержать все изображения, добавленные вам и в свой п роект Xcode.
Выберите изображен ие, добавленное м и нуту назад. Ваше изображение должно
поя виться в графическом представлении, как показано на рис. 4.9.
yЬoard
111 Maln.st... (8810) ) Cit View C ... r Scene )
•
о
1!!1
View )
epress_logo
"
Ststt r
о
0 Apres
о
View Controller )
Ylew
Modt
Hlghllghlld
Scale То Flll
U�specfl!!<!_
Samantlc
в
в
_
о :
Tag
lnteractlon -:· Uaer lnteraction EnaЫed
Q
Alph1
+ Background
Tlnt
� Multlpl1 Touch
1 :
.
-
"8
В
Def1ult
Drowlng D Op1que
Hldd1n
D Clears Graphlcs Context
,_
Stretching
+
Cllp SuЬvlews
а Autoreslze S.. Ьviews
о :
Wldth
1;
f.l installed
у
Н.lght
о' :
1 :
Рис . 4 . 9 . И н с п е ктор атри бутов графи ч е с кого п р едста вл е н и я . М ы в ы б рал и
наше изображе н и е в м е н ю l mage в в е рх н е й ч асти окна и н с п е кто ра , а зате м
запол н ил и граф и ч еское п редставл е н и е н а ш и м изображе н и е м
И з менение размеров графического п редставления
О казы вается, размеры испол ьзуемого нам и изображения не совпадают с раз­
мерами графического представления, в котором оно находится. Среда Xcode по
умолчанию масштабирует изображе н ие так, чтобы запол н ить все графическое
представление. Для этого достаточ но в окне инспектора атрибутов установить
для параметра Mode значение S ca l e to F i l l . М асштабировать изображения
лучше до запуска приложения, потому что этот процесс занимает время работы
процессора. В данном случае мы вообще не собираемся масштабировать наше
1 26
ГЛАВА 4 1! Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
графическое п редставлен ие, поэтому просто изменим его размеры, чтобы они
совпадали с размерам и изображения . Для начала измен ите атрибут Mode на
Center, означающий, что изображение не должно масштаби роваться и должно
быть расположено в центре представлен ия. Затем подгоните размеры графичес­
кого представления под размеры изображения . Для этого выберите графическое
представление, чтобы на э кране поя вил ись конrуры и размерные линии, а затем
нажм ите комбинацию клавиш <Х +=> ил и выберите команду EditorQ Size to Fit
Content. Если комбинация клавиш не дала эффекта ил и команда была заблоки­
рована, снова выберите графическое представление, перетащите его немного в
сторону и повторите попытку.
ПОДСКАЗКА. Если вы испыты ваете трудности с выбором элемента в окне редактора ,
переключитесь на окно Document Outline, щел кнув на маленьком треугольнике, рас­
положенном в левом н ижнем углу. Затем щелкните на элементе , выбранном в окне
Document Outline, и этот элемент окажется выбранным в окне редактора .
Для того чтобы извлечь объект, вложе н н ы й в другой объект, щелкните на треуголь­
н и ке раскрыти я , расположен н о м слева от объекта - контейнера, и увидите вложе н ­
н ы й объект. В нашем случае для выбора графического п редставл е н и я необходи мо
сначала щелкнуть на треугол ьнике раскрыти я , расположенном слева от представле­
ния. Затем графическое п редставление появ ится в окне Docu ment Outline. Когда
вы щел кнете на нем , соответствующее графическое п редставление будет выбрано
в окне редактора.
Изменив размеры изображения, переместите его в окончател ьное положение.
Как было показано в главе 3, перетаски вайте графическое представлен ие, пока
оно не окажется в центре, щел кн ите на п и ктограмме Align, расположенной в
правом н ижнем углу области редактирован ия, установите флажок Horizontal Cen­
ter in Container и щел кните на кнопке Add 1 Constraint.
Возможно, вы заметили, что програм ма l nterface Bui lder проводит нескол ько
сплошных л и н и й от края представления к краю его родител ьского представления
(не путайте их с пун ктирными голуб ы м и линиями, которые поя вляются при пе­
ретаскивани и элементов по макеrу) или от одного родительского представления
к другому. Эти сплош ные л и н и и п редставля ют добавленные вам и ограничения.
Есл и щел кнуть на добавлен ном ограничении, то на экране появится сплошная
оранжевая линия, верти кально проходя щая через все главное представление, как
показано на рис. 4 . 1 О.
Эти сплошные л ин и и п редставля ют ограничен и я . Оранже в ы й цвет означа­
ет, что позиция графического представления и/или его размеры задан ы не пол­
ностью и необходимо задать допол нител ь н ые огран ичения . В ыяснить причину
этой проблемы можно, щел кнув на оранжевом треугольнике в окне Activity View.
В данном случае среда Xcode сообщает нам, что необходимо установить верти­
кал ьное ограничение для графического представления . Это можно сделать пря­
мо сей час, испол ьзовав п рием ы, описанные в главе 3, ил и подождав, пока м ы
н е исправим все ограничен ия в нашем макете позднее.
ГЛАВА 4 � Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
о
•
1 27
111
-
Ар ess·
Рис. 4 . 1 О . И з м е н и в раз м е р ы граф и ч е с ко г о п ред­
ста вл е н и я та к , чтобы они соответствовал и раз м е р а м
и зображе н и я , м ы п е ретащили е го в требуе м ое м е сто
с п о м ощью голуб ых л и н и й разм етки и создал и огра н и ­
ч е н и е , чтобы закреп ить е го в центре
ПОДСКАЗКА. П еретаски вание и масштабирование п редставлений в п рограмме l nterface
Builder может оказаться сложной задаче й . Не забывайте об окне Docu ment Outline,
которое откры вается после щелчка на мален ьком треугол ь н и ке , расположенном
в нижней части окна редактора . Во время масштаби рования удерживайте нажатой
клавишу <Option > . П рограмма l nterface B uilder нарисует на экране вспомогательные
красные л и н и и , которые позволят намного быстрее понять, где должно находиться
изображе н и е . Этот трюк не срабатывает при перетаски ван и и , потому что клавиша
<Optio n > предлагает програм м е l nterface B u ilder создать коп и ю перетаскиваемого
объекта . Однако , если выбрать команду Editorc:> Canvasc:> Show Bounds Rectangles,
вокруг элементов вашего интерфейса будут нарисованы л и н и и , чтобы их легче было
увидеть. Эти л и н и и можно откл юч ить, снова выбрав команду Show Bounds Rect­
angles.
Настройка атрибутов представления
Выберите свое графическое п редставлен ие, а затем перекл ючите в н имание
на инспектор атрибутов. Под разделом l mage View находится раздел View. Легко
1 28
ГЛАВА 4 11t, Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
догадаться, что в этом разделе сначала вы водятся атрибуты выбран ного объек­
та, за которым и следуют более общие атрибуты, nримен и м ые к родител ьско­
му классу в ыбранного объекта. В данном случае родительским классом класса
U I Ima g eView я вляется класс U I V i ew, nоэтому следующи й раздел назы вается
View. О н содержит атрибуты, которы м и обладает л юбое nредставление.
А трибут Mode
Первым элементом в окне и нсnектора nредставлен и й я вляется всnл ы ваю­
щее меню Mode. В этом меню м ожно задать сnособ, которым nредставление
будет отображать свое содержи мое на экране. Оно оnределяет режим выравни­
ван ия изображения в nредставлении и то, надо ли его масштабировать. Можно
выбрать л юбой вариант демонстрации изображения apre s s _ l ogo, чтобы nо­
смотреть, как оно будет в ы глядеть, но не забудьте в конце оставить значение
Center.
Как указ ы валось ранее, выбирая л юбой вариант, nредусматри вающи й масш­
табирование изображения, вы увел и ч иваете в ы числ ител ьные затраты, nоэтому
лучше избегать таких ситуаций и задавать nравил ьные размеры изображений
еще до их и м nортирован и я . Есл и же в ы хотите в ы вести на экран одно и то
же изображен ие, но с раз н ы м и размерами, то лучше сделать нескол ько разных
коn и й этого и зображения, чем в ы нуждать устройство с системой iOS масшта­
бировать его во время работы .
А трибут Semantic
Неnосредствен но n од м е н ю Mode расn ол ожен атрибут Semantic. Этот ат­
рибут n оя в ился в верс и и i O S 9 и поз воляет у казы вать, как должно nрори­
совы ваться nредставление в локал изаци и , n редусматри вающей чтение сn рава
налево, наnример на и вр ите ил и арабском я з ы ке . По умол чан и ю n редставле­
ние не и м еет этого атрибута, но его можно установить, выбрав соответству­
ющее значение. Более nодробную и нформацию можно найти в документаци и
no Xcode, в которой оnисы вается свойство s ema n t i c C o n t e n tAt t r i b u t e в
классе U IView.
А трибут Tag
Следующи й no nорядку элемент
Tag
заслужи вает вни мания, хотя мы
не будем исnол ьзовать его в этой главе. Все nодклассы класса U I Vi ew, вкл ю­
чая все nредставления и элементы у n равления, имеют свойство t a g, которое
я вляется обы ч н ы м ч ислов ы м значением (дескриnтором), отображаем ы м рядом
с nредставлением изображения. Этот атрибут nредназначен тол ько для nользо­
вателя ; система ни когда не устанавл и вает и не изменяет его значение. Есл и вы
установил и значение атрибута Tag для элемента уnравления ил и nредставления,
то можете быть уверен ы, что он всегда будет и м еть заданное вам и значен ие,
nока вы сам и его не измените.
-
-
ГЛАВА 4 ." Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
1 29
Дескри пторы обеспечи вают простой и независим ы й от языка способ иденти­
фикации объектов и нтерфейса : Допусти м, в вашем и нтерфейсе есть пять разных
кнопок, каждая из которых имеет собственную метку, и вы хотите испол ьзовать
один метод, выполняющий действие для всех пяти кнопок. В этом случае вам,
вероятно, необходим о как-то разл ичать кноп ки при вызове этого метода. В от­
личие от меток, дескрипторы н и когда не изменяются, поэтому, есл и вы зададите
значение дескри птора в програм ме lnterface B u i lder, то сможете испол ьзовать
его в качестве быстрого и надежного инструмента для проверки элемента уп­
равления, передаваемого в качестве аргумента s e nde r методу, выполняющему
действие.
Флажки lnteraction
Эти два флажка относятся к взаимодействию с пол ьзователем. Первый фла­
жок
User l nteraction EnaЫed
оп редел яет, может л и пол ьзовател ь вооб­
ще что-л ибо делать с объектом . Для большинства элементов управления этот
флажок установлен, потому что и наче элемент управления н и когда не сможет
инициировать м етоды, в ыпол н я ющие действи я . Однако для графических пред­
ставлен и й этот флажок по умол чан и ю сброшен, потому что оче н ь часто эти
элементы управления испол ьзуются для отображения статической информаци и .
Поскол ьку м ы планируем л и ш ь вы вести рисунок н а э кране, нет необходимости
устанавл ивать этот флажок.
Последний флажок
Multiple Touch
определяет, способен ли элемент уп­
равления получать события м ногократного прикосновения. Такие события до­
пускают испол ьзование сложных жестов, таких как щи пок, который применяется
для увел ичения масштаба во м ногих приложениях для системы iOS . О жестах и
событиях м ногократного прикосновения реч ь пойдет в главе 1 8 . Так как графи­
ческое представление не допускает н и какого взаи модействия с пол ьзователем,
нет причин для вкл ючения обработки событи й м ногократного прикосновения,
поэтому этот флажок остается сброше н н ы м .
-
-
-
-
Ползунок Alpha
Следующий элемент инспектора назы вается Alpha, и с н и м следует быть ос­
торожн ы м . Элемент Alpha определяет степен ь прозрач ности вашего изображения,
т.е. как отображать на экране элементы, находя щиеся под этим изображением .
Степень прозрач ности определяется числом с плавающей точ кой от О.О до 1 .0.
Чисоо О.О означает пол ную прозрачность, а 1 .0
пол ную непрозрач ность. Если
ввести число, меньшее еди ницы, то ваше устройство iOS нарисует это представ­
ление полупрозрачным, так что вы сможете увидеть элементы, находящиеся под
ним. Есл и степень прозрач ности меньше еди н и цы, то, даже есл и под изображе­
нием н ичего нет, вы заставите п роцессор вы полнить допол н ител ьные выч исле­
ния, связанные с определением прозрачности . Поэтому не задавайте этот показа­
тел ь мен ьшим еди ницы, есл и у вас нет веских причин поступить иначе.
-
1 30
ГЛАВА 4 � Н О В Ы Е У П РАЖН Е Н И Я С И НТЕРФЕЙСОМ
А трибут Background
Следующий по порядку элемент под названием Background определяет цвет
фона для представлен ия . Дnя графических п редставлений это имеет значение
только тогда, когда изображение не запол няет представление пол ностью ил и ка­
кая-то его часть я вляется п розрачной. Поскол ьку наше изображение пол ностью
запол няет представление, изменение этого атрибута не будет иметь ни каких ви­
зуальных последствий, так что его можно не трогать.
А трибут Tint
Следующий элемент управлен ия задает оттенок цвета переднего плана вы­
бранного п редставления. Этот же цвет некоторые представления испол ьзуют
для своей прорисовки. Сегментирован н ы й элемент управления, который м ы
будем испол ьзовать далее, испол ьзует цвет переднего плана, а объект класса
U I ImageView - нет.
Флажки Drawing
Под атрибутом Tint расположен ряд флажков Drawing. Первый из них и меет
метку Opaque. Убедитесь, что он установлен по умолчанию. Есл и нет, устано­
в ите его. Он сообщает системе iOS, чтобы она н и чего не рисовала под ваши м
представлением, и позволяет ей оптим изировать методы рисования для ускоре­
ния п роцесса прорисовки .
В ы м ожете п о и нтере соваться , почему необход и м о установ ить фл ажо к
Opaque, есл и м ы уже задал и атрибут Alpha рав н ы м 1 . 0, чтобы сделать пред­
ставление непрозрач н ы м . Значение атрибута Aplha относится тол ько к тем час­
тя м изображения, которые должны быть нарисован ы, а есл и изображение не
пол ностью зан имает п редставление ил и в нем есть дыры, образованные ал ь фа­
каналом (alpha channe l), то объекты , расположенные под н и м , будут показаны
независимо от з начения атрибута Alpha. Установив флажок Opaque, мы сооб­
щаем системе IOS, что под дан н ы м представлением н ичего рисовать не надо,
поэтому нет необходимости тратить время процессора на элементы, располо­
жен н ые под объектом . М ы можем безопасно устанавл и вать флажок Opaq ue,
поскол ь ку ранее выбрал и команду Size to Fit, которая вынуждает представление
изображений изменить размеры так, чтобы они совпал и с размерам и изображе­
ния, которое оно содержит.
Флажок H idden означает и менно то, что вы подумал и . Есл и он установлен, то
пол ьзовател ь не может видеть дан н ы й элемент управления. С крыть элемент уп­
равления иногда бывает полезно. Позднее мы покажем, когда следует скрывать
перекл ючател и и кнопки, но в подавляющем больши нстве случаев этот флажок
не устанавли вается . М ы можем оставить его в состоя нии, предусмотренном по
умолчанию.
Следующий флажок - Clears Graphics Context - устанавл и вается редко. Есл и
он установлен, то система iOS, прежде чем нарисовать сам элемент управления,
ГЛАВА 4 щ Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
1 31
нарисует всю область, покрытую элементом управления, как прозрач ную и чер­
ную. И снова замети м, что он отключен, отчасти потому, чтобы не снижать про­
изводительность приложения, а отчасти потому, что он нужен довол ьно редко.
Остави м этот флажок сброшен н ы м (скорее всего, по умолчанию он окажется
установленным).
Флажок Clip Subviews довол ьно и нтересен . Есл и ваше представление имеет
дочерние представления и они не полностью запол няют родительское представ­
ление, то данный флажок определяет, как будут прорисовываться эти представле­
ния. Есл и флажок Clip Subviews установлен, то нарисована будет только та часть
дочерних представлений, которая лежит в п ределах родител ьского представле­
ния. Есл и флажок Clip Subviews сброшен, то дочерние представления будут про­
рисованы пол ностью, даже есл и они выходят за предел ы родител ьского пред­
ставления.
По умолчанию флажок Clip Subviews должен быть сброшен. Может показать­
ся, что на самом деле все должно быть наоборот и дочернее представление не
должно прорисовы ваться где угодно. Однако выч исление отрезаемой области и
отображение тол ько части дочерних представлений - довол ьно затратная опе­
рация с математической точки зрения, а в больши нстве случаев дочерние пред­
ставления не выходят за предел ы родительских. Есл и по каким-то при ч и нам это
вам действител ьно необходи мо, можете установить флажок Clip Subviews, но по
умолчанию он сброшен, чтобы не тормозить работу приложения .
Последн ий флажок в этом разделе - Autoresize Subviews. Он сообщает сис­
теме iOS, чтобы она масштабировала все дочерние представления при масшта­
бировани и родител ьского представления . Оставим его установленн ы м . Поскол ь­
ку мы не собираемся масштабировать п редставление, этот флажок не играет
никакой рол и .
Раздел Stretching
Следующий раздел назы вается Stretching. Он регламентирует перерисовку
прямоугольных представлений при изменени и их размеров на экране. Идея за­
ключается в том , чтобы не растя ги вать все содержание представления равно­
мерно, а фиксировать внеш н ие края представления, например скошенные гран и
кнопок, чтобы они выглядел и так же, как в центральной части области растя­
гиван ия.
Четыре ч исла с плавающей точ кой определяют, какая часть прямоугол ьника
может растя ги ваться . Эта вел и ч и на определяется координатами левой верхней
точ ки представления и размером растягиваемой области . Все эти ч исла лежат в
диапазоне от О . О до 1 . О, выражая долю размера всего представления. Например,
если вы хотите оставить 1 0% каждого края нерастяжимыми, задайте значения Х
и У равны м и О . 1 , а Width и Height - О . 8 . В дан ном случае оставим значения
Х и У равн ыми О . О , а Width и Height
1 . О. С корее всего, вам редко придется
изменять эти параметры .
-
1 32
ГЛАВА 4 "1'1. Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕ Й СОМ
Добавление полей редактирования
Завершив подготовку графического представления, добавим в него поля ре­
дактировани я . Захватите поле редактирован ия из библ иотеки, перетащите его в
раскадровку. Испол ьзуя голубые л и н и и разметки для выравнивания по правому
краю, поместите поле немного н иже графического представления (рис. 4 . 1 1 ).
iew ... r Scene /
View •.. ntroller
)
Toxt
•
CQlor
а
Alignrnont
•
P*•hotder 1 · .-fi
+
а
-
+
Вeckground
Dlнbled
!Aln Font Slzo
G:J :
• •
а
, ' f/1 1: .,,ь r
,. у .
11
11
1•
О
О
-
Never ap_Eears
••• В
Clear when edltlng Ьeglna
Cloar But:ton
а
•
,,.. 1 ",
CJ
8order Style
в
Default
Font Syatem 14.О
-
лpress·
в
Pleln
"
17 :
D Ad)ust to Flt
Capitolfzlllon None
Correotlon
Defeult
Defau l t
Spell ChtcklnQ
КоуЬоаrd Туре
Default
Appearanct
Raturn Кеу
(�
Text
··-
Default
Default
r
С\
Auto·enaЫe Retum Кеу
secure Text Entry
(}
@
в
в
в
в
в
в
[]
Т.хt Fi.ld • Oltpl.yt edltt Ыo text
end нnd• an actlon m1188g1 10 •
torQet oЬjoct when Rtturn lt lll)ped.
Text Vlew • D11play1 multlp'41 llnos
of 1dltaЫe text and 11nd1 1n actlon
m1111gt to а t1rget oЬJect when Ra."
75%
+
о
Рис . 4 . 1 1 . М ы пе ретащили поле редакти рова н и я из б и бл и отеки и
раз м е ст и л и его на п р едставл е н и и н е п ос редстве н н о под и зобра­
жен и е м , и спол ьзуя голуб ы е л и н и и разм етки
Затем захватите метку из библ и отеки и перетащите ее так, чтобы выров­
нять по левой границе изображения и по верхнему краю поля редактирован ия.
ГЛАВА 4 il: Н О В Ы Е УП РАЖН Е Н И Я С И НТЕРФЕЙСОМ
1 33
Обратите внимание на нескол ько голубых л и н и й разметки, которые поя вля ются
вокруг метки при ее перемещен и и . Они облегчают выравн и вание метки по от­
ношен и ю к пол ю редактирован ия с помощью верхней ил и н ижней границы, а
также середины метки . М ы собираемся выровнять метку и поле редактирования
по тексту, ориентируясь на базовую л и ни ю, проходя щую по н ижнему краю тек­
ста через все поле редактирован ия (рис. 4 . 1 2).
� :rJ о. 6 э е;
- �
о
оо
� <
a cQf'l," ,....
�,
· е � с_..."
. ...,..
•
.• VJ.w �
lep � Qwlcм
.
.... a шin _..,.м.d a w.1c1 -� 1..." , e \'lмl c.-w a-
...,_ � о....
, ...... ,..,",". ,.....
. ...
• 8C-1..W.
. ,.. .......,_
8ы
....... i...... ,..,
(J i..J �J
" r�, " '
w.w �
'"
• •
лpresS"
о:
--
-·-
"'"""""
о:
о:
1:
-
,:
D О 0 tJ
1
""
LaЬel :i� .......,
_.
•
о
Рис. 4 . 1 2 . В ы ра в н и в а н и е м етки и поля редакти рова н и я по базо вой л и н и и
Дважды щел кнув н а метке, измен ите е е имя Label на Name: ( н е забудьте по­
ставить двоеточие) и нажм ите клавишу <Return>, чтобы зафиксировать внесен­
ные изменения .
Затем перетащите другое поле редактирован ия из библиотеки на представ­
ление и, испол ьзуя голубые л и н и и разметки, поместите его под первы м полем
редактирован ия (рис. 4. 1 3 ).
Размести в второе поле редактирования, захватите в библиотеке другую метку
и пом,естите ее в левой части н иже существующей метки . Для выравнивания
метки по второму пол ю редактирования снова испол ьзуйте голубую л и н и ю раз­
метки . Дважды щел кн ите на новой метке и измен ите ее имя на N u m ber: (не за­
будьте поставить двоеточие).
Растя ните нижнее поле редактирования влево, чтобы оно полностью доходи­
ло до правого края метки. Почему мы начи наем с н ижнего поля редактирован ия,
а не с верхнего? Потому что хотим, чтобы оба текстовых поля имели одинако­
вые размеры, а н ижняя метка дл и н нее, чем верхняя.
1 34
ГЛАВА 4 � Н О В Ы Е УП РАЖН Е Н И Я С И НТЕРФЕЙСОМ
Оди н раз щелкните на нижнем поле редактирован ия и перетаски вайте левую
точ ку изменения размера влево, пока не поя в ится голубая л и н ия разметки, со­
общающая о том, что приблизиться к метке еще больше невозможно (рис. 4. 1 4 ).
Эта л и н и я разметки почти незаметна - ее дл ина равна высоте самого поля
редактирования, так что будьте внимательны .
.лpress·
о
---i
Name:
i1
1
i1
Apress·
11
1
11
•
1
Name:
1
i
1
."
1
1
1
1
1
1
Рис . 4 . 1 З . Добавл е н и е вто ­
Рис . 4. 1 4 . Растя г и в а н и е н и ж ­
рого поля редакти рова н и я
н е го поля реда ктирова н и я
Теперь точно так же растя н ите верхнее поле редактирования, чтобы размеры
обоих полей совпадал и . Эту задачу также облегчают голубые л и н и и разметки .
М ы сделал и с пол я м и редактирован ия практически все, что требовалось, за
искл ючением одной детал и . Верн итесь к рис. 4 . 1 . Разве метки Name: и Number:
выровнен ы по правому краю? Нет, в данн ы й момент они выровнены по лево­
му краю. Для того чтобы обе эти м етки в ыровнять по правому краю, щелкни­
те на метке Name: и, удерживая нажатой клавишу <Sh i ft>, щел кн ите на метке
N umber: , чтобы обе метки оказал ись выбран н ы м и . Н ажм ите комби нацию кла­
виш <Option+X +4>, чтобы открыть окно инспектора атрибутов, и убедитесь,
что раздел LaЬel открыт. Есл и он не открыт, то щел кн ите на кнопке Show, рас­
положенной справа от заголовка. Теперь воспол ьзуйтесь элементом управления
Alignment для выравнивания метки, а затем задайте ограни чен ие, регламенти­
рующее, что оба поля всегда должны и м еть оди наковый размер, щел кнув на
кнопке Add 1 Constraint. В окне Activity View должен поя виться оранжевый инди­
катор п редупрежден ия в в иде треугольника, а в окне навигатора проблем долж­
ны поя виться п редупреждения о проблемах с макетирован ием . Пока их можно
и гнорировать - мы исправим их позднее.
ГЛАВА 4 � Н О В Ы Е УП РАЖН Е Н И Я С И НТЕРФЕЙСОМ
1 35
После этого и нтерфейс должен очень напом и нать и нтерфейс, показанн ы й на
рис. 4 . 1 . Еди нствен ное отл ичие закл ючается в том , что поля редактирования
на рис. 4 . 1 содержат светло-серый текст, а поля на нашем и нтерфейсе - нет.
Этот недостаток м ы сейчас исправ и м . Щел кн ите на верхнем поле и нажм ите
комбинацию клавиш <Option+3f:+4>, чтобы открыть окно и нспектора атрибутов
(рис. 4. 1 5). Поле редактирования - оди н из наиболее сложных и наиболее часто
испол ьзуемых элементов управления в системе iOS. Рассмотри м его настройки,
начиная с самой верхней строки окна и нспектора. Убедитесь, что вы выделwш
и:wенно поле редактирования, а не метку Wtи другой элемент.
LaЬel
�
[mJ
ф
P l a in
Text
"'
_в
-..
1
Allgnment
�--=
-
Llnes 1
8
II)J ::
J
�e_fault
Font • Syste� 1 7.О
Sehavior
@
M 1J ! ip\c , " ," i u C"3
Color
+
(1
А - __::::_·
&
11 EnaЫed
- Highlighted
Baseline
Alig�_!!�l! lin e s
__
Line Breaks , Tr��!_Tai�
--
Autoshrlnk
Fixed Font Size
11111!1 LO�f� l t
�
+
Tighten Letter Spacing
_ в
в
Highlighted , _
� \.Oe!ault
Shadow
+
Shadow Offset
_
О
1
Horlzontil
Vlew
Mode 1
Semantlc
__
v
Left
_
__ _
u!l�e�fied
_
О 1 :;
Tag l
lnteractlon ,-
8
8
User lnteraction ЕпаЫеd
!' Multiple Touch
Alpha
+
Background
j
�
,
- --·
v
_! 18
___
--'Unt..c-· -- �-- -"'
�
о @ []
Рис. 4. 1 5 . И н с п е ктор поля редакти рован и я
со значе н и я м и п о умол ч а н и ю
1 36
ГЛАВА 4 il.> Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
Ус тановки инс пектора полей редактирования
В первом разделе метка Text связана с двумя элементам и управления, позво­
ляющи м и задать вид текста в поле редактирования. Первый элемент - это рас­
крывающийся список, позволяющий сделать выбор между обычным текстом и
текстом с атрибутам и (разными шрифтами и т.п.). В главе 3 мы использовали эти
атрибуты, чтобы текст отображался полужирным шрифтом . В данном случае Пока
остави м атрибут равным P l a i n . Непосредственно под ним можно ввести значе­
ние, заданное для поля редактирования по умолчанию. Все, что вы наберете в этом
поле, будет отображаться в поле редактирования при запуске вашего приложения.
Сразу за первым разделом следует ряд элементов управления, позволяющих
задавать шрифт и его цвет. Оставим атрибут Color по умолчанию черн ы м . Меню
Color разделено на две части : в п равой можно выбрать заранее заданные цвета,
а в левой - собстве н н ы й цвет.
Раздел Font разделен на три части . Правая часть - это элемент управления,
позволяющий увел и ч и вать ил и уменьшать размер текста на оди н пункт. Левая
часть позволяет вручную редактировать н азвание и размер шрифта. И наконец
пиктограмма с бу квой Т в квадрате откры вает ко нтекстное окно, в котором мож­
но задать разл и ч н ы е атрибуты шрифта. Оставим для атрибута Font значение
S y s t em 1 4 . О, задан ное по умолчанию. В зависимости от системы это значение
может меняться .
Под эти м и разделами расположены три кнопки для управления выравнивани­
ем текста в поле редактировани я . Остави м текст выровнен н ы м по левому краю
(по умолчанию). Для этого надо нажать левую кнопку.
Раздел Placeholder позволяет задать текст (запол нител ь), которы й будет отоб­
ражаться в поле редактирован ия серым цветом тол ько тогда, когда в поле ре­
дактирования не в ведено н и каких значени й . Есл и на экране мало места ил и вы
хотите подсказать пользователю, что именно следует вводить в поле редактиро­
ван ия, то запол нител ь можно использовать в качестве метки . Введите в качестве
запол н ителя пол я редактирования текст Туре in а name .
Следующие два поля, Background и DisaЫed, испол ьзуются, тол ько есл и вам
необходимо настроить внешн и й вид поля редактирования, хотя это совершенно
необязател ьно и часто просто при водит к потере времен и . Пол ьзовател и при­
выкли к полям редактирования определенного вида. По этой причине м ы оста­
вим эти поля заполнен н ы м и их значения м и по умолчанию.
Далее следуют четыре кнопки с меткой Border Style, позволя ющие изменять
стил ь прорисовки границ полей редактирования. Вы можете выбрать любой из
четы рех стилей, но по умол ча н и ю считается в ыбран ной правая кноп ка. Она
задает стил ь поля редактирования, которы й наиболее популярен среди пол ьзо­
вателей приложе н и й для системы iOS, поэтому, когда наи граетесь со стилями,
выберите край нюю справа кнопку.
Параметр Clear Button позволяет у казать, должна л и поя вл яться на экране
кнопка оч истки содержимого . Она п редставляет собой букву Х, расположен ную
ГЛАВА 4 "*' Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
1 37
в кон це поля редактирования. Кнопка очистки содержи мого обы ч но испол ьзу­
ется в полях поиска и других пол я х, содерж и мое которых ч асто изменяется .
Как правило, его не в ы водят в пол я х, содержащих постоя н н ые дан н ые, по­
этому это значение параметра Clear Button следует оставить рав н ы м Neve r
Appe a r s .
Флажок Clear When Ed iting Begins о пределяет, что произойдет, когда пол ьзо­
вател ь прикоснется к указан ному пол ю . Есл и флажок установлен, то значен ие,
ранее введен ное в поле редактирован ия, будет удалено, и пол ьзователь начнет
работу с пустым полем редактиро ван ия. Есл и же флажок сброшен, то преды­
дущее значение останется в поле, и пол ьзователь сможет его отредактировать.
Убедитесь, что этот флажок сброшен .
Следующи й раздел начинается с элемента управления, позволяющего задать
минимальный размер ш рифта. Оставим значение этого поля заданн ы м по умол­
чанию. Флажок Adj ust to F it определяет, следует л и уменьшать размер текста
при уменьше н и и размеров пол я редактирован и я . Есл и флажок установлен, то
весь текст будет виден в поле редактирования, даже есл и его сли ш ком м ного и
он выходит за выделен ное пространство. Справа от этого флажка расположено
поле редактирован ия, позволя ющее задать м и нимал ь н ы й размер шрифта. Неза­
висимо от размера поля, шрифт не может б ыть меньше заданного м и н имал ьного
размера. Задавая м и н и мальный размер шрифта, в ы гарантируете, что текст всег­
да можно будет проч итать.
Следующи й раздел определяет внешний в ид клавиатуры и ее поведение при
использован и и поля редактирования. Поскол ьку в поле будет вводиться имя, ус­
тановим для параметра Capitalize значение W o rd s . В резул ьтате каждое слово
будет автоматически начинаться с прописной буквы, что обычно и требуется
при вводе и мен .
Четыре следующих раскры вающихся списка
Correction, Spell Checking,
Keyboard Туре и Appearance
можно оставить без изменен и й . Подумайте о
них пару м и нут, чтобы понять см ысл их содержани я .
Следующее меню, Return Кеу, относится к клавише, расположенной в правом
нижнем углу клавиатуры. Ее метка изменяется в зависимости от того, что вы
делаете. Есл и вводите текст в поле запросов поисковой маш и н ы Safari, напри­
мер, то она назы вается Goog l e . В приложении, подобном этому, где поле редак­
тирования дел ит экран с други м и элементам и управления, правил ь н ы м выбором
будет значение Done.
Есл'и установлен флажок Auto-enaЫe Return Кеу, то клав и ша < Return> будет
откл ючена, пока в поле редактирован ия не будет введен хотя бы оди н сим вол .
Оставим этот флажок сброшенным, потому что м ы разрешаем, чтобы поле ре­
дактирован ия оставалось пусты м, есл и пол ьзовател ь так хочет.
Флажок Secure определяет, должен ли введенный символ отображаться в поле
редактирования. Этот флажок следует устанавл и вать, есл и поле редактирования
испол ьзуется для ввода парол я . Оставим его сброше н н ы м .
-
-
1 38
ГЛАВА 4 /Зi Н О В Ы Е У П РАЖН Е Н И Я С И НТЕРФЕЙСОМ
Следующий раздел (для того чтобы его увидеть, возможно, необходимо вы­
пол н ить вертикальную прокрутку экрана) позволяет установить общие атрибуты
элемента управления, унаследованн ые от класса U I Control, но они обычно не
относятся к полям редактирования и, за исключением флажка EnaЫed, не влияют
на внешний в ид поля. М ы хотим, чтобы поля редактирования был и доступными
и пол ьзовател ь мог взаимодействовать с н и м и, поэтому оставим все как , есть.
Последн и й раздел в окне инспектора должен б ыть вам хорошо знаком .
Он идентичен разделу с таким же названием в и нспекторе представления изоб­
ражений, который мы описывали выше. Существуют атрибуты, унаследованные
от класса U IVi ew, а поскол ьку все элементы уп равления я вляются подклассам и
класса U IVi ew, все они совместно испол ьзуют этот раздел атрибутов. Устано­
вите флажок Opaque и сбросьте флажки Clears Graph ics Context и Clip Subviews
(причины мы объясним позже).
Установка атрибутов для второго поля редактирования
Щелкните на н ижнем поле редактирования (под меткой N umber: ) в раскад­
ровке и верн итесь в окно и нспектора атрибутов. В ведите в поле Placeholder
строку Туре in а numЬer. Флажок Clear When Editing Begins должен быть сбро­
шен. Немного н иже откройте вспл ы вающее меню Keyboard. Поскол ьку мы хо­
тим, чтобы пользовател ь вводил только цифры, а не буквы, вы пол н ите команду
N umber Pad . В результате пол ьзовател ь увидит на экране i Рlюпе клавиатуру, со­
держащую тол ько цифр ы . Это означает, что он не сможет вводить буквы, сим­
вол ы или что-либо другое, кроме цифр. М ы не обязаны устанавл ивать значение
атрибута Return Кеу для цифровой клавиатуры, потому что на ней нет такой кла­
виши. Следовател ьно, все остал ьные параметры в и нспекторе следует оставить
задан н ы м и по умолчанию. Как и раньше, установите флажок Opaque и сбрось­
те флажки Clears Graphics Context и Clip Subviews. На устройстве i Pad команда
N umber Pad вкл ючает виртуал ьную цифровую клавиатуру, когда пол ьзовател ь
активизирует поле редактирования, при этом он может переключить клавиатуру
обратно в алфавитн ы й режи м . Это означает, что в реал ьном приложении вы
должны проверить, что пол ьзовател ь в вел правил ьное ч исло в поле Number.
ПОДСКАЗКА. Есл и хотите предотвратить ввод в поле редактирования любых символов,
кроме чисел , то создайте класс , реал изующий метод textView ( _ textView : shou ld
ChangeTex t i nRange : rep l a c ementTe x t : t e x t ) протокола U I Tex tViewDe legate,
и сделайте его делегатом текстового представления. Это несложно , но описание это­
го процесса выходит за рамки нашей кни ги .
До бавление ограничений
П режде чем п родолжать работу, м ы должны настроить нескол ько ограниче­
н и й для нашего макета. Когда вы перетаски ваете одно представление в дру­
гое, находясь в окне I пterface B u i lder ( как мы тол ько что сделал и), програм ма
Xcode автоматически не создает для него н и каких огран ичен ий. Однако система
ГЛАВА 4 � Н О В Ы Е УП РАЖН Е Н И Я С И НТЕРФ Е Й С О М
1 39
макетирован ия требует пол ного набора огран ичений, поэтому во время ком пи­
ляции програм ма Xcode создает набор стандартных ограничений, описывающих
макет. Эти огран ичения зависят от позиции всех объектов в родительском пред­
ставлении. В зависимости от того, где они расположены - бл иже к левому или
правому краю представления, - они прикрепляются к левому или правому краю.
Аналогично в зависимости от того, к какому краю они бл иже расположены верхнему ил и нижнему, - они прикрепля ются к верхнему или н ижнему краю.
Есл и объект расположен точно в центре, то обы ч но он фи ксируется в центре.
Для того чтобы еще бол ьше запутать ситуацию, програм ма Xcode может при­
менить автоматические ограничения и прикреп ить все новые объекты к одному
ил и нескольким "соседя м" в рам ках одного и того же родительского представ­
ления . Это может соответствовать ваш и м желан и я м , а может и нет, поэтому
лучше самостоятел ьно создать пол н ы й набор ограничений в п рограмме l nterface
Bui lder до ком пиляции вашего приложения, и в последних двух главах м ы по­
казал и, как это сделать.
Итак, посмотри м на то, что мы имее м . Для того чтобы у видеть все огра­
н ичения, относящиеся к кон кретному представлению, выберите его и откройте
инспектор размеров. Выбрав л юбую метку, поле редактирования или ползунок,
вы увидите, что инспектор размеров вы водит сообщение о том , что дл я в ы ­
бран ного представления не установлено н и одного ограничен и я . Графически й
пользовател ьский и нтерфейс, который м ы создаем, пока имеет только ограниче­
ния, связы вающие центры по горизонтали графического и контейнерного пред­
ставлени й . Щел кните на контейнерном ил и графическом представлении, чтобы
увидеть эти ограничения в окне инспектора.
Нам необходим пол н ы й набор огран ичений, точно описывающий все п ред­
ставления и элементы управления на макете на этапе ком п иляции. К счастью,
создать его довольно просто. В ыберите все представления и элементы управле­
ния, нажав клавишу <Control> и обведя указателем контур вокруг н их, нач иная
с верхнего левого угла контейнерного представления против часовой стрелки в
направлении правого верхнего угла. Если вы увидите, что при этом представле­
ние начало перемещаться, отпустите кнопку м ыши, переместите указатель глуб­
же внутрь представления и попробуйте снова. В ыбрав все элементы, выпол ните
команду Editori=> Resolve Auto Layout l ssues i=>Add M issing C onstraints. После этого
вы увидите, что все представления и элементы управления соединены между
собой и с контейнерны м представлением тонкими голубы м и отрезками . Кажды й
из этих отрезков представляет ограничение. Это намного лучше, чем позволить
програм ме Xcode создать автоматические ограничения, потому что теперь у вас
есть возможность модифицировать каждое огран ичение при необходимости .
Примеры такой модификации м ы приведем п о мере изложения.
1
ПОДСКАЗКА. Для того чтоб ы п рименить ограничения к о всем представлениям , принадле­
жащим контроллеру, можно в ы б рать контроллер представлени й в окне Document Outline
и вы полнить команду Editoгq Resolve Auto Layout l ssuesqAdd Missing C onstraints.
1 40
ГЛАВА 4 !бi Н О В Ы Е УП РАЖН Е Н И Я С И НТЕРФ Е Й С О М
Теперь, когда все необходимые огран ичения заданы, м ы можем удал ить пре­
дупреждения, поя вивш иеся в окне навигатора проблем. Для этого выберите кон­
троллер п редставления в окне Document Outline и в ы пол н ите команду Editorq
Resolve Auto Layout l ssues q U pfate Frames в меню Xcode. В резул ьтате предуп­
реждения о проблемах с макетирован ием должны исчезнуть.
Создание и присоеди нение выходов
Наше приложение почти готово к испытанию. Первая часть и нтерфейса у нас
есть. Осталось создать и п рисоед и н ить выходы . Графическому представлению
и меткам и нтерфейса выходы не нужн ы, потому что мы не будем изменять их
во время вы полнения п рограм м ы . Однако два поля редактирован ия я вляются
пассивными элементами управления, хранящими данные, которые будут исполь­
зоваться в нашем коде, поэтому для них выходы необходим ы .
Как в ы , вероятно, пом н ите, п рограм ма Xcode позволяет создавать и присо­
еди нять выходы одновременно с помощью помощн и ка редактора, окно которого
должно быть открыто.
В ыберите свой файл раскадровки в навигаторе проекта. Если места на экра­
не недостаточно, выпол н ите команду View q Utilities q H ide Utilities, чтобы скрыть
вспомогател ьную панель . На панели быстрых переходов в окне помощн ика ре­
дактора выберите файл Vi ewCont r o l l e r . swi f t (рис. 4. 1 6).
�
r:t fl 0. /f!) ф 1'11
• I Ollnltol '""'
,
.
.
•
.
"...
.
� �..-tl.
!::).
-
�
�
8 Conl•lll •""
')..: (
С..11
8 .
•
11 Vtw t«itro!... ._
· �·"""
о • •
лpress- )
1!.%
'
Рис. 4 . 1 6 . Область редакти рова н и я раскадровки п р и в кл юч е н н о м п о м о щ ­
н и ке . Сп рава п о к а з а н а область п о м о щн и ка , в кото рой н аходится ф а й л View
Con t ro l l e r . s w i f t
ГЛАВА 4 � Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
1 41
Теперь соеди н и м объекты . Удержи вая клавишу <Control>, перетащите у каза­
тел ь от представления, расположенного прямо над файлом Vi ewC o n t ro l l e r .
s w i f t , в точ ку, распол оженную под строкой ViewController. Появится серое
вспл ывающее окно, содержащее строку l nserts Outlet, Action , ог Outlet Collection
(рис . 4. 1 7). Отпустите кнопку м ы ши, и откроется меню, которое вы уже в идели
в предыдущей главе. М ы хотим создать выход с именем name F i e l d, поэтому
введите строку name F i e l d в поле Name, а затем нажм ите клавишу <Retum>
или щелкните на кнопке Connect.
.
_,. ...,
--
·
--...... ...
•
-
.
�
:;; '�J •-'
IJ U lJ
•
лpress·
* - --
Рис . 4 . 1 7 . Дл я того чтоб ы создать и п ри соеди н ить выход name Fi e l d , м ы вкл ю ­
ч и л и помощн и к реда ктора и п е ретащили указатель и з и сходного кода в соот­
ветствующее поле редакти рова н и я , удерживая кла в и ш у < Contro l >
Теперь у нас есть свойство name F i e l d в классе Vi ewC ont ro l l e r, которое
связано с верхн и м полем редактирован ия. Сделайте то же самое со вторым полем
редактирования, создав для него выход и связав его со свойством numЬe r F i e ld.
Посл � этого код будет выглядеть так, как показано в л исти нге 4. 1 .
Листинг 4 . 1 . Связанны е поля р е дактирования
c l a s s Vi ewCont r o l l e r : U I V i e w C o n t r o l l e r (
@ IBOUt l e t weak var nameFi e l d : UI TextFie ld !
@ IBOUt l e t weak var numЬerFi e l d : U I TextFiel d !
1 42
ГЛАВА 4 11! Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
З акрыт ие кл авиатуры
Посмотрим, как работает наше приложение. В ы пол н ите команду Productc>Run.
Приложение должно попасть в симулятор IOS . Щел кн ите на поле редактирова­
ния Name, чтобы на экране поя в илась обычная клавиатура.
ПОДСКАЗКА. Если клавиатура в симуляторе не появляетс я , значит, симулятор настроен
на работу с клавиатурой подкл юченного устройства . Для того чтобы исправить ситу­
аци ю , сбросьте флажок у команды Hardwarec::Ж e yboaгd q Connect Hardware Keybord в
меню симулятора IOS и повторите запуск приложе н и я .
Когда на экране поя в ится цифровая клавиатура, введите имя и косн итесь поля
редактировани я N u m ber. Должна поя в иться цифровая клавиатура (рис. 4. 1 8).
Каркас Сосоа Touch предоставляет все функционал ьные возможности для сво­
бодного добавления полей редактирован ия в свой и нтерфейс.
iPhone 6s - IOS 10.О (14А5261Щ
h
C1rrkJr •
a:•s Ам
-
лpress·
А Good Friend
1 23456789
1
2
3
АВС
DEF
GНI
JKL
MNO
PORS
TUV
WXY2
4
7
5
8
о
6
9
<Ю
Рис . 4 . 1 8 . Кл авиатура появляется а вто м а ­
тически , когда в ы касаете с ь л и бо поля р е ­
дакти рован и я , л ибо п о л я ц и ф р ы
Но осталась одна маленькая проблема. Как убрать клавиатуру с экрана? По­
п ытайтесь. Как видите, н и чего не происходит.
ГЛАВА 4 w Н О В Ы Е У П РАЖ Н Е Н И Я С И Н ТЕРФЕ Й СОМ
1 43
Закрытие клавиатуры при нажатии кнопки Done
Поскол ьку клавиатура я вляется виртуал ь н ы м , а не физическим устройством,
нам следует обдумать операци и, которые необходи м ы для того, чтобы она ис­
чезала с экрана, когда пол ьзователь заканч ивает работать с ней. Когда пользо­
вател ь нажмет кнопку Done, расположенную на виртуал ьной клавиатуре, будет
сгенерировано событие D id End On Exit, и в это время вы должны сообщить
полю редактирования, чтобы оно передало управление и клавиатура исчезла с
экрана. Для этого необходимо добавить в наш класс контроллера метод, вы пол­
няющий действие.
Выберите в нави гаторе проекта файл ViewCont ro l l e r . s w i f t и добавьте
следующие строки (листин г 4.2).
Листинг 4 . 2 . М е тод для закрытия клавиату ры
@ IВAc tion func tex tFiel c!DoneEdi ting ( sende r : U I TextFi e l d )
{
sender . re s i gn Fi r s tRe sponder ( )
Как было показано в главе 2, первым реагирующим объектом я вляется эле­
мент управления, с которым пол ьзовател ь взаимодействует в дан н ы й момент.
В новом методе м ы с н и маем наш элемент у п равления с рол и первого реаги­
рующего объекта, передавая ее предыдущему элементу управления, с которым
работал пол ьзователь. Когда поле редактирован ия получает статус первого реа­
гирующего объекта, клавиатура, связанная с н и м , исчезает с экрана.
Сохран ите файл ViewCont ro l l e r . swi f t и вернитесь к раскадровке, чтобы
инициировать задан ное действие из обоих полей редактирования.
Выберите файл Ma i n . s t o r yb o a rd в окне нави гатора п роекта, оди н раз
щел кн ите на поле редактиро ван и я Name и нажм ите комб и нацию кл авиш
<Option+X+б>, чтобы вызвать и нспектор связей. На этот раз м ы не хотим гене­
рировать событие Touch Up l nside, испол ьзован ное в предыдущей главе. В место
него сгенерируем событие Did End On Exit, поскол ь ку именно оно возни кает,
кода пол ьзовател ь нажимает кнопку Done на вирrуал ьной клавиатуре.
Перетащите указател ь от кружоч ка, расположен ного с права от события Did
End On Exit, к желтой п и ктограмме View Controller и соедините ее с действием
t e x t Fi e l dDoneEdi t i ng . Повторите эту операци ю для второго поля редакти­
рования, сохраните файл и нажм ите комби нацию клавиш <X+R> , чтобы снова
запустить приложение.
Коrда поя вится си мулятор, щел кн ите на поле Name, наберите в нем что­
нибудь и нажм ите кнопку Done . С корее всего, клавиатура исчезнет, как вы и
хотели . Отлично! А что вы скажете о поле N u m ber? Где кнопка Done для нее
(см . рис. 4. 1 8)?
Не все схемы клавиатуры и меют кнопку Done. Мы, конечно, можем заста­
вить пол ьзователя коснуться пол я редактирования Name, а затем нажать кнопку
Done, но это не очень удобно. А м ы хотим , чтобы пол ьзователю было удобно
работать с наш и м приложением . Посмотрим, как вы йти из этой ситуаци и .
1 44
ГЛАВА 4 lf'J. Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕ Й С О М
Закрытие клавиатуры п рикосновением к фону
В бол ь ш и нстве п р иложе н и й ком пан и и Арр\е дл я систе м ы iOS, имеющих
поля редактирования, нажатие представления за пределам и акти вных элементов
управления приводит к закрытию клавиатуры. Попробуем реал изовать эту фун­
кционал ьную возможность в нашем приложе н и и .
Ответ уди вит вас с воей п ростото й . Н а ш е представление изображений и ме­
ет свойство vi ew, у наследованное от класса U IVi ewCon t r o l l e r и соответ­
ствующее главному п редставлен и ю в раскадровке. Оно указы вает на экземп­
ляр класса U IVi ew, которы й фун кционирует как контей нер для всех элементов
пол ьзовател ьского и нтерфейса. И ногда его назы вают контей нерн ы м представ­
лением (container v i ew), потому что основ н ы м его назначен ием я вляется хране­
ние всех дру гих представлени й и элементов управления . Со всех точек зрения
это контейнерное представлен ие я вляется фоном для нашего пол ьзовател ьско­
го и нтерфейса. Н ам необходимо л и ш ь распознать, когда пол ьзовател ь коснется
его. В главе 1 8 будет оп исано нескол ько способов, позволя ющих это сделать.
В классе U I Re s ponder, п роизводном от класса U IVi ew, есть методы, которые
вызы ваются кажд ы й раз, когда пол ьзовател ь касается п редставления одним
ил и нескол ь к и м и пал ьцам и, п роводит пал ьцам и по нему ил и отн имает пал ьцы
от представления . Оди н из этих методов можно переопредел ить (в частности ,
метод, которы й вызы вается, когда пол ьзовател ь отн и м ает п алец от экрана) и
добавить в него код. Другой способ подразумевает добавление механизма рас­
познава н и я жестов (gesture recogn izer) в контей нерное п редставление. Этот
механ изм п рослу ш и вает события, которые генерируются, когда пол ьзовател ь
взаимодействует с п редставлением, и пытается понять, что делает пол ьзова­
тел ь. В главе 1 8 описываются нескол ько механизмов распознаван ия жестов, со­
ответствующих раз н ы м последовател ьностя м действи й . Нам нужен механизм
распознаван ия прикосновен и я , с и гнал изирующий о событи и, когда пол ьзова­
тел ь при касается пал ьцем к экрану, а затем отн имает его от экрана за разумно
короткое время .
Для испол ьзован ия механ изма распознаван ия жестов необходимо создать
объект, настроить его, связать его с п редставлением, за которым м ы хоти м сле­
дить в ожидани и событи й, связан ных с прикосновением, и добавить метод дейс­
твия в класс контроллера представления. Этот метод будет вызы ваться, когда бу­
дет распознано прикосновение. Механизм распознавания жестов можно создать
и настроить в коде ил и в п рограм ме I nterface Builder. В данном случае м ы будем
испол ьзовать I nterface B u i lder, потому что это п роще . Верн итесь в раскадровку
и откройте окно библиотеки объектов . Затем найдите в нем объе кт механ из­
ма распознаван ия прикосновен ия, перетащите его на раскадровку и оставьте в
контейнерном представлени и . Во время работы механ изм распознавания жестов
остается невиди м ы м , поэтому вы не увидите его в раскадровке, но он поя вится
в окне Document Outline, как показано на рис. 4. 1 9.
ГЛАВА 4 >;: Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
т
1 45
С1 Vlew Controller Scene
View C ontroller
т
Тор Layout Guide
Bottom Layout Guide
View
т
apress_iogo
F Name Field
1>
L Label
" F Number Field
1>
liJ Constraints
liJ Constraints
L Label
1>
C!D First Responder
lia Exit
11 Тар Gesture Recognizer
1 Storyboard Entry Point
Рис . 4 . 1 9 .
Меха н и з м
распознаван и я
п р и коснове н и й в окне Document Outline
Когда вы выберете механизм распознавания прикосновений, в окне и нс пекто­
ра атрибутов поя вится набор настроек, показанный на рис. 4.20.
Тар Gesture Recognlzer
Recognize
Taps
1
v
Touches
1
v
Oesture Recognlzer
State С1 EnaЫed
Behavior
С1 Cancels touches in view
,.._.
Del ays touches began
С1 Delays touches ended
-�-- --
--
Рис . 4 . 20 . Атр и буты м еха н и з м а рас ­
познава н и я п р и косновен и й
Поле Taps задает кол ичество прикосновен и й , которые пол ьзовател ь должен
вы пол н ить, чтобы механ изм их распознал, а поле Touches о пределяет, скол ь­
ко пальцев должно быть задействовано в прикосновени и . По умолчанию пред­
усмотрено, что пол ьзовател ь оди н раз прикоснется к экрану одн и м пал ьцем,
поэтому остал ьные поля можно оставить неизменн ы м и . Остал ь н ы е атрибуты
нас также впол не устраи вают, так что нам остается л и ш ь связать механ изм
1 46
ГЛАВА 4 !Ш Н О В Ы Е УП РАЖН Е Н И Я С И НТЕРФЕЙСОМ
распознавания с методом действия . Для этого откройте файл ViewContro l l e r .
swi f t в окне помощника редактора, нажм ите клавишу <Control> и перетащите
указател ь с механизма распознавания в окне Docu meпt Outl iпe на строку, рас­
положенную над закры вающей скобкой в файле ViewCoпtroller. swift. Отпустите
кнопку мыши, когда увидите обы ч ное вспл ы вающее окно, подобное показан­
ному на рис. 4 . 1 6 . В этом окне необходимо измен ить тип соединения на Actioп,
а имя метода - на oпTapGestu reRecogп ized . В резул ьтате среда Xcode добавит
метод действия и свяжет его с механ измом распознаван ия прикосновения. Этот
метод будет вызы ваться каждый раз, когда пол ьзовател ь прикоснется к главно­
му представлению. На осталось л и ш ь добавить код, чтобы закрыть клавиатуру,
есл и она была открыта. М ы уже знаем, как это сделать, поэтому измен им код
так, как показано в листи нге 4.3 .
Л и стинг 4 . 3 . К од закрытия клавиату ры в м е хан изм е распознавания прикоснов е ни й
@ I BAc t i o n f u n c onTapGe s t u r e R e c o gn i z e d ( s e n de r : AnyOb j e c t ) {
nameField . res ignFi rs tRe sponder ( )
numЬerFie ld . res i gnFi r s tResponder ( )
Этот код просто устанавл и вает у обоих полей редактирования статус пер­
вого отвечающего объекта. Можно совершенно безопасно вызы вать метод
r e s i g n F i r s t Re sponde r ( ) из элемента управления, которы й не я вляется пер­
вым отвечающи м объектом, поэтому его можно вызы вать из обоих полей редак­
тирован ия, не проверяя, какое из них я вляется первы м отвечающи м объектом .
Соберите и вы пол ните свое приложение еще раз . На этот раз клавиатура должна
исчезнуть не тол ько после прикосновения к кнопке Dопе, но и после того, как
пол ьзовател ь прикоснется к л юбому месту экрана за пределами активного эле­
мента управления . И менно такая реакция я вляется наиболее естественной.
Добавление ползунка и м етки
Добавим в приложение ползунок и метку, значение которой будет изменяться
в зависимости от позиции ползунка. Выберите файл Ma i n . s t o ryboard в окне
навигатора проекта, чтобы добавить несколько элементов управления в пол ьзо­
вател ьский и нтерфейс приложения. Найдите ползунок в библиотеке объектов
и разместите его под полем редактирован ия N u m ber, оставив немного места.
Щел кните на вновь добавленном ползунке, чтобы выбрать его, а затем нажм ите
комбинацию клави ш <Optio11+3C +4>, чтобы вернуться к окну инспектора, если
оно еще не открыто. Это окно должно выглядеть так, как показано на рис. 4.2 1 .
Ползунок позволяет выбрать ч и сл о в определен ном диапазоне. С помощью
и нспектора установите м и нимал ьное значение рав н ы м 1, максимальное значе­
н ие - рав н ы м 1 0 0 , а нач ал ьное значен ие - 5 0 . Установите флажок Eveпts
Coпtiп uous U pdate. Он обеспеч ит непрер ы в н ы й поток событи й при изменении
значен ия ползунка.
•
"
•
.,_ ,..
, __
·
1 47
r. � .. •
1 1 u [.\
Co!lllOl ,,,.. 1 • "'- ••
� r.­
·-
ГЛАВА 4 ;:v Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
�.i .,...
• c.l vi.. � k.м
·
--
... ._ .....
_ ._ ....
·-r-
•
.
" , __ ,....,
" .с-......
· ­
-• • С--•*'1•
. �" --­
ll •d
e. lfll Gf:tU'll �
---
1-
с Ф • о в е
1
-
. . .....
" .,.. .....
, • ..... "" � a.f-
, .
�
·
-.." �
c:z::i Dlf...it
- nr.t t;;::;3 08I...
·- · � U\IO!t'-
ApreSS'
-
оо :
о:
, ,
.
.
8
•
•
_"
·­
_"
- -
8
8
о;
,"
-- • u.i _..,. t....,.
,,
- == IJ
-
(Jj .
,...
т s м t.t-1 -
+
•
!:> {) @ о
8
�=:.::=:-.::.
--
о
�· .
Рис. 4 . 2 1 . И нс п е ктор , де м о н стри рующий атрибуты ползу н ка
Перетащите метку в окно и поместите ее слева от ползун ка, испол ьзуя го­
лубые л и н и и разметки для выравнивания по верхнему краю ползу н ка и левому
краю представления (рис. 4.22).
r
1т
•
'1 !
•:;J
., .
""'i
1;
J,
1
� 11 Name:
1
1-4Н·�-----·
№mt>er.
i
-· ··-·--·- ·-
1j
1!
lJ
·--·------.-·.
·i1
!
1
-·�-
-- -
-�-�
..
1
Рис . 4.22. Разм е ще н и е метки пол зун ка
Дважды щел кн ите на вновь добавленной метке и измените ее текст с Labe l
на 1 0 0 . Это наибол ьшее значен ие, которое может п р и н имать ползунок, и вы
1 48
ГЛАВА 4 \'r Н О В Ы Е УП РАЖН Е Н И Я С И НТЕРФ Е Й С О М
можете испол ьзовать его для определения правил ьной ширины ползунка. По­
скол ьку строка 1 О О короче, чем строка Labe l, вы должны изменить размеры
метки, захватив среднюю правую точ ку изменения размера и перетащив ее вле­
во. Постарайтесь остановиться до того, как размер шрифта станет уменьшаться .
Если это все ж е произойдет, перетащите точ ку изменен ия размера вправо и про­
должайте ее тя нуть, пока не восстановится исходн ы й размер шрифта. Можно
также испол ьзовать фун кциональную возможность "вписать в форму", которую
мы уже обсуждал и ранее. Для этого следует нажать комби нацию клавиш <Х+=>
ил и выбрать команду Editorc::> Size to Fit Content.
Затем измен ите размер ползун ка, щел кнув на нем и перетащи в влево левую
точ ку изменен ия размера так, чтобы голубые л и н и и разметки указал и, где сле­
дует остановиться .
Добави в два допол н ител ьных элемента управления, м ы должны задать со­
ответствующие ограничения A uto Layout. Это можно легко сделать, выбрав
п и ктограм му View Controller в окне Docu ment Outline и выпол н и в команду
Editorc::> Resolve Auto Layout l ssuesc::> A dd Missing Constraints. С реда Xcode автома­
тически настроит эти ограничения, чтобы о н и соответствовал и позициям всех
элементов управления на экране.
Создание и связывание действий и выходов
Нам осталось л и ш ь связать выход и действие с эти м и двумя элементам и уп­
равления. Нужен в ыход, у каз ы вающий на метку, чтоб ы можно было изменять
значение метки при движе н и и пол зунка. Кроме того, нужен метод действия,
чтобы вызы вать его при изменении положения ползунка. В ызовите помощник
редактора для редактирован ия файла ViewC o n t ro l l e r . s w i f t , а затем нажм ите
клавишу <Coпtrol> и перетащите указател ь от ползунка к точ ке кода, располо­
женной под методом onTapGe s t u reRecogni t i z e d ( ) в окне помощн ика редак­
тора. Когда поя вится вспл ы вающее окно, измен ите значение поля Connection
на Ac t i on, наберите строку o n S l ide rChanged в поле N a me, наберите в поле
Туре строку U I S l i d e r, а затем нажм ите клавишу <Returп>, чтобы создать и
соединить выход.
Нажм ите клавишу <Contro\> и перетащите указател ь от в новь созданной мет­
ки (" 1 0 0") к помощн и ку редактора. Н а этот раз перетащите указател ь в точ ку,
расположенную н иже свойства n u m berField в верхней части файла. Когда поя­
вится вспл ы вающее окно, введите строку s l i de rLabe l в поле Name и нажм ите
клавишу <Retum>, чтобы создать и соединить выход.
Реализация метода действия
Несмотря на то что програм ма Xcode создала и связала н а ш метод действия,
м ы все еще должн ы нап исать код самого метода. Добавьте в метод onS l i der
Changed ( ) код, показан н ы й в л исти нге 4 .4 .
ГЛАВА 4 е1 Н О В Ы Е УП РАЖН Е Н И Я С И НТЕРФЕЙСОМ
1 49
Л исти нг 4 . 4 . И зм е н е ни е м етки в зависимости от позици и полз у н ка
@ I BAc t i o n f u n c o n S l i de r C h a n g e d ( s e n de r : U I S l i de r )
s l i de r Labe l . t e x t
" \ ( l r o u n d f ( s e nde r . va l ue ) ) "
=
Метод l roundf ( ) при вызове из стандартной библ иотеки языка С получает
текущее значение ползун ка и округляет его до бл ижайшего целого числа. Ос­
тал ьной код создает строку, содержащую это число, и присваи вает ее метке.
Это обес печ и вает реакцию контроллера на перемещение ползунка. Однако для
того, чтобы быть точ н ы м и , необходимо убедиться, что метка правильно отражает
значение ползунка еще до того, как пользовател ь его коснется . Дпя этого в ме­
тод viewDidLoad ( ) необходимо добавить строку s l iderLaЬel . text = 1 1 5 0 1 1 •
Этот метод вы пол няется сразу после начала загрузки приложения из файла
раскадровки, но до того, как оно будет отображено на экране. Добавленная стро­
ка гарантирует, что пол ьзовател ь сразу увидит правил ьное начал ьное значение.
Сохран ите файл . Затем нажм ите комбинацию клавиш <X+R>, запустите при­
ложение в си муляторе i Phone и испытайте ползунок. При его перемещении вы
должны увидеть изменение текста на метке, п роисходящее в реальном времени .
Еще один фрагмент приложения готов. Однако, есл и перетащить ползунок влево
(сделав его значение мен ьше 1 О) ил и до упора вправо (положив его значение рав­
н ы м 1 00), мы увиди м странные я вления. По мере уменьшения значения ползунка
до одной цифры метка будет сжиматься горизонтально, но, достигнув значения
3 , она станет расширяться. Теперь, кроме текста, которы й содержит метка, мы
не увидим саму метку и не обнаружим изменение ее размера, хотя увидим, что
ползунок действительно изменяет его, делая метку то больше, то меньше. Тем
самы м поддерживается постоя нное расстоя ние между н и м и меткой.
Это просто побоч н ы й эффект програм м ы l nterface Builder, помогающей нам
создавать гибкие и точ но реагирующие пол ьзовател ьские и нтерфейсы . Мы уже
упоминали об ограничениях и теперь видим , как они работают. Когда м ы изме­
нял и размер ползунка так, чтобы он почти касался метки , п рограм ма l nterface
B u i lder создавала ограничен ие, п оддержи вающее горизонтал ьное расстоя ние
между эти м и элементам и постоя н н ы м .
К счастью, это поведение можно переопредел ить собствен н ы м огран ичени­
ем. Вернитесь в среду Xcode, выберите метку в своей раскадровке и щел кн ите
на п и ктограмме Pin, расположенной в н ижней части раскадровки . В откры в­
шемся вплывающем окне установите флажок Width и щел кн ите на кноп ке Add
1 Constraint. В резул ьтате возникнет ограничение с высоким приоритетом, сооб­
щающее системе макетирован и я : "Не изменяйте ш и ри ну этого ползу н ка". Есл и
теперь вы нажмете клави ш и <X+R>, чтобы собрать и в ы пол н ить приложение
снова, то увидите, что ползунок бол ьше не растя ги вается и не сжимается при
его перетаскиван и и .
В книге есть еще нескол ько примеров ограничен и й и их применени я . Однако
настало время перейти к реал изаци и перекл ючателей .
1 50
ГЛАВА 4 � Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
Р е али з ац ия перекл ю ч ате л е й , кнопки
сегментиров ан ного эл емен та у п ра влен ия
Вернемся к среде Xcode. Эти метания rуда и обратно могут показаться не­
м ного стран н ы м и , но переходы от редактирован ия кода в среде Xcode к на­
строй ке и нтерфейса в програм ме l nterface B u i lder с эпизодически м и остановка­
м и для проверки приложения в симуляторе системы IOS
обыч ная практика
при разработке програм м .
В нашем п риложе н и и предусмотрены два перекл ючателя, представля ющие
собой маленькие элементы управления, и меющие тол ько два состоя ния: включен
и выкл ючен . Кроме того, мы добави м сегментированный элемент управления,
который будет скрывать и отображать перекл ючател и . Наряду с этим элементом
управления добави м кнопку, которая поя вляется на экране, когда пол ьзовател ь
нажимает правую часть сегментированного элемента управления.
Вернитесь к раскадровке, перетащите сегментирован н ы й элемент управления
из библиотеки объектов в окно View немного н иже ползун ка и отцентруйте его
по горизонтали (рис. 4.23 ).
Дважды щелкн ите на слове First на сегментированном элементе управления
и измените строку F i r s t на строку Swi t che s . Сделав это, повторите эrу про­
цедуру для сегмента Second, переименовав его в Button (рис. 4.24) и перетащите
этот элемент управления в центр.
-
f;i! �
лpress-
\
100 -----
Рис . 4.23. Разм е ще н и е сег­
Рис. 4 . 24 . П е реи м е н ован ие
м е н т и р о ва н н о г о п р едста в ­
л е н и я в раскадровке
сегме нтов
ГЛАВА 4 «i! Н О В Ы Е У П РАЖН Е Н И Я С И НТЕРФЕ Й С О М
1 51
Добавление переключателей с меткам и
Захватите перекл ючател ь в библиотеке, поместите его на представление чуть
ниже сегментирован ного элемента у правления и выровня йте по левому краю.
Перетащите на представлен ие второй переключател ь и выровня йте его по пра­
вому краю, расположив на одной л и н и и с первым перекл ючателем, как показано
на рис. 4.25 .
лpress·
100 -----
с
1
Рис. 4 . 2 5 . Добавл е н и е п е р е кл ю ­
ч ател е й в п редста вл е н и е
ПОДСКАЗКА. Удерживая нажатой клавишу < O ption > и перетаскивая объе кт в програ м ­
ме lnterface Builder, вы создаете коп и ю этого элемента . Если вам необходимо со­
здать несколько экземпляров одного и того же объекта , то будет быстрее перетащить
из библ иотеки тол ько оди н объект, а затем с помощью указанного приема сделать
стол ько копий , сколько потребуется.
Для трех добавленных нам и ограничений необходим ы огран ичения разметки .
На этот раз м ы добавим огран ичения вручную. С начала выберите сегментиро­
ван н ы й элемент управления и зафиксируйте его в центре, щел кнув на п и ктог­
рам ме Aligп, установив флажок H orizontally in Conta i ner и щел кнув на кнопке Add
1 Constra i nt. Затем выберите сегментирован н ы й элемент управления, нажм ите
клавишу <Control> и перетаскивайте указатель вверх до тех пор, пока фон глав­
ного � редставления не станет голубы м . Отпустите кноп ку м ы ш и и вы пол ните
команду Veгtical Spacing to Тор Layout G u ide, чтобы зафиксировать расстоя ние от
сегментирован ного элемента управления до верхнего края представлен и я .
Перейдем к перекл ючателя м . Нажм ите клавишу <Control>, перетащите ука­
зател ь влево вверх по диагонал и и отпустите кнопку м ы ш и . Нажав и удерживая
клавишу <Sh ift>, вы пол н ите команды Lead ing Space to Conta i ner Marg i n и Vertical
Spacing to Тор Layout G u ide из вспл ывающего меню, а затем нажмите клавишу
1 52
ГЛАВА 4 ,,,, Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФ Е Й С О М
<Returп> или щел кните м ышью где-н ибудь за пределами меню, чтобы применить
огран ичения. Сделайте то же самое со вторым перекл ючателем, но на этот раз
перетащите указател ь вверх и вправо по диагонали и выполните команды Trailing
Space to Container Marg i n и Vertical Spacing to Тор Layout G u ide. После того как
вы примен ите ограничения, программа Xcode предложит вам разные варианты
в зависимости от направления, в котором вы п ровели соедин ител ьную линию.
Есл и вы перетащил и объект по горизонтал и, вам предложат прикрепить элемент
управления к левому ил и правому краю родител ьского представления, а если по
верти кал и - то к верхнему ил и н ижнему краю. В дан ном случае нам нужны
одно горизонтал ьное и одно верти кал ьное ограничения для каждого переключа­
теля, поэтому мы вел и соедин ительные линии по диагонал и .
Связывание и создание выходов перекл ючателя и действий
Перед тем как добавить кнопку, м ы собираемся связать выходы с обоими пе­
реключателями. Кнопка, которую мы добавим позднее, фактически будет делить
одно и то же место с переключателями, затрудняя связывание, поэтому мы хотим
сделать это заранее. Поскольку кнопка и перекл ючател и н и когда не поя вляются
на экране одновременно, разместить их в одном и том же месте -- не проблема.
Испол ьзуя помощн и к редактора, нажм ите клавишу <Coпtrol> и перетащите
курсор от перекл ючателя к точ ке, расположенной ниже последнего выхода в
файле Vi ewC ont r o l l e r . s w i f t . Когда п оя вится вспл ы вающее окно, назовите
выход leftSw itch и нажм ите кл авишу <Returп>. Повторите эту п роцедуру для
другого перекл ючателя, наз вав выход rig htSwitc h .
Теперь выберите левый перекл ючател ь, снова щел кнув на нем . Нажм ите кла­
вишу <Coпtrol> и перетащите курсор в окно помощни ка редактора. На этот раз
остановитесь над скобко й в кон це объя вления класса. Когда поя в ится всплы­
вающее окно, изме н ите значение поля Con nection на Ac t i on, присвойте мето­
ду имя onSwi t chChanged ( ) , задайте атрибут Туре его аргумента sender рав­
н ы м U I Sw i t c h и н ажм ите клавишу <Return>, чтобы создать новое действие.
Повторите эту процедуру для п равого перекл ючателя, но вместо создания но­
вого действия проведите соеди н ител ьную л и н и ю к ранее создан ному методу
onSwi tchChanged ( ) . Как и в предыдущей главе, будем испол ьзовать один ме­
тод для обоих перекл ючателей .
В заключение н ажмите клавишу <Control> и перетащите курсор от сегменти­
рованного элемента управления к помощни ку редактора в точку, расположенную
под методом onSwit chCha nged ( ) . Вставьте новый метод toggl eCont ro l s ( ) ,
как вы делали это раньше, но на этот раз задайте атрибут Туре его параметра
sender рав н ы м U I S e gment edCont ro l .
Реализация действий переключателя
Сохран ите раскадровку и щел кн ите на файле ViewC o n t ro l l ew . swi ft, от­
крытом в окне помощн и ка редактора. Найдите метод onSwi t chCha nged ( ) и
добавьте в него строки, при веде нные в л истю� ге 4 . 5 .
ГЛАВА 4 1;; Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
1 53
Листи нг 4 . 5 . Метод onSwi t chChanged ( )
@ I BAc t i o n f u n c o n S w i t c h C h a n g e d ( s e nde r : U I S w i t c h )
l e t s e t t i ng = s e nde r . i s On
l e f t S w i t c h . s e t On ( s e t t i n g , a n i ma t e d : t r u e )
r i g h t S w i t c h . s e t On ( s e t t i ng , a n ima t e d : t r u e )
Метод onSwi t chChanged ( ) вызывается при н ажати и одного из двух пере­
кл ючателей. В этом методе мы п олучаем значение свойства i s On аргумента
s e nder, представляющего нажатый перекл ючател ь, и испол ьзуем это значение
для установки обоих перекл ючателей. Идея заключается в том, чтобы задание
этого значения для одного перекл ючателя изменяло состоя н ие другого перекл ю­
чателя, обеспечи вая их синхрон изацию .
Аргумент s ende r всегда будет прини мать одно из двух значений : l e f t Swi t ch
ил и r i ghtSw i t ch. В этом случае может возникнуть вопрос : зачем нам два раза
присваивать значения? Ответ: из п рактических соображе н и й . Это п роще, чем
каждый раз устанавл ивать значение для обоих перекл ючателей, чтобы опреде­
лять, какой из них сделал вызов. Как тол ь ко перекл ючател ь вызовет наш метод,
правильное значение уже будет установлено и повторное присвоение того же
самого значения ничего не изменит.
Добавление кнопки
Верн итесь в програм му I nterface B u i lder и перетащите элемент управления
Поместите его п ря мо поверх крайней
слева кноп ки и выровняйте по левому краю так, чтобы ее центр находился на
одной линии с обо и м и переключателям и (рис. 4 .26).
Button из библ иотеки на п редставление.
лpress·
1
---7!
'00
11��
1
1
'---
-
Рис. 4 . 2 6 . Доба вл е н и е к н о п к и п о верх
существующих п е р е кл ю ч ателе й
1 54
ГЛАВА 4 t': Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
Захватите среднюю точку изменения размера на правой гран ице кнопки и
перетаскивайте ее до тех пор, пока не достигнете голубой линии разметки, обоз­
начающей правое поле. Кнопка должна полностью покрыть оба перекл ючателя.
Однако, поскольку по умолчанию кнопка считается прозрачной, мы по-прежне­
му будем видеть перекл ючател и (рис. 4.27).
лpress·
�i
100 ----�,
о
Button
о
Cj
Рис . 4 . 27 . После и з м е н е н и я раз м е ро в к н о п ка
должна пол ностью скр ыть оба п е рекл ю ч ател я
Дважды щелкните на кнопке и присвойте ей метку Do Somet h i n g .
Для этой кнопки нужны ограничения Auto Layout. М ы прикреп им ее к право­
му краю и обеим сторонам главного представления . Нажм ите клавишу <Control>
и перетаскивайте указатель вверх от кнопки, пока фон представления не станет
голубы м , а затем отпустите кнопку м ы ш и и вы пол н ите команду Vertical Spa­
cing to Тор Layout G u ide. Теперь нажм ите клавишу <Control> и перетаски вайте
указател ь по горизонтал и, пока фон главного представления снова не станет
голубы м , а затем вы пол н ите команду Lead i n g S pace to Conta i ner Marg i n . Этот
вариант станет досту п н ы м , тол ь ко есл и вы переместите указател ь достаточно
далеко влево от кнопки, поэтому есл и вы его не увидите, то попробуйте снова и
перетащите указатель влево, далеко за пределы кнопки. В закл ючение нажм ите
клавишу <Control>, перетаскивайте указател ь вправо от кнопки до тех пор, пока
фон главного п редставления не станет голубы м , и вы пол н ите команду Tra i l i n g
S pace to Container Marg i n . Запустите приложен ие, чтобы увидеть резул ьтат.
Добавление и з обра жен и я н а кноп ку
Есл и сравн ить реал ьное приложен ие с приложением на рис. 4.2, то можно
заметить раз н и цу. Ваша кно п ка Do Somet h i n g в ы глядит не так, как на рисун­
ке. Это объясняется тем , что начиная с верси и iOS 7 кнопка, предусмотренная
по умолчанию, выглядит очен ь просто : обы ч н ы й фрагмент текста без контура,
ГЛАВА 4 1t1 Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
1 55
гран ицы, цветного фона и других декоративных атрибутов. Это пол ностью со­
ответствует принци пам дизайна, принятого ком панией Арр\е для iOS 7 и более
поздних версий, но и ногда хочется испол ьзовать собственные кнопки, и мы пла­
нируем создать свой вариант.
Больши нство кнопок на устройствах, работающих под управлен ием систем ы
iOS, нарисован ы с помощью изображений. М ы предусмотрел и изображения для
нашего примера в папке 04 Button Image s . Находясь в среде Xcode, выберите
пап ку As s e t s . xca s s e t s в окне навигатора проекта (этот каталог ресурсов м ы
уже испол ьзовал и для добавления логотипа ком пани и Apress) и перетащите оба
изображения из папки 0 4 Button Image s , открытой в окне Fi nder, в область
редакти рован ия, расположенную в окне Xcode . Эти изображения будут в кл ю­
чены в ваш проект и немедленно станут досту п н ы м и для вашего приложения.
-
-
Растягивающиеся изображения
Взглянув на изображения для добавленных нами кнопок, вы, вероятно, бу­
дете удивлены их размерам и . Они сл и ш ком маленькие и не способ н ы запол­
нить поверхность кнопок, добавленных в раскадровку. Это объяс няется тем ,
что изображения считаются растя гиваю щ и м ися (stretchaЬ\e). Б ибл иотека U I Kit
прекрасно умеет растя ги вать изображения и запол нять ими л юбое пространс­
тво. Растя ги вающееся изображение - это изображен ие, допускающее измене­
ние размеров, которое "знает", как целенаправленно изменить свои размеры так,
чтобы дости ч ь желаемого в нешнего вида. Для данного шаблона кнопки мы не
хотим равномерно растя гивать ее границы по всему изображению. О конеч н ые
элементы (edge insets) - это части изображения, измеряемые в п и кселях, раз­
меры которых нельзя изменять. Мы хоти м, чтобы фаска вокруг краев оставалась
неизменной независимо от того, какой размер и меет кнопка, поэтому необходи­
мо задать размер ее оконеч ных элементов.
Ран ьше эту часть работы приходилось п рограмм и ровать. Сначала надо было
измерить размер изображения в п и кселях, испол ьзуя графический редактор, а
затем задать это число в качестве размера оконечных элементов. В среде Xcode
6 зто бол ьше делать не нужно! Теперь можно в изуал ьно создать нарезку любого
изображения в своем каталоге ресурсов ! И менно зто м ы собираемся сделать .
Откройте каталог ресурсов As s e t s . x ca s s e t s в программе, а в нем выбе­
рите элемент wh iteButto n . В н ижней части области редактирования вы увидите
кнопку с меткой Show S l ici n g . Щелкните на ней, чтобы начать процесс нарез­
ки, которы й просто поместит кнопку Sta rt S l ic i n g поверх вашего изображения.
Щел кн ите на этой кнопке, и увидите три новые кнопки, позволя ющие задать
вид нарезки : по верти кали, по горизонтали или в обоих направлениях. Выберите
среднюю кноп ку, чтобы в ы пол н ить нарезку в обоих направлениях. П рограм­
ма Xcode быстро проанал изирует ваше изображение, а затем найдет раздел ы,
расположенные на однозначно определен ном расстоян и и от краев, а также вер­
тикальные и горизонтал ьные срезы, которые следует повторить. Эти границы
представлены в виде пунктирных линий (рис. 4.28). Есл и изображение сложное,
1 56
ГЛАВА 4 ;t! Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФ Е Й С О М
его можно подправить, перетащи в с помощью м ы ш и ; в нашем случае автомати­
ческие оконеч ные элементы работают п рекрасно.
whit
...
n - 1х
Рис. 4 . 2 8 . Н а р е з ка б е л о й
к н о п к и по умол ч а н и ю
В ыберите элемент ЫueButton и в ыпол ните его автоматическую нарезку. Гото­
во ! Эти графические элементы готовы к испол ьзованию.
Вернитесь в раскадров ку и щелкн ите оди н раз на кнопке Do Someth i n g . Вы­
дел и в кноп ку, нажм ите комби наци ю клавиш <Option+3C +4>, чтобы открыть
и нспектор атрибутов . Перейдите в окно и нспектора атрибутов и с помощью
вспл ы вающего меню измен ите тип с S y s t em на C u s t om. В этом инспекторе
можно задать изображение и фон своей кноп ки. М ы хоти м испол ьзовать фон
для демонстраци и растяги вающегося изображе н и я , поэтому откройте меню
Backg round и вы пол н ите команду wh iteB utto n . В ы увидите, что вся поверхность
кнопки запол нена бел ы м изображением .
Теперь м ы хоти м испол ьзовать голубую кно п ку для выбора внешнего вида
н ажатой кнопки. О состоя н иях кнопки м ы поговори м в следующем разделе, а
пока п росто обратите внимание на второе вспл ы вающее меню
State Confi g .
Объект класса U I Button может иметь м ного состоя ний, каждое из которых име­
ет свой текст и изображения. До сих пор м ы настраивал и состоя н ие по умол­
чанию, поэтому в ы пол н ите во вспл ы вающем меню команду H ig h l i g hted , чтобы
приступить к настрой ке этого состоян и я . Вы увидите, что вспл ы вающее меню
Backg round стало пусты м ; щел кните на нем и вы пол н ите команду ЫueButto n .
-
Состояния элемента управления
Каждый элемент управления в системе iOS и меет пять возможных состоя ний
и всегда в отдел ь н ы й момент времени п ребы вает тол ько в одном из них.
iiii
По умолча н и ю (defau lt). Чаще всего элементы у п равлен ия находятся в
состоянии, которое задано по умолчанию. И менно в этом состоя нии пре­
бывает элемент управления, есл и он не находится в другом состоя н и и .
!!}
Сфокусирован ное (focused). В системах, испол ьзующих механ изм фоку­
сирован ия, элементы управления переходят в сфокусирован ное состоя ние,
ГЛАВА 4 ® Н О В Ы Е У П РАЖН Е Н И Я С И НТЕРФЕЙСОМ
1 57
когда получают фокус. Сфокусированное состоя ние изменяет внеш н и й
вид элемента у правления, чтобы сигнал изировать, что он получил фокус.
Этот внеш н и й вид отличается от подсвеченного или выделенного. Дал ь­
нейшее взаимодействие с элементом управления может перевести его в
подсвеченное ил и выделен ное состояние.
"' Подсвеченное (h ighl ighted). П одсвечен ное состоя ние - это состоя ние, в
котором находится элемент управления, испол ьзуе м ы й в данн ы й момент.
Кнопка переходит в это состоян ие, когда пол ьзовател ь при касается к ней
пальце м .
щ;
Выбранное (se lected). Тол ько некоторые элементы управления поддержи­
вают выбранное состоя ние. Оно обы чно испол ьзуется для того, чтобы
обозначить, что элемент управления вкл ючен или выбран. В ыбран ное со­
стоя ние похоже на подсвечен ное, но элемент управления может по- п ре­
жнему находиться в в ыбранном состоян и и, даже есл и пользователь бол ь­
ше не использует этот элемент управления непосредственно.
�'
Недоступ ное (disaЫed). Элементы у п равления находятся в недосту пном
состоян и и , есл и они был и откл ючены с помощью перекл ючателя E naЫed
в программе l nterface B u i lder ил и их свойство i s E n a Ы e d и м еет значе­
н ие NO.
Некоторые элементы управле ния систе м ы iOS имеют атрибуты, прини ма­
ющие разные значе1шя в зависимости от их состоя н и я . Например, задав одно
изображение для свойства i sDefau lt, а другое - для i s H i g h l i g hted, мы сообщаем
системе iOS, чтобы она испол ьзовала одно изображение, когда пол ьзовател ь ка­
сается кнопки пал ь цем, а другое - в остал ьных случаях. По существу, при этом
мы настраи ваем два фоновых состоя ния кнопки в раскадровке.
ЗАМЕЧАНИЕ. В предыдущих изданиях книги перечислялись четыре состоян и я : Normal ,
H ig h l ig hted , Disa Ыed и Selected , которым соответство вал и значения перечисл е ­
ния в языке Objective -C U I Co n t ro l S t a t e N o rma l , U I C o n t r o l S t a t e H i gh l i g h t e d ,
U I Co n t r o l S t a t e E n a Ы e d и U I C on t r o l S t a t e S e l e c t e d . Описание этих значе н и й
можно найти в литературе , посвященной ран н и м версиям среды Xcode (до Xcode 8 )
и языка Swift (до Swift 3 ) .
Связывание выходов и действий кнопки
'
Нажм ите клавишу <Control> и перетащите указател ь от новой кнопки в окно
помощн и ка редактора, в точ ку, расположенную н иже последнего выхода в вер­
хнем разделе файла. Как тол ько поя в ится вспл ы вающее окно, создайте новый
выход с именем doSometh i n g Bu tton . Затем нажм ите клавишу <Control> и перета­
щите указател ь от кнопки к точ ке, расположенной над закры вающей фигурной
скобкой в конце файла. На этот раз вместо выхода создайте метод действия
onBut tonPre s s e d ( ) и установите атрибут Туре рав н ы м U I Button.
1 58
ГЛАВА 4 � Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
Сохраните результаты работы, вернитесь в среду Xcode и протестируйте при­
ложение. Вы увидите, что сегментированн ы й элемент управления работает, но
это н ичего нам не дает. Нам нужно определ ить какую-то логи ку, в соответствии
с которой кнопки и перекл ючатели будут отображаться и скры ваться .
Кроме того, изначал ьно кнопки должны быть скрыты . М ы не сделали этого
ран ьше, потому что эта задача немного сложнее, чем соеди нение выходрв и
действ и й . Теперь, когда в ы уже можете соединять выходы и методы, скроем
кнопку. Будем показы вать кноп ку, когда пол ьзовател ь нажмет правую полови­
ну сегментированного элемента управления, но в начале работы кнопка должна
быть скрыта. Нажмите комбинацию клавиш <Option+X +4>, чтобы открыть ин­
спектор атрибутов, найдите раздел View и щел кн ите на флажке H idden . В окне
I nterface B u i lder кнопка по-прежнему будет види мой.
Р е али з ац ия действия сег м енти рован ного
эл емен та уп ра в л ен ия
Сохраните раскадровку и щелкните на файле ViewContro l l e r . swi f t . Най­
дите метод toggleCont ro l s ( ) , которы й создала програм ма Xcode, и добавьте
в него новый код, приведенн ы й в листин ге 4 .6.
Листи н г 4 . 6 . М е тод, показы вающий и скрывающий п е р е ключате ли
@ I BAc t i o n f u n c t o g g l e C on t r o l s ( _ s e nde r : U I S e gme n t e d C o n t r o l )
i f s e nd e r . s e l e c t e d S e gme n t i n d e x = = О { / / Выбр а н ра здел s w i t c h e s
l e f t S w i t c h . i s H i dden = f a l s e
r i gh t S w i t c h . i s H i dd e n = f a l s e
d o S ome t h i n g B u t t o n . i s H i dd e n = t r u e
else {
l e f t S w i t c h . i s H i dd e n = t r u e
r i g h t S w i t c h . i s H i dd e n = t r u e
d o S ome t h i n g B u t t o n . i s H i dden = f a l s e
Этот код проверяет свойство s e l e c t e d S e gme n t i nd e x аргуме нта s e nder,
кото р ы й сооб щает о том , како й перекл юч ател ь в ы з вал м етод . Первый раз­
дел , s w i t c h e s , и м еет и ндекс О . Этот ф акт м ы отм етил и в ко м м ентар и и ,
чтобы п озднее об этом не забыть. В зав и с и м о сти о т того, какой перекл юча­
тел ь был в ыбран, соответствующие элем енты у п равл е н и я будут поя вл яться
ил и исч езать.
Прежде чем вы пол н ить приложение, воспол ьзуемся несложны м трюком, что­
бы сделать его немного луч ше. В верси и iOS 7 ком пания Арр\е внедрила не­
скол ько новых парадигм графического пол ьзовател ьского интерфейса. Одна и1
н их - строка состояния в верхней части экрана в приложении для версии iOS
7 я вляется п розрач ной, так что содержан ие приложения просвечи вает сквозь
нее. В дан н ы й момент п и ктограм ма Apress бросается в глаза на фоне белого
фона, поэтому желател ьно окрасить желтым цветом все приложение. Выберите
ГЛАВА 4 � Н О В Ы Е У П РАЖ Н Е Н И Я С И Н ТЕРФЕЙСОМ
1 59
в файле Ma i n . s t o ryboard главное представление содержи мого и нажм ите кла­
виши <Option+31:+4>, чтобы открыть инспектор атрибутов. Щелкните на пункте
для выбора цвета с меткой Background (который в дан ный момент содержит бе­
лый прямоугол ьник,) чтобы открыть стандартный селектор цветов OS Х . Одна
из функциональных возможностей этого селектора цветов заключается в том, что
он позволяет выбрать любой цвет, которы й вы видите на экране. Откры в селек­
тор цветов, щел кн ите на графическом представлен ии Apress в раскадровке. Затем
щел кните на пиктограмме с изображением лул ы в левом верхнем углу селектора
цветов и снова на графическом представлении Apress. В верхней части селекто­
ра цветов сразу лосле увеличител ьного стекла должен появиться цвет фона для
изображения Apress. Для того чтобы сделать его основным цветом фона в глав­
ном представлении содержимого, выберите главное представление в окне Docu­
ment Outline, а затем щел кните на желтом цвете в селекторе цветов. Закройте
селектор цветов.
Цвета фона и изображения Apress могут немного отличаться, но на симулято­
ре ил и на устройстве они будут совладать. Эти цвета могут не совладать в про­
грам ме l nterface B u i lder из-за того, что система OS Х автоматически адаптирует
цвета к дисплею, который вы испол ьзуете. На устройстве iOS и в си муляторе
этого не происходит.
Запустите приложен ие, и увидите, что желтый цвет заполн яет весь экран, так
что строка состоя ния и содержимое приложения в изуал ьно разл ичить невозмож­
но. Есл и содержимое приложения не требует прокрутки на экране ил и дру гое
содержимое предусматри вает н ал и ч ие панел и навигаци и ил и других элемен­
тов управления в верхней части экрана, этот способ может оказаться удобным.
Он позволяет демонстрировать пол ноэкран ное содержимое без перекрытия со
строкой состоя ния.
Есл и вы все сделали правил ьно, то сможете перекл ючаться между кнопками
и парами переключателей, испол ьзуя сегментированн ы й элемент управления, а
есл и вы нажмете какой-нибудь переключател ь, то второй перекл ючател ь также
изменит свое значение. Однако кноп ка ло-лрежнему ничего не делает. П режде
чем реализовать ее, поговорим нем ного о списках действи й и сигналах.
Р еали з а ци я с п иска де йстви й и с и гн ала
Сп иски действий (action sheets) и п редуп режден ия (alerts) обеспеч и вают
обратную связь с пол ьзователем .
'
"' С п иски действий испол ьзуются для того, чтобы застав ить пол ьзователя
выбрать один из двух ил и более вариантов. С п исок действи й поя вляется в
нижней части экрана и предлагает пол ьзователю выбрать одну из несколь­
ких кнопок (см . рис . 4 . 3 ) . Пол ьзовател ь не может продолжать испол ьзо­
вать приложен ие, лока не нажмет одну из кнопок. С п иски действи й часто
испол ьзуются для подтвержден ия потенциал ьно опасных ил и необрати­
мых действий, таких как удаление объекта.
1 60
'�
ГЛАВА 4 IJ\I Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
П редуп режде н и я поя вл я ются в с инем прямоу гол ь н и ке с закругленны­
м и углами, расположенном в центре э крана (см. рис. 4.4). Как и сп иски
действи й , п редупрежден и я в ы нуждают пол ьзователя ответить на вопрос,
п режде чем продолжить работу. Предуп режден и я обычно испол ьзуются
для и нформ и ровани я пол ьзователя о чем-то важном или неожиданном и, в
отличие от сп иска действий, могут п редлагать пол ьзователю нажат!:\ толь­
ко одну кнопку, хотя, есл и необходимо предоставить выбор, могут содер­
жать несколько кнопок.
ЗАМЕЧАНИЕ. П редставление, вынуждающее пользователя сделать выбор , п режде чем
п родолжить работу, называется модальным ( modal view ) .
Демонстрация списка действи й
Перейдем к файлу Vi ewCont ro l l e r . swi ft и реализуем метод, вы полняю­
щий действие кноп ки. Приведем изменения, которые необходи мо внести в пус­
той метод onBut t o n P re s s e d ( ) , созданн ы й п рограм мой Xcode автоматически
(л истин г 4.7).
Л и ст и н г 4 . 7 . Д е монстрация списка де йствий
@ I BAct i oп f u п c oпBu t t oп P r e s s e d ( _ s e пde r : U I Bu t t o п ) {
l e t coпt rol l e r
U I Al e r t C o n t r o l l e r ( t i t l e : " A r e You S u r e ? " ,
me s s a g e : п i l , p r e f e r r e d S t y l e : . a c t i o n S h e e t )
=
l e t y e s Ac t i o п
=
U I A l e r tAc t i o n ( t i t l e : " Ye s , I ' m s u r e ! " ,
s t y l e : . de s t r u c t i ve , h a п d l e r : { a c t i oп i п
l e t m s g = s e l f . n ame F i e l d . t e x t ! . i s Emp t y
? " Y o u с а п b r e a t h e e a s y , eve r y t h i n g w e п t ОК . "
: " Yo u с а п b r e a t h e e a s y , \ ( s e l f . пame F i e l d . t e x t )
+ " e ve r y t h i n g w e n t ОК . "
l e t c oп t r o l l e r 2
U I A l e r t C oп t r o l l e r (
t i t l e : " S ome t h i п g W a s Dопе " ,
me s s a g e : m s g , p r e f e r r e d S t y l e : . a l e r t )
l e t c a п c e l Ac t i oп
U I Al e r tAc t i o п ( t i t l e : " Phew ! " ,
s t y l e : . с а п се l , h a п d l e r : п i l )
c o n t r o l l e r 2 . a d dAc t i o n ( c a п c e lAct i o n )
s e l f . p r e s e п t ( c o n t r o l l e r 2 , a п im a t e d : t r u e ,
c omp l e t i o п : n i l )
=
=
} )
l e t п оАс t i о п = U I Al e r tAc t i o n ( t i t l e : " N o wa y ! " ,
s t y l e : . са п с е l , h a п dl e r : п i l )
c o n t r o l l e r . addA c t i o n ( ye sAct i o п )
c on t r o l l e r . addAc t i oп ( пoAc t i o п )
i f l e t ррс
c oп t r o l l e r . popove r P r e s e п t a t i o п C o п t r o l l e r
ppc . sourceView
s e пde r
p p c . s o u r ce R e c t = s e п de r . b o u п d s
=
=
,
"
ГЛАВА 4 1:с Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
161
p r e s e n t ( c o n t r o l l e r , a n i m a t e d : t r u e , comp l e t i o n : n i l )
Что именно м ы сделал и? В методе onBut t o n P re s s e d ( ) м ы в ыдел ил и па­
мять и и н и циал изировал и объект класса U IA l e r t C on t r o l l e r, который будет
представлять с п исок действий или сигнал.
let cont rol l e r
=
UIAlertControl l e r ( t i t le : "Are You S u re ? " ,
me s s a g e : n i l , p r e f e r r e d S t y l e : . a c t i o n S h e e t )
Первы й параметр - это загол о вок, кото р ы й будет в ы веден на э кран .
Взглян ите еще раз на рис. 4 . 3 , чтобы увидеть заголовок, который вы водится
над списком действи й . Следующий аргумент - это сообщен ие, которое вы­
водится под заголовком более мелким шрифтом . В этом п р и мере мы не ис­
пол ьзуем сообщение, п оэтому вместо него передаем параметр n i l . Послед­
ний параметр указы вает, хотим ли м ы , чтобы контроллер в ы водил на экран
с и гнал (значение UIAler tContro l l e r S tyle . alert) ил и список действи й
(UIAl e r tControl l e r S tyle . acti onShe e t) . Поскол ьку нам нужен с п исок
действий, м ы передаем параметр UIAlertControl lerS tyle . actionShee t.
Контроллер сигнала по умолчан и ю не и м еет н и каких кнопок - вы должн ы
самостоятельно создать объект класса U IAl e r tAc t i on для каждой кнопки, ко­
торую хотите добавить в контроллер. Н иже при водится часть кода, создающего
две кнопки для нашего списка действи й (л истин г 4 . 8 ) .
Л истинг 4 . 8 . Создани е кнопок для списка де йствий
l e t y e s Ac t i on
} )
U I Al e r tAc t i on ( t i t l e : " Ye s , I ' m s u r e ! " ,
s t y l e : . de s t r u c t i ve , h a n d l e r : { a c t i o n i n
1 1 Код про пуще н - см . ниже .
l e t noAc t i o n
=
=
U I A l e r tAc t i on ( t i t l e : " No wa y ! " ,
s t y l e : . cance l , handl e r : n i l )
Для каждой кноп ки необходимо задать заголовок, стиль и обработчи к, кото­
рый вызы вается при ее нажатии . Существуют три возможных стил я .
'1'
Стил ь UIAl e r tAct i o n S t y l e . de s t ru c t i v e должен испол ьзоваться , если
кноп ка я вляется триггером разруш ител ь ного, опас1юго ил и необратимого
' действия, напри мер удаления или перезап иси файла. Заголовок кнопки в
этом стиле прорисовы вается крас н ы м цветом и полужирн ы м шрифтом .
��!
Стил ь U I Al e r tAct i o n S t y l e . de f a u l t испол ьзуется для обы ч н ы х кно­
пок, таких как О К, когда действие не я вляется разрушитель н ы м . Заголовок
таких кнопок в ы водится на э кран с помощью обычного с и него шрифта.
1tt
Стиль U IAl e r t S t y l e . cance l испол ьзуется для кнопки Cancel . Ее заголо­
вок прорисовы вается полужирны м синим шрифтом .
1 62
ГЛАВА 4 аА Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
В заключение добавим в контроллер кнопки.
[ c on t r o l l e r a ddAc t i o n : y e s Ac t i o n ] ;
[ c ont r o l l e r a ddAc t i o n : n oAc t i o n ] ;
Дпя того чтобы сигнал ил и с писок действи й стал види м ы м , необходи мо поп­
росить текущи й контроллер представления предъя вить контроллер сигнала. Вот
как можно предъя вить список действи й (л истин г 4 .9).
1
Л истинг 4 . 9 . Пр едъявл е н и е списка де йствий
if let р р с
co n t r o l l e r . popove r P r e s e n t a t i on C o n t r o l l e r
p p c . s o u r c e V i e w = s e nd e r
ppc . s o u r c e R e c t = s e nde r . bounds
=
p r e s e n t V i ewCont r o l l e r ( c o n t r o l l e r , a n im a t e d : t r u e , comp l e t i o n : n i l )
Первые четы ре строки определяют, где поя вится с писок действ и й . В этих
строках мы получаем контроллер вспл ы вающего представления от контроллера
си гнал а и задаем с войства s o u r ceView и s ou r c e Re c t . Вскоре мы вернемся
к эти м свойствам . В закл ючение мы делаем представление види м ы м , вызывая
метод контроллера представления p r e s e n t ( _ : a n ima t e d : comp l e t ion : ) и пе­
редавая ему контроллер сигнала в качестве контроллера, который должен быть
п редъявлен. Если в роли предъя вляемого контроллера испол ьзуется контроллер
п редставлений, его представление временно заменяет текущее представление.
Есл и в рол и п редъявляемого контроллера в ыступает контроллер сигнала, то
список действи й ил и сигнал частично перекры вает текущее представлен ие; ос­
таток представления затеняется прозрачным
.......
фоном, сквозь который можно видеть ниже­
лежащее представлен ие, работать с которым
невозможно, пока вы не перекл юч ите конт­
роллер представлен и й .
Перейдем к настройке контроллера всплы­
вающего представления. На устройстве i Phone
список действий всегда вспл ывает снизу, как
показано на рис. 4.3, но на устройстве i Pad
о н и м еет в с п л ы в а ю щее о к н о (popover),
которое представляет собой небол ьшой за­
кругл е н н ы й п р я м оугол ь н и к со стрел кой,
указывающей на другое представление, став­
шее причиной его поя влен ия. С писок дейст­
вий в симуляторе i Pad показан на рис. 4 .29.
Как видите, стрел ка вспл ы вающего окна
показы вает на кнопку Do Someth i n g . Это
Рис . 4 . 29 . С п и с о к де й ств и й н а в ызвано тем , что м ы установили свойство
экране устройства i Pad A i r
s ou r ceView в контроллере вс пл ы вающего
ГЛАВА 4 l'!! Н О В Ы Е УП РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
1 63
окна так, чтобы стрел ка указывала на эту кноп ку, а с войство s ourceRect свя­
зано с контуром этой кнопки (л истин г 4 . 1 О).
Л исти нг 4 . 1 О . Задание свойств s ourceView и s ourceRect
i f l e t ррс
c o n t r o l l e r . popove r P r e s e n t a t i on C o n t r o l l e r
ppc . s o u r ce V i e w
s e n de r
ppc . s o u r c e R e c t
s e nde r . b o u n d s
=
=
=
Обратите в н имание на конструкцию if let
она необходима, потому что
на устройстве i Phone контроллер сигнала не п редъявляет список действий в виде
вспл ывающего окна, поэтому для свойства popove r P r e s e n t a t i onCont rol l e r
установлено значение n i l .
Н а рис. 4 . 2 9 вспл ы вающее окно поя вляется под кнопкой, которая его вы­
звала, но это можно измен ить, задав свойство контроллера представления
вспл ы вающего окна p e rmi t t e dAr rowD i re c t i o n s , которое я вляется маской
допусти мых направл е н и й для стрел к и . Следующий код перемещает вспл ы­
вающее окно над кнопкой с помощью присвоения этому с войству значен ия
U I Popove rAr rowDi re c t i on . down, как показано в л истин ге 4 . 1 1 .
-
Листинг 4 . 1 1 . Создание кнопок для списка действи й
if let ррс
c o n t r o l l e r . popove r P r e s e n t a t i on C o n t r o l l e r
ppc . s o u r c e V i e w
s e nd e r
ppc . s o u r c e R e c t
s e nde r . b o u n d s
ppc . pe rmi t t edAr rowDi r e c t i o n s = . down
=
=
=
Есл и вы сравн ите рис. 4.29 и 4.3, то увидите, что на экране устройства i Pad
нет кнопки No Way ! . Контроллер п редставления не испол ьзует на устройстве
i Pad кноп ки со стилем UIAl e r t S t yl e . cance l , потому что пол ьзовател и при­
выкл и убирать вспл ы вающее окно, касаяс ь экрана за пределам и этого окна.
В ывод предупреждения
Когда вы нажи маете кноп ку Yes, l ' m Sure ! , в ы хотите вы вести на экран сиг­
нал с сообщением. П ри нажатии кнопки, добавленной в контроллер си гнала,
список действий (или си гнал ) в ы кл ючаются, а его обработчи к вызы вается со
ссылкой на объект класса U IA l e rtAc t i on, из которого кнопка была создана
(листи.нг 4 . 1 2).
Листинг 4 . 1 2 . В ы вод на экран п редупреждения
let yesAc t i o n
U I Al e r tAc t i o n ( t i t l e : " Ye s , I ' m s u r e ! " ,
s t y l e : . de s t r u c t i ve , h a n d l e r : { a c t i o n i n
let msg
s e l f . name F i e l d . t e x t ! . i s Emp t y
? " Yo u c a n b r e a t h e e a s y , e ve r yt h i n g w e n t ОК . "
: " Yo u с а п b r e a t h e e a s y , \ ( s e l f . n ame F i e l d .
text ) , "
+ " eve r y t h i n g w e n t ОК . "
=
=
1 64
ГЛАВА 4 �� Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕ Й С О М
l e t coпtrol l e r 2 = UIAler tCoпt rol l e r (
t i t l e : " S ome t h i п g W a s Dоп е " ,
me s s a g e : ms g , p r e f e r r e d S t y l e : . a l e r t )
l e t c a п c e l Ac t i o п
U I Al e r tAct i o п ( t i t l e : " P h ew ! " ,
s t y l e : . с а п с е l , h a п dl e r : п i l )
c o п t r o l l e r 2 . a ddAc t i o п ( c a п c e lAct i o п )
s e l f . p r e s e п t ( c o п t r o l l e r 2 , a п i ma t e d : t r u e ,
comp l e t i o п : п i l )
=
) )
С н ачал а в блоке обработч и ка создается но вая строка, которая будет выво­
диться на экран . В реал ьном п риложе н и и здес ь можно предусмотреть кон­
кретные действия . Пока мы лишь и м итируем какие-то действия и уведомление
пол ьзователя с помощью сигнала. Есл и пол ьзовател ь введет имя в верхнем поле
редактирования, мы запомн и м его и будем испол ьзовать в сообщении, в проти в­
ном случае сгенерируем следующее сообщение:
l e t m s g = s e l f . п ame F i e l d . t e x t ! . i s Emp t y
? " Yo u с а п b r e a t h e e a s y , e ve r y t h i пg w e п t ОК . "
" You с а п b r e a t h e e a s y , \ ( s e l f . п ame F i e l d . t e x t ) , "
+ " eve r y t h i п g w e п t ОК . "
Следующие несколько строк вам должны быть знаком ы . Представления сиг­
нала и сп иска действия создаются и испол ьзуются аналогично. М ы всегда начи­
наем с создания объекта класса U IAlertCont ro l l e r :
l e t c o п t r o l l e r 2 = U I Al e r t Co п t r o l l e r (
t i t l e : " S ome t h i п g W a s Dопе " ,
me s s a g e : ms g , p r e f e r r e dS t y l e : . a l e r t )
Здесь м ы снова передаем заголовок сообщен ия. Но на этот раз передаем более
подробное сообщение, а именно - созданную нам и строку. Последний параметр
задает стил ь. В данном случае м ы в ыбрал и стил ь U IA l e r t Cont rol l e r S t yl e .
a l e rt, потому что хотим , чтобы на экран вы водился сигнал, а не сп исок дейс­
твий . Затем мы создаем объект класса U IA l e rtAc t i on для кнопки отмены сиг­
нала и добавляем его в контроллер:
l e t c a п c e l Ac t i o п
U I Al e r tAc t i oп ( t i t l e : " P h e w ! " ,
s t y l e : . сапсе l , haпdl e r : пi l )
coп t r o l l e r 2 . addAct i o п ( c a п c e lAct i o п )
=
В заключение в ыводим сигнал на экран с помощью контроллера представ­
ления сигнала:
s e l f . p r e s e п t ( co п t r o l l e r 2 , a п i ma t e d : t r u e , comp l e t i o п : п i l )
Созданн ы й сигнал показан на рис. 4.4. Легко видеть, что наш код не пытается
получить и настроить контроллер представления с и гнала в виде вспл ывающего
окна. Это объясняется тем, что сигналы поя вляются в маленьком закруглен ном
представлен и и в центре экрана устройства i Phone ил и i Pad .
ГЛАВА 4 ,, Н О В Ы Е У П РАЖ Н Е Н И Я С И НТЕРФЕЙСОМ
1 65
Сохраните файл Vi ewCont ro l l e r . swi f t, а затем соберите, запустите и про­
тестируйте завершенное приложение.
Р е з ю ме
Это была большая глава. Надеемся , что в ы не был и шокированы лавиной но­
вой информаци и, хотя мы испол ьзовал и бол ьшое кол и чество элементов управ­
ления и показали м н ожество деталей реал изации . Вы получ ил и бол ьшой опыт
работы с выходам и и действия м и и увидел и, как можно испол ьзовать иерархи­
ческую природу представлен и я . Вы узнали о состоя ниях элементов управления,
а также о сп исках действи й и предупреждениях.
В приложении Contro l Fun есть м ного и нтересного. Поработайте с ним. Из­
мен ите значения, поэкспери ментируйте с кодом, и увидите, какую рол ь играют
разные параметры в программе l nterface B u i lder. М ы не в состоя н и и п родемонс­
трировать все возможные варианты элементов управления в с истеме iOS, но зто
приложение представляет собой хорошую отправную точку и охваты вает м ного
базовых поняти й .
В следующей главе м ы расс мотрим, что происходит, когда пользовател ь вра­
щает устройство iOS, меняя его ориентацию с книжной на ал ьбомную, и наобо­
рот. Возможно, вам известно, что м ногие приложения меняют внеш н и й вид в
зависимости от ориентации устройства, и м ы покажем, как зто можно реал изо­
вать в своих приложениях.
ГЛ АВА 5
• •
В ра щ е н ие у с тр о й с тв а
Устройства i Phone и i Pad nредставля ют собой изумительные изобретения с
точ ки зрения внеш него вида, удобства исnол ьзования и фун к циональности . И н­
женеры ком nан ии Apple исумел и втиснуть максимум фун кционал ьн ы х возмож­
ностей в очень маленькую коробочку. Наnри мер, в этих устройствах существует
механ изм, nозволя ющи й исnол ьзовать их как в книжной (вытянутой в высоrу),
так и в ал ьбом ной (растя нутой в ш и р и ну) ориентаци и, а также изменять ори­
ентацию nри nовороте устройства. Проя вление этой фун кциональной возмож­
ности, которая назы вается а втомат и ч е с к и м поворотом (autorotation), можно
увидеть в веб-браузере систе м ы IOS Moblle Safari (рис. 5 . 1 ) В этой главе м ы
nодробно рассмотри м механизм автоматического nоворота, а затем nерейдем к
реал изаци и этой фун кциональной возможности в nриложениях.
До nоя вления системы iOS 8, есл и вы хотел и сnроектировать nриложение,
которое могло бы работать как на устройствах i Phones, так и на устройствах
i Pads, вы должн ы был и создать отдел ьную раскадров ку для устройств i Phones
и отдел ьную раскадровку для устройств i Pad. В системе IOS 8 все изменилось.
Ком nания добавила и нтерфейсы nрикладного nрограмм и рования в библиотеку
U I K it и инструменты в среду Xcode, благодаря чему стало возможно создавать
nриложения, которые могут работать на любых устройствах (ил и, исnол ьзуя
терм и нологию ком nан и и Apple, адаnтироваться к л юбому устройству), исnоль­
зуя тол ько одну раскадровку. В ы nо-nрежнему должн ы внимател ьно учиты вать
формфакторы разных устройств, но теnерь это можно делать в одном месте. Что
еще лучше, с nомощью функции Prev iew, оnисанной в главе 3 , можно немедлен­
но ув'идеть, как будет в ы глядеть ваше nриложение на экране л юбого устройства,
даже не заnуская симулятор. Адаnтив н ые макеты nриложений будут рассмотре­
ны во второй части этой главы .
.
1 68
ГЛАВА 5 .п В РАЩЕ Н И Е УСТРОЙСТВА
л р гсss
- ··· ·-
apress,com
··
�
�=
-о
.'
лpress
-···
, •• , " , 6 •""-"" ....с е- .... " . �
с:::ас:�
:
� ",
.... , . .
� . W., Dlwo6o�I
-- с
• f
�
::-:::::'
-� - " .........
... __ ....,.
· ·-
Z'CDl8.::!
Рис . 5 . 1 . Как и м н о г ие п р и л оже н и я дл я с и сте м ы IOS , б рауз е р M o Ь i l e Safa ri
и з м е н яет свое п редста вл е н и е в зав и с и м ости от того , как и м е н н о пол ьзова ­
тел ь держит устро й ство . Это п оз воляет макси м ал ьно и с п ол ьзовать доступное
п ростран ство н а экране
М ехан и зм а втомати ч еского поворо т а
Возможность работать как в книжной, так и в ал ьбом ной ориентаци и есть не
у всех п риложен и й . Некоторые приложения для устройства i Phone ( напри мер,
Weather) поддержи вают тол ько одну ориентацию. Однако это не относится к
устройству i Pad, для которого ком пания Apple рекомендует, чтобы практически
все приложен ия (за исключением и м мерсивных п р иложений, таких как и гры)
поддерживал и л юбую ориентацию. Бол ь ш и нство собствен н ы х приложен и й для
устройства i Pad, разработан н ых ком панией Apple, прекрасно работают в обоих
режи мах. М ногие И3 них испол ьзуют разные ориентаци и, для того чтобы про­
демонстрировать раз н ые п редставления ваш их дан ных. Напри мер, приложения
Mail и Notes испол ьзуют ал ьбомн ы й режим, чтобы показать с п исок объектов
(папок, сообщен и й ил и заметок) слева и выбра н н ы й объект - справа, а книж­
ная ориентация позволяет скон центрировать вни мание пол ьзователя на деталях
тол ько что выбранного объекта.
Для приложений i Phone можно сформул и ровать правило: автоматически й по­
ворот необходи мо реал изовы вать, если он расширяет во3можности пол ьзовате­
л я . Для приложе н и й iPad это правило звучит нескол ько и наче: автоматический
ГЛАВА 5 W' В РАЩЕ Н И Е УСТРО Й СТВА
1 69
поворот необходимо реал изовы вать, есл и у вас нет весом ы х п р и ч и н этого не
делать. К счастью, ком пания Apple п роделала огром ную работу, чтобы скрыть
сложные детал и автоматического поворота в системе iOS и в пакете U I K it, поэ­
тому реал изация этой фун кционал ьной возможности в ваших приложениях для
системы iOS я вляется довол ьно простой.
Автоматический поворот реализуется в контроллере представления. Если пол ь­
зовател ь поворачивает устройство, активный контроллер представления получает
запрос о том, готов л и он изменить ориентацию (как это сделать. в ы узнаете из
настоя щей главы). Есл и контроллер представления отвечает положительно, ори­
ентация окна и представления приложения, а также их размеры будут изменены.
В устройствах i Phone и i Pod touch представление начинает работу в кн иж­
ном режиме, в котором высота экрана бол ьше его ш и ри н ы . Реал ьные размеры
доступной области на экране разных устройств при веден ы в табл . \ . \ главы 1 .
Однако следует заметить, что есл и ваше приложе н ие и меет строку состояния
(status bar), то размер экрана, действител ьно досту пного для вашего приложе­
ния, может быть уменьшен на 20 точек по вертикал и . Строка состоя ния - это
полоска высотой 20 точек, расположенная в верхней части экрана (см. рис. 5 . 1 ) .
На нее вы водятся сила сигнала, время и заряд батареи .
Когда телефон перекл ючается в ал ьбом н ы й режим, представление поворачи­
вается вдол ь окна приложения и изменяет размеры, чтобы запол н ить все окно.
Например, на устройстве i Phone 6/6s экран и м еет размеры 3 7 5 х 667 точек в
книжном режи ме и 667 х 3 7 5 точек в ал ьбом ном . Как и прежде, размер экрана по
верти кал и, выделен н ы й для приложений, и меющих строку состоян ия (т.е. для
большинства приложений), уменьшается на 20 точек. В устройствах i Phone, ра­
ботающих под управлен ием систе м ы iOS 8, строка состояния в ал ьбомной ори­
ентации скры вается .
Точки , пиксели и дисплей Retina
У читателей может возни кнуть вопрос: п очему м ы говорим о точках, а не
пикселях? Ведь в п редыдущих изданиях книги мы измеряли размеры экрана в
пикселях, а не в точках. Причина закл ючается в том, что ком пания Apple разра­
ботала дисплей Retina (Retina display). Дисплей Retina (от англ . сетчатка. Примеч. ред. ) - это маркетин говы й терм и н компан и и Apple, которым она обоз­
начает экраны с высоким разрешением на устройствах i Phone 4 и более поздн их
версий. Разрешение этих экранов приведено в табл . 1 . 1 . В бол ьшинстве случаев
оно вдв ое бол ьше ап паратного, а на устройстве i Phone 6 P l us - втрое.
К счастью, в большинстве случаев нам ничего не надо делать, чтобы учесть
этот факт. Работая с визуал ь н ы м и элементами, мы задаем размеры и расстоя ния
между объектам и в точках, а не в п и кселях. Дл я старых устройств i Phone, i Pad 2
и i Pad M i n i 1 точ ки и п и ксел и экви валентн ы . Однако в современ н ы х моделях
i Phone и i Pod touch одна точка соответствует четырем п и ксел я м (два п и кселя
по горизонтал и и два по вертикали), а экран, например устройства i Phone 5 s,
1 70
ГЛАВА 5 !.<i В РАЩЕ Н И Е УСТРО Й СТВА
по-прежнему имеет ширину 320 точек, в то время как фактически он имеет
разрешение, равное 640 п и кселям по горизонтал и . На устройстве i Phone 6s ко­
эффициент масштабирования равен трем, так что каждая точка отображается в
квадрат 9 х 9 пикселей. Считайте это "виртуальным разрешением", которое сис­
тема iOS автоматически отображает в реальное физическое разрешение. Более
подробно мы поговорим об этом в главе 1 6.
В обычных прил ожениях перемещение п и кселей вы полняется системой IOS .
Основная задача вашего приложения - обеспеч ить точное согласование эле­
ментов и нтерфейса с размерами экрана.
Способы реализаци и автоматического вращения
Для обработки вращения устройства можно задать корректные ограничения
для всех объектов, образующих и нтерфейс. Огран ичения сообщают устройству,
работающему под управлением системы iOS, как должны фун кционировать эле­
менты управления, когда содержащее их представление изменяет размеры. Как
это связано с вращением устройства? Когда устройство вращается, размеры его
экрана меняются местам и, поэтому размеры окна п росмотра изменяются .
П роще всего испол ьзовать ограничения, настраивая и х в программе I nterface
B u i lder ( 1 8 ) . Она позволяет определять огран ичения, описы вающие изменение
положения и размеров ком понентов графического пол ьзовател ьского и нтерфей­
са при модификации родител ьского п редставления ил и перемеще н и и других
представлен и й , окружающих эти ком поненты . Мы уже касались этой тем ы в
главе 4, а в этой главе рассмотри м ее глубже. Ограничения можно считать неки­
ми математическим и уравнениями, описывающим и геометри ю представления,
а систему представлен и й в iOS - блоком решения этих уравнений, который
перестраи вает объекты так, чтобы эти уравнения вы полнялись.
Ограничения впервые поя вил ись в системе iOS 6, но в ком пьютерах Мае они
существовал и нам ного ран ьше. В системах IOS и maxOS ограничения можно ис­
пол ьзовать вместо старых "пружин и растяжек". Огран ичения позволяют делать
все, что делала старая технология, предоставляя м ного новых возможностей.
Выбор ориента ц и и п редс т а влени я
Создадим простое п риложение, демонстрирующее изменение ориентаци и .
Нач ните новый проект ти па Single View Application в среде Xcode и назовите его
Orienta t i o n s . Выберите в списке Devices пункт U niversal и сохран ите проект.
Прежде чем ском поновать графический пол ьзовател ьский и нтерфейс в рас­
кадровке, необходимо сообщить системе iOS, что наше п редставление поддер­
живает автоматический поворот. Существуют два способа сдел ать это. Можно
создать настройки приложения, которые будут задаваться по умол чанию для
всех контроллеров п редставлен и й , ил и уточ нять их для каждого отдел ьного
контроллера. М ы будем испол ьзовать оба подхода, нач и ная с общих настроек
контроллеров представлен и й .
ГЛАВА 5 r» В РАЩЕ Н И Е УСТРОЙСТВА
171
Поддержка ориентации на уровне приложения
Сначала м ы должны указать, какие в и д ы ориентаци и подцержи вает наше
приложен ие. Когда откроется п роектное окно Xcode, вы увидите настройки
своего проекта. Если нет, щел кните на верхней строке навигатора проекта (ко­
торая содержит и м я вашего проекта), а затем откройте в кл адку Geпera l . Сре­
ди параметров, доступных на вкладке Geпeral, есть раздел Deploymeпt l пfo, а в
нем - подраздел Device O rieпtatioп со списком флажков (рис. 5 .2) .
.., Deployment lnlo
Deployment Target
'".о
"
М.. in lnterface
мaln
•
Devices
Device Drlentation
Status 8ar
Style
Unlvornl
D Portralt
'
в
Upslda Down
S Landscape Lert
S Landscape Rlght
De!ault
-
в
Hlde statu1 bar
Requlres full screen
Рис. 5 . 2 . В кл адка Geпeral п о казы вает подде р ­
живае м ы е о р и е нтаци и дл я вашего проекта н а ­
ряду с остал ьн ы м и п а ра м етра м и
Таким образом, м ы указы ваем, какие в иды ориентации подцерживает ваше
приложение. Совершенно необязател ьно, чтобы каждое п редставление прило­
жения испол ьзовало все выбран ные виды ориентаци и . Однако, есл и вы собира­
етесь поддерживать какую-то ориентацию в каких-нибудь представлениях, вы­
берите ее на этой вкладке. Ориентация U pside Dowп по умолчанию откл ючена.
Это объясняется тем, что телефон обычно звон ит, когда пол ьзовател ь держит
его верти кал ьно, и, как правило, остается в этом положении во время разговора.
Откройте сп исок Devices, расположе н н ы й над флажкам и (рис. 5 . 3 ), и увиди­
те, как настроить разные варианты ориентаци и на устройствах i Phone и i Pad .
Есл и вы выберете пункт i Pad, то увидите, что по умол чани ю выбран ы все четы­
ре ориентаци и, поскол ьку планшет может испол ьзоваться в л юбом положен и и .
ЗАМЕЧАНИЕ. Четыре кнопки , показанные на р и с . 5 . 2 и 5 . 3 , означают добавление и уда ­
ление записей в файле I n f o . pl i s t . Есл и вы щелкнете на файле I n fo . p l i s t в окне
навигатора п роекта , то увидите два пун кта , Supported l пterface Orientatioпs и S u p­
ported l пterface O rieпtatioпs ( i Pad) , с подпунктами для выбранных видов ориента­
ци и . Выбирая и отменяя выбор этих кнопок на вкладке Geпera l , вы добавляете и уда­
ляете элементы из этого массива. Использование кнопок п роще и позволяет делать
меньше ошибок, поэтому мы настоятельно рекомендуем пользоваться и м и , полагая ,
что вы точно знаете их назначение.
1 72
ГЛАВА 5 !i В РАЩ Е Н И Е УСТРОЙСТВА
•
Deployment lnfo
Deployment Targe
Devic e
'
iPhone
@!!�!!!!!!!!!•
Main lnterface
Devlce Orlentatlon
IPad
•
Maln
D Portrait
., Upside Down
D Landscape Left
D Landscape Right
Status Ваг Style
в
Default
Рис . 5 . 3 . Настрой ка разн ых в идов о р и е нта ц и и дл я i P h o n e и i Pad
В качестве устройства мы снова выберем i Phone6s. Теперь выберите файл
Ma i n . s t o ryboa rd, найдите объект Label в библиотеке объектов и перетащите
его на свое приложен ие, отпустив п ря м о в центре, как показано на рис. 5 .4 . Вы·
берите текст метки и измен ите его на "Th i s way up". Изменение текста может
привести к сдвигу позиции метки, поэтому верн ите ее в центр экрана.
•
11
�his �ay U�
"
Рис . 5 . 4 . Н астро й ка м етки в книжной о р и е н т аци и
ГЛАВА 5 ·"'� В РАЩЕН И Е УСТР ОЙ СТВА
1 73
Необходимо добавить огран ичения Auto Layout, чтобы зафиксировать кнопку
до запуска приложения, поэтому нажм ите клавишу <Coпtrol> и перетаскивайте
указател ь вверх от метки, пока цвет фона внешнего представления не станет
голубы м , а затем отпустите кнопку м ы ш и . Нажав и удерживая клавишу <Sh i ft>,
выпол н ите команды Vertica l Spacing to Тор Layout G u ide и Center H orizon ta l ly in
Container из вспл ывающего меню, а затем н ажм ите клавишу <Retum>. Теперь
нажм ите клави ш и <X+R>, чтобы собрать и запустить это простое приложение.
Когда оно поя вится в симуляторе, попробуйте повернуть устройство несколько
раз, нажи мая клавиши <Х+�> ил и <Х+�> . В ы увидите, что все приложение
(вкл ючая добавленную метку) будет вращаться во всех направлениях, кроме на­
правления "сверху в н из", в соответствии с наш и м и настрой кам и . В ы пол н ите
приложение в си муляторе i Pad, чтобы убедиться , что оно вращается во всех
четырех направлениях.
Итак, м ы идентифи цировал и виды ориентации, поддержи ваемые наш и м при­
ложением, но это еще не все. М ы должны также у казать для каждого контрол­
лера представления, какие виды ориентаци и он поддержи вает. Эти виды ориен­
тации должн ы образовы вать подмножество видов ориентаци и, переч исленных
выше.
Н астройка поддержки поворота
Настроим наш контроллер представления так, чтобы он поддержи вал другой,
мен ьший набор допустимых вариантов ориентаци и . Отмети м, что глобал ьная
конфигурация для приложения задает нечто вроде абсолютного верхнего пре­
дела для допусти м ы х вариантов ориентаци и . Есл и глобал ьная конфигурация
не содержит ориентации "сверху вниз", напри мер, то н и у одного контроллера
представлен и й нет н и каких способов заставить систему повернуть экран в на­
правлении "сверху в н из". В контроллере представлений можно л и ш ь ужесто­
чить ограничения на допустим ые варианты ориентаци и .
Щелкн ите на файле ViewContro l l e r . swi f t в окне навигатора проекта. М ы
реал изуем метод, оп ределен н ы й в суперкл ассе U I Vi ewC o n t r o l l e r, который
позволяет нам указать допустимые варианты ориентации.
ove r r i de f u n c s upp o r t e d i n t e r f a c e O r i e n t a t i o n s ( ) - >
U I I n t e r f a c e O r i e n t a t i o nMa s k {
r e t u r n U I I n t e r f a c e O r i e n t a t i o nMa s k ( rawVa l u e :
( U I I n t e r f a c e O r i e n t a t i o nM a s k . p o r t r a i t . r a wVa l u e
1 U I I n t e r f a c e O r i e n t a t i o nM a s k . l a nds c a p e L e f t . r awVa l u e ) )
Этот метод позволяет вернуть объект класса U I I nt e r faceOri e nt a t i onMa s k
для допусти м ы х вариантов ориентаци и, как это делается в язы ке С . Вызы вая
этот метод, система запраши вает у контроллера представления, поддержи вает
ли он переход к кон кретной ориентации . В данном случае м ы возвращаем зна­
чение, которое означает поддержку двух видов ориентации : ал ьбом ная ориен­
тация по умолчанию и ориентация, полученная при повороте экрана на 900 по
1 74
ГЛАВА 5 !!! В РАЩ Е Н И Е УСТРОЙСТВА
часовой стрелке. Логическая операция OR (вертикал ьная черта) объединяет эти
два объекта класса U I I n t e r faceOr i e n t a t i onMa s k и возвращает комбиниро­
ванное значение.
Устройство, работающее под управлением системы IOS, может осуществлять
такую поддержку четырьмя способам и.
•
U I I n t e r faceOrienta t i o nMa s k . po r t r a i t . rawVa lue
•
U I I n t e r faceOr i e n t a t i o nMa s k . l a nds capeLe ft . rawVa lue
�
U I I nt e r fa ceOr i e n t a t i onMa s k . l ands capeRight . rawVa l ue
•
U I I n t e r faceOr i e n t a t i onMa s k . port r a i tUps ide Down . rawVa lue
Кроме того, существуют заранее задан ные комбинаци и общих вариантов ориентации . Они фун кционал ьно эквивалентны о пераци и OR и позволяют сэконо­
м ить время и сделать код более понятн ы м .
•
U I I n t e r faceOr i e n t a t i onMa s k . l ands cape . rawVa lue
•
U I I nt e r faceOr i e n t a t i onMa s k . a l l . rawVa lue
U I I nt e r faceOr i e n t a t i onMa s k . a l l ButUp s i de Down . rawVa lue
•
Когда устройство, работающее под управлением системы IOS, изменит про­
странствен ную ориентацию, из акти вного контроллера п редставления будет
вызван метод s uppo r t ed i n t e r faceOr i e n t a t i o n s ( ) . В зависимости от воз­
вращаемого значения, идентифицирующего новую ориентацию, приложение
реш ит, следует ли повернуть э кран . Поскольку каждый подкласс контроллера
представления может по-разному реал изовать этот поворот, одн и приложения
могут поддерживать автоматически й поворот некоторых из своих представле­
ний, а другие нет. Запустите приложение снова и убедитесь, что теперь вы мо­
жете вращать свое устройство тол ь ко в двух видах ориентации, идентификаторы
которых возвращают метод supportedi n t e r f a ceOr ient a t i ons ( ) . Выражение
. rawVa l ue в кон це каждого идентификатора ориентации возвращает целое зна­
чение, соответствующее п роверяемой ориентаци и .
ЗАМЕЧАНИЕ. В ы можете вращать устройство , но само п редставление вращаться н е бу­
дет, так что кнопка всегда будет возвращаться в верхнюю часть экрана за искл ючен и ­
ем двух видов ориентаци и .
ТЕХНОЛОГИЯ АВТОДОПОЛНЕНИЯ В ДЕЙСТВИИ
Вы заметил и , что н екоторые системные константы в устройстве iPhone всег­
да начинаются с одних и тех же букв? Одна из п р ич и н , по которым имена
U l l nterfaceOrientationMask.portrait, U l lnterfaceOrientation Mask.portraitUpsideDown ,
U l lnterfaceOrientation Mask.landscapeleft U l l nterfaceOrientationMask. landscapeRight
начинаются с префикса U l l nterfaceOrientation Mask, заключается в желани и ис­
пользовать технологию автодополнен и я , реал изованную в среде Xcode.
ГЛАВА 5 � В РАЩЕ Н И Е УСТРОЙ СТВА
1 75
Возможно , вы заметил и , что , когда вы набираете символы на клавиатуре, среда
Xcode часто пытается дополн ить слово , которое вы печатаете . Это - технология
автодополнения кода (code completion ) в действии.
Разработчики часто не могут запомнить все константы , определенные в системе,
но могут запом н ить имена груп п , которым они принадлежат. Когда нужно ука ­
зать ориентаци ю , просто введите слово U I I n t e r faceOr i e n t a t i onMa s k ( ил и
даже U I I n t e r f ) , а затем нажмите клавишу < Esc > , чтобы увидеть список имен ,
начинающихся с этих букв. ( В настройках среды Xcode можно вместо клавиши
< Esc > для открытия этого списка выбрать другую . ) Для п росмотра списка можно
испол ьзовать клавиши навигаци и , а выбор осуществл яется нажатием клавиши
<ТаЬ> или < Return > . Этот способ намного быстрее просмотра значений в доку­
ментации ил и заголовочных файлах.
Этот метод может возвращать л юбую маску для ориентации устройства.
Вы можете заставить систему ограни ч ить ваше представление тол ько тем и ви­
дами ориентаци и, которые и меют см ысл для вашего приложения, но не забы­
вайте о глобал ьной конфигураци и ! Пом н ите, что есл и вы, например, отключ ил и
ориентаци ю "с верху вн из" в глобал ьной конфигураци и, то н и одно из ваш их
представлений не будет ориентировано так, независимо от того, как объя влен
метод s uppo r t e d i n t e r faceOr i e n t a t i o n s ( ) в контроллере представления .
ЗАМЕЧАНИЕ. На самом деле система IOS разл ичает два типа ориентаци и . Одна из них
рассмотрена выше и назы вается ориентацией интерфейса ( inte rface orientation ) ,
а другая назы вается ориентацией устройства ( device orientation ) . Ориентация ус ­
тройства определяет то , как пол ьзовател ь держит устройство в дан н ы й момент. Ори­
ентация интерфейса оп ределяет способ п рорисовки экрана при его враще н и и . Есл и
вы держите ста ндартное устройство iPhone вертикально, то его ориентация будет
вертикальной , но ориентация интерфейса может быть л юбой из трех остальных воз­
можн ых, поскол ьку приложения для iPhone обычно не поддерживают вертикал ьную
ориентацию по умолчан и ю .
С ОЗДА Н И Е МАК Е ТА П РОЕ КТА
Находясь в среде Xcode, создайте другой новы й п роект по шаблону S i ngle
View Appl ication и назовите его Layout . Щел кните на файле Ma i n . s t o ryboa rd,
чтобы открыть рас кадровку в програм ме I nterface B u i lder. Атрибуты автома­
тического изменения р азмеров и меют одно хорошее свойство - они требуют
очень мало кода. Нет необходимости указы вать, какую ориентацию м ы выбрал и,
как в коде контроллера представления, а осталь ная реал изация автоматического
изменения размеров может быть осуществлена непосредственно в програм ме
l nterface Builder.
Для того чтобы увидеть, как это работает, перетащите четыре метки из биб­
лиотеки на свое представление и разместите их так, как показано на рис. 5 . 5 .
1 76
ГЛАВА 5 ;''· В РАЩ Е Н И Е УСТРО Й СТВА
Испол ьзуя пунктирные голубые л и н и и разметки, выровняйте их по углам . В на­
шем примере мы испол ьзуем экзем пляры класса U I Labe l , чтобы продемонстри­
ровать ограничения макета графического пол ьзовател ьского интерфейса, но эти
же правила относятся ко всем и нтерфейс н ы м объектам .
UL
"
UR
LL
LR
Рис . 5 . 5 . Доба вл е н и е четы рех м еток в раскадро вку
Дважды щелкн ите на каждой из меток и н азовите их так: U L
верхняя
левая (upper- left); U R
верхняя п равая (upper-right); LL
н ижняя левая ( \ower­
left button); LR
н ижняя п равая (lower-right button).
Теперь посмотрим, что п роизойдет, если мы не зададим н и одно ограничение
Auto Layout. Соберите и в ы пол н ите приложение на симуляторе i Phone 5s. Когда
с и мулятор iOS начнет работу, вы увидите л и ш ь м етки в левой части экрана, ос­
тал ьные метки, расположенные с права, оказы ваются за п ределам и экрана. Более
того, метка в левом н ижнем углу н и как не реагирует на действия пользователя .
В ы пол н ите команду H a rdwarec> Rotate Left, которая будет и м итировать перевод
устройства i Phone в ал ьбом н ы й режим , и вы увидите все метки (рис. 5 .6).
-
-
-
-
ГЛАВА 5 i1 В РАЩЕ Н И Е УСТРОЙ СТВА
)�".
"
1 77
iPed Alr - IOS 10.0 {\4Аб281u)
....
."�
"
Рис . 5 . 6 . И з м е н е н и е о р и е нтаци и без добавл е н и я огран и ч е н и й
Как види м , все не так уж хорошо. Верхняя левая метка после вращения
находится на правил ьной позиции, а остал ьные находятся на неправил ь н ы х
пози циях ил и вообще не видн ы . Дело в том, что кажд ы й объект и нтерфейса
соблюдает фиксированное расстоя ние от левого верхнего угла представления в
раскадровке. На самом деле м ы хотел и бы, чтобы каждая метка после враще­
ния была прикреплена к бл ижай шему углу. Метки на правой стороне должны
быть сдви нуты вправо. чтобы учесть новую ширину представления, а кнопки
в н ижней части должны быть подтя нуты вверх, чтобы соответствовать новой
высоте. К счастью, в п рограмме l nterface Bui lder это можно сделать с помощью
установки огран ичен и й .
Как указ ы валось ранее, програ м ма l nterface B u i lder может автоматически
создать набор огран ичен и й . Для этого она испол ьзует определен ные правила.
Для того чтобы применить их, сначала выберите все ч етыре метки . Для этого
щел кн ите на одной из меток, а затем , удержи вая клавишу <S h i ft> ил и <Х>,
щел кн ите на всех остал ьных метках по очереди. После этого выпол н ите коман­
ду Editori=> Resolve Auto Layout l ssues i=> Add M issing Constra i nts (существуют два
мен Ю с такой командой - в ы можете использовать л юбое из н их). Затем щел к­
н ите на кноп ке R u n , чтобы запустить приложение на симуляторе и п роверить
его работу.
ЗАМЕЧАНИЕ. Существует еще один простой способ выбрать все метки - нажать кла­
вишу <Shift> и щел кнуть на и м е нах меток в окне Document Outli n e , как показано на
рис. 5 . 7 .
ГЛАВА 5 i!! В РАЩЕ Н И Е УСТРО Й СТВА
1 78
•
11 Vlew Controller Scene
• Q V1ew Controller
t3 ТоР L•yout Guide
(] Вotlom Layout Gulde
•
П view
•
Е1
ф Fifst Responder
[!2 Exlt
-� StoryЬoard Entry Polnt
Рис . 5 . 7 . И с п ол ьз о ва н и е о к н а Doc u m e n t O u tl i n e ( л е ва я ч асть ка н в ы
Storyboard ) и н огда упрощает в ыдел е н и е и работу с не скол ьки м и объе к­
та м и пол ьзовател ьского и нтерфе й са одн о в р е м е н н о
Для того чтобы эффективно испол ьзовать огран ичения, необходимо хорошо
понимать, как они работают. Вернитесь в п рограм му Xcode и выберите левую
верхнюю метку, щел кнув на ней . Вы увидите пару сплош ных голубых линий,
присоединенных к этой метке. Одна из этих линий ведет к левому краю, дру­
гая - к верхнему. Эти голубые л и н и и отличаются от голубых пунктирных ли­
ний разметки, которые можно увидеть при перетаскиван и и объектов по экрану
(рис. 5 . 8).
Каждая из этих голуб ых л и н и й представляет собой огран и чение. Есл и на­
жать клави ш и <Option+34:+5>, то откроется и н с пектор размеров (size inspector),
и вы ув идите, что он содержит с п исок ограничен и й . На рис. 5 .9 показан ти­
п и ч н ы й набор ограничений, но огран ичения, создаваем ые п рограм мой Xcode,
зависят от кон кретного места, в котором находятся метки, поэтому они могут
отл ич аться .
ГЛАВА 5 m В РАЩ Е Н И Е УСТРОЙ СТВА
L1Ьel
Preferred
Vlew
1!11
-
....
Wl".Qc; ·cr�t.rj(:
Show
l lD
,� Expllclt
Fram� Recta�_gle
16 v
20
�
х
22
Width
у
�
v
нёight
21
Arrange --����n y 1ew _ ___ _
Layout Margins
+
+
-�e_!ault
1 79
_ _
в
v
v
JI
В
- Preserve Supervlew Margins
'"'"' Follow ReadaЫe Wldth
Conatralnt•
д11
Ll
••вwм
LR
Рис. 5 . 8 . Спл о ш н ы е голуб ы е л и н и и ,
Рис . 5 . 9 . Ч етыре огран и ч е н и я , ге ­
де м о н с т р и р у ю щ и е о г р а н и ч е н и я ,
задан н ы е дл я в ы б р а н н ого объе кта
н е р и руе м ы е п ро г ра м м о й Xc od e ,
дл я ф и ксаци и м етки н а родител ь с к о м п редставл е н и и
В данном случае позиция метки по отношению к родительскому представле­
нию задается двумя ограничен иям и : одно из них контролирует начальный про­
бел (l �ading space), который обычно означает расстоя ние до правого края метки,
а другое управляет верхним отступом (top space), т.е. пространством над меткой.
Эти ограничения вы нуждают кнопку занять равноудаленное положение по отно­
шению к верхнему и левому краям родительского представления при изменении
его размеров. Остал ьные два ограничения относятся к двум остальным меткам и
выравнивают их по отношению к остальным. Проверьте все метки, чтобы убедиться, что ограничения удерживают метки в углах их родительского представления .
1 80
ГЛАВА 5 tfi В РАЩЕ Н И Е УСТРОЙ СТВА
Обратите внимание на то, что в языках, в которых текст пи шется и читается
справа налево, начальный пробел расположен справа, поэтому дан ное ограниче­
ние может испортить графический пол ьзовател ьски й интерфейс при переклю­
чен и и на противоположное нап равление, например, есл и пол ьзовател ь выберет
арабский язы к на своем телефоне. Пока будем сч итать, что начальный пробел
означает "пробел слева'', потому что именно это огран ичение устанавл ивается
автоматически .
П ереопределение ограничений , заданных по умолчанию
Захватите в библ иотеке объектов новую метку и перетащите ее на макет.
На этот раз не перемещайте ее в угол, а приблизьте к левому краю представле­
ния, выровняв ее левы й край с остал ь н ы м и метками, расположе н н ы м и у левого
края, и размести в вертикал ьно по центру представления. Голубые линии размет­
ки помогут вам сделать это. Резул ьтат показан на рис. 5 . 1 О.
�L
-,
--7
•
11
-·
-
i
u�I
�
-е Ьеf -- - - -- - - - - - - - - - - -- - - - -- -- - - - - - - - - - - - - - - - · - - - - - -
!
i
_
!
!LL -------·-----L�
Рис. 5 . 1 0 . Раз м е ще н и е м етки Left
Добави м новое огран ичение, заставляющее кнопку сохранять централ ьное
положение по вертикал и . В ыберите метку и щел кн ите на п и ктограмме A l i g n ,
расположен ной под раскадровко й . Выберите во вспл ы вающем меню ком анду
Vertical Center in Contai ner, а затем щел кните на кнопке Add 1 Constra i nt. Открой­
те и нспектор размеров, нажав клавиши <Option+X+5>, и вы увидите, что теперь
метка имеет ограничение, фиксирующее ее в центре по вертикали родител ьского
ГЛАВА 5 "" В РАЩЕ Н И Е УСТРОЙСТВА
1 81
представлен ия. Кроме того, метке нужно еще одно ограничение, фиксирующее
ее по горизонтал и . Выберите кнопку и выпол н ите ком анду Editorq Resolve Auto
Layout l ssuesq Add M issing Constrai nts из раздела All Views во вспл ы вающем
меню. Нажм ите клав и ш и <X+R> и снова запустите приложение, выпол н ите не­
скол ько поворотов и убедитесь, что кнопки зан имают ожидаемые позици и .
Теперь запол н и м наше кольцо меток, добавив новую метку в правую часть
представления, выровняв по правому краю и вертикал ьно по метке Left. П рисво­
им новой кнопке имя Right. В ыбрав кнопку, выровняйте ее по вертикал и отно­
сительно остал ьных меток с помощью м ы ш и . Мы хотим испол ьзовать автомати­
ческие огран ичения, созданные програм мой Xcode, поэтому вы пол н ите команду
Editorq Resolve Auto Layout l ssuesqдdd Missing Constraints.
Еще раз соберите и запустите приложен ие, в ыпол н ите нескол ько поворотов,
и увидите, что все кнопки находятся на с воих местах по отношению одна к
другой (рис. 5 . 1 1 ). Есл и вы повернете экран обратно, они должн ы вернуться в
исходное положение. Этот метод прекрасно работает во м ногих приложениях.
1
UL
IPhone 5
-
iOS 10.О (14A5261u)
1
•
--------�
UR
Left
Right
LL
LR
Рис . 5. 1 1 . К н о п к и в н о в ы х поз и циях после пово рота
К нопки , занимающие всю ширину представления
Создадим нескол ько огран ичен ий, гарантирующих, что кнопки будут и меть
одинщ<овую ширину и будут растя нуты на всю ширину представления даже пос­
ле поворота устройства (рис. 5 . 1 2).
Нам необходимо визуал ьно определ ить, дости гл и л и м ы желаемого резул ь­
тата и находится ли каждая метка точ но в центре своей половины экрана. Дll я
того чтобы проверить это, временно измен и м цвет фона метки . Выберите в рас­
кадровке метки UL и U R , откройте и нспектор атрибутов и перейдите в раздел
View. Выберите какой-нибудь яркий цвет с помощью элемента управления Back­
ground. В резул ьтате контур каждой метки будет залит эти м цветом .
1 82
ГЛАВА 5 &!! В РАЩЕ Н И Е УСТРО Й СТВА
Рис . 5 . 1 2 . В е рхн и е кнопки растя нуты н а всю ш и ри н у экрана как в кн ижно й ,
так и в альбо м н о й о р и е нтаци и
Перетащите элемент управления, изменяющий размеры метки U L, с ее пра­
вого края, приблизив его к централ ьной точ ке этого представления по горизон­
тал и . По причи нам, которые будут разъяснены позднее, особая точ ность здесь
не нужна. Сделав это, измените размеры метки U R, перетаски вая ее левы й край
влево до тех пор, пока не появится перпенди куля рная л и н ия разметки, которая
обозначает рекомендован ное расстоя ние от метки до левого края родител ьского
представлен и я . Теперь м ы добави м огран ичение, благодаря которому эти мет­
ки будут запол нять всю ширину с воего родител ьского представления . Нажм ите
клавишу <Control>, щелкните на метке U L и перетащите указател ь на метку UR,
а затем отпустите кнопку м ы ш и . Во всплы вающем меню вы пол ните команду
Horizontal Spacing и н ажмите клавишу <Rerturn>. Это ограничен ие, соединяю­
щее левый край метки U R с прав ы м краем метки U L . Соберите и запустите
приложение, чтобы увидеть изменени я . Поверните устройство, и, возможно, вы
увидите нечто, похожее на рис. 5 . 1 3 . Более дл и н ная метка может оказаться слева
ил и справа в зависимости от конфигурации устройства.
Это почти то, что м ы хотели, но не совсем. Что же м ы сделали неправил ьно?
Мы определил и ограничения, регламентирующие положение меток относител ь­
но их родител ьского п редставления, и задал и расстоя ние между метками, но
ничего не сказали о размерах этих меток. Это позволяет системе макетирования
произвол ьно задавать размеры меток. Для того чтобы исправить эту ситуацию,
добавим новое ограничение.
ГЛАВА 5 11! В РАЩЕ Н И Е УСТРОЙСТВА
f':
Carrler •
UL UR
1 83
iPhone 5 - iOS 10.0 (14Аб• . .
-
Left
Right
LL
LR
Рис . 5 . 1 3 . М етки растя нуты по всей
ширине экрана не равномерно
Щел кн ите на метке U L, затем нажм ите клави шу <Sh ift> и щел кн ите на метке
вы можете создать огран ичение, которое будет вл и ять
на них обеих. Щел кн ите на пиктограмме Pin, расположенной под раскадровкой,
и установите флажок Equal Widths в появ ившемся всплы вающем меню (как мы
это делали в главе 3). Затем щелкните на кнопке Add 1 Constraint. В ы увидите
новое ограничение (рис. 5 . 1 4). Под меткам и поя вятся две оранжевые л и н и и . Это
означает, что позиции и размеры меток в раскадровке не соответствуют реал ь­
ным позициям и размерам меток во время выпол нения приложения. Для того
чтобы исправить этот недостаток, выпол ните команду Editorc:::> Resolve Auto Lay­
out l ssuesc:::> U pdate Frames в меню Xcode. Огран ичения должны стать голубыми,
а ра1 � еры меток изменятся автоматически и будут иметь оди наковую шири ну.
U R . Выбрав обе метки,
Рис . 5 . 1 4 . Теперь верхни е м етки и м еют оди наковую ш и рину
1 84
ГЛАВА 5 w; В РАЩЕ Н И Е УСТРОЙСТВА
Есл и запустить п риложение и повернуть устройство, то метки будут зани­
мать всю ширину экрана, как показано на рис. 5 . 1 2 .
В данном при мере все метки были види м ы м и и допускал и нескол ько вари­
антов ориентации, но бол ьшая часть экрана осталась неиспол ьзованной . Воз­
можно, было бы луч ше, есл и бы остальные два ряда меток тоже запол нял и всю
ширину экрана или метки изменял и высоту, чтобы запол н ить пустое пространс­
тво. Поэкспериментируйте с огран ичениями, накладываем ы м и на эти шесть ме­
ток, ил и добавьте новые м етки . Пом имо приемов, оп исан ных вы ше, вы можете
найти действия, создающие огран ичения во вспл ы вающих меню, которые по­
я вляются , когда вы щел каете на п и ктограм мах Pin и Align, расположенных под
рас кадровко й . Есл и какие-то огран и чения вам бол ьше не нужны, удал ите их,
выбрав их и нажав клавишу <Delete>, ил и поп ытайтесь настроить их в и нспек­
торе атрибутов. Поп робуйте разные варианты, пока не почу вствуете, что хорошо
ос воил и работу с огран ичен и я м и . Мы будем испол ьзовать их на протяжении
всей книги, но есл и вы хотите узнать бол ь ше, введите терм и н Auto Layout в
окне документации програм м ы Xcode.
Созд а ние ада пти вн ы х м а к е т о в
Макет, созданный в данном простом при мере, хорошо работает в кн ижной и
в ал ьбом ной ориентации как на устройствах i Phone, так и на устройствах iPad,
независимо от разл и ч и й в размерах экранов. Как уже указ ы валось, обработка
вращения устройства и создание и нтерфейса для устройств с разными размера­
м и экрана по существу - одна и та же задача. В конце концов, с точ ки зрения
приложения при вращении устройства размер экрана изменяется . В простейших
случаях эти задачи решаются с помощью огран ичений Auto Layout. Однако это
не всегда возможно. Некоторые макеты хорошо работают в книжной ориентации
и плохо в ал ьбом ной. Аналоги ч но некоторые приложения подходят для устройс­
тва i Phone, но не для i Pad. В таких случ аях приходится создавать для каждого
варианта отдел ь н ы й макет. До поя вления версии IOS 8 это означало реал изаци ю
всего макета в коде с помощью м ногих раскадровок ил и сочетания этих и нстру­
ментов. К счастью, ком пания Apple сделала возможной разработку адаптивных
приложений, которые одинаково хорошо работают в обоих видах ориентаци и на
основе всего одной раскадровки. Посмотри м , как работает этот механизм .
Создан ие приложения Restructure
Для де монстраци и возможностей создадим пол ьзовател ьс к и й и нтерфейс,
хорошо работающи й на устройстве i Phone в книжной ориентаци и и плохо в ал ьбом ной ил и н а устройстве i Pad . Затем покаже м , как с помощью про­
грам м ы l nterface B u i lder адапти ровать макет так, чтобы он работал в л юбой
орие нтаци и .
Создадим новый проект Single View и назовем его Re s t r u c t u r e . М ы со­
би раемся разработать графический пол ьзовател ьски й и нтерфейс, состоя щий
ГЛАВА 5 � В РАЩЕ Н И Е УС Т РО Й С Т ВА
1 85
из большой области содержимого и небол ьшого н абора кнопок, в ы полняющих
фиктивные действия. Размети м кнопки в н ижней части экрана, предоставив ос­
тал ьное место для области содержи мого (рис. 5 . 1 5 ) .
.
.., , ,
::- t ...
�.... , :!'.,
.:• • •
� .
�
,;_'
'" •'
'"
• •
i\L..f lOP Т /, О
,
.'
-"
: ·__
.
<
'
Action Four
Рис. 5 . 1 5 . И сходн ы й графический пол ьзо ­
вател ьск и й и нтерфейс в книжной ори е нта ­
ции на устройстве i Ph o n e
ЗАМЕЧАНИЕ. Возможно, вы заметил и , что некоторые устройства Apple , которые м ы ис­
пользуем в книге дл я иллюстраци и , и меют разные конфигурации . Одни иллюстрации
( например 5 . 1 5 ) бл иже к реал ьности , а другие ( например 5 . 1 1 ) кажутся более схе м а ­
тич н ы м и . Эта раз н и ца не должна с мущать читателей , поскольку о н а довол ьно часто
встречается в технической документаци и , включая документацию ком пании Apple.
Выберите файл M a i n . s to ryboard для редактирования графического пол ьзо­
вательского интерфейса. Поскол ьку представление содержимого для нас и нтере­
са не представляет, изобраз и м его в виде бол ьшого цветного прямоуголь н и ка.
Перетащите один объект класса U IView из библиотеки объектов в свое внеш нее
1 86
ГЛАВА 5 � В РАЩЕ Н И Е УСТРОЙСТВА
представление. Выдел ите представление и измените его размер, оставив небол ь­
ш ие поля сверху, справа и слева, как показано на рис. 5 . 1 5 . Теперь перейдите в
окно и нспектора атрибутов и с помощью раскры вающегося списка Background
выберите другой цвет фона. Вы можете в ыбрать любой цвет, кроме белого, что­
бы представление выдел ялось на белом фоне. В архивной раскадровке представ­
ление окрашено зеленым цветом, поэтому с этого момента мы будем назы вать
его зелены м .
Перетащите кнопку и з библиотеки объектов и поместите е е в левой н ижней
части пустого пространства под зелен ы м представлением . Дважды щелкните на
тексте этой метки и измените его на Action One. Н ажав клавишу <Option>, пере­
тащите три коп и и этой кнопки и поместите в виде двух столбцов, как показано
на рис. 5 . 1 5 . Не стоит стрем иться к их идеальному выравниванию, потому что
и х окончател ьные позиции м ы уточн и м с помощью огран ичен ий, но поп ытай­
тесь р азместить две гру п п ы кнопок на примерно оди наковых расстоя н иях от
соответствующих сторон внеш него представлен и я . Измените их заголовки на
Action Two, Action Three и Action Four. В заключение перетащите н ижний край
зеленого представления в н из, оставив небол ьшой просвет между ним и верхним
рядом кнопок. Для выравни вания испол ьзуйте голубые л и н и и разметки, пока­
занные на рис. 5 . 1 5 .
Перейдем к определению ограничений Auto Layout. Нач нем с выбора зелено­
го п редставления . Мы хотим прикрепить его к верхнему краю, а также к левому
и правому края м главного представлен и я . Это не пол н ы й набор огран ичен ий,
потому что м ы еще не определили высоту представления; м ы исправим этот не­
достаток, прикрепи в представление к верхнему ряду кнопок, зафи ксировав при
этом сами кноп ки. Щел кните на кнопке Pin в нижнем правом углу редактора
раскадровок. В верхней части раскрывающегося сп иска вы увидите знакомую
группу из четырех полей редактирования, окруженную небольшим квадратом.
Установите флажок Constrain to Margins. Щел кн ите на красных пун ктирных л и­
н ия х, расположенных сверху, слева и справа от маленького квадрата, чтобы со­
еди н ить представление с верхн им, левым и правым края м и родител ьского пред­
ставления (рис. 5 . 1 6). Щел кн ите на кнопке Add 3 Constraints.
Теперь зададим оди наковую высоту наш их кнопок, нач и ная с кнопки Action
One, как показано на рис. 5 . 1 7. Мы выбрал и высоту, равную 43 точ кам, просто
потому, что это значение уже было установлено, когда м ы приступили к созда­
нию кнопки. Для нашего примера подойдет любое значение, не сл ишком сильно
отличающееся от 43 . Задав высоту первой кнопки, повторите эти операции для
остальных трех кнопок.
Есл и все о перации в ыполнены правил ьно, все огран ичения должны быть
видны в окне Document Outline, как показано на рис. 5 . 1 8, где м ы видим огра­
ничения, задающие высоту всех четырех кнопок, а также трех сторон зеленого
п редставлен и я .
ГЛАВА 5 �. В РАЩЕ Н И Е УСТРОЙСТВА
------ -----.
а
_... u
,"
1r111н8C1kln a
а
-
!ЖkgrcNnd С
- ---
...-. а
n
а
(1
а
l.
1
1
у
• НОн о
1
Action Four
1!
Spaclng to nнre•1 nolghЬot
а Con1t1aln to m1rgin•
г1 11) wtdth
1!!1 "
1
!
з.сз
Г' liJI Нoltlhl
652
''"""'
'""' . "'"'
' :1 11J) - Ralio
111 "'.,,.
(��t.
Uodtt• •- c---""'
--- ,
!
Рис . 5 . 1 6 . Добавлен и е огран и ч е н и й для корректировки верх­
ней , левой и правой сторон зеленого п редставления
,lf-...
·I
-71
Add - Conttralnto
о
Spacl� to noarest NНghЬor
0 Conatr•ln to mмgint
172
1
1
43
,.. 11 fQtu,! W·d1·1�
r 11 �1 �.:gt-.,s
0 IJ Alpect Ratio
�
•
1111 All\j" � �·
lllt
.
(
•
�----�
Add 1 Con.U.ln1
)
Updt18 f'r-
Рис. 5 . 1 7 . Настройка вы соты одной из кнопок
1 87
1 88
ГЛАВА 5 w В РАЩЕ Н И Е УСТРОЙСТВА
11
.
1
1
1
1
11
1
1
r
У
8 Vie� Controller ;се�е
У О View Controller
о
!1З} Тор Layout Guide
[1] Bottom Layout Guide
У [d] View
{i] View
У [Ю Action One
У (!} Consttaints
(ilJ height 43
" [!!] Action Two
" (!) Constralnts
!Ш height 4 3
.
" [!] Action Throe
У (!) Constralnts
liil height 4 з
" оо Actlon Four
• @i) Constraints
1Ш height 4 з
У (!) Constraints
lliJ View.leading leadingM".
•
•
•
•
•
View.tra!llng • trailingMa".
11 View.top • Тор Layout G".
t'li First Rcsoonder
Рис. 5 . 1 8 . Добавл е н н ы е о г ра н и ч е н и я
отоб ражаются в окне Docu ment Outl i n e
Теперь прикреп ите левую нижнюю (Action Two) и правую н ижнюю (Action
Four) кнопки к нижн и м углам , нажав клавишу <Control> и перетащив каждую
из них в левый и правый угол соответственно. Для перемещения кнопки Action
Two нажм ите клавишу <Sh ift> и выберите два соответствующих пун кта, как по­
казано на рис. 5 . 1 9 .
Рис . 5 . 1 9 . П е р етас к и в а н и е к н о п к и Action Two и ее п р и кр е пл е н и е к
л е в о м у н иж н е м у углу конте й н е ра п р и нажатой кла в и ш е < Contro l >
ГЛ АВА 5 rJ: В РА ЩЕ Н И Е УСТРОЙ СТВА
1 89
Вы полните аналогич ную операцию, перетащив клавишу Action Four в правый
нижн ий угол 11 ри нажатой клавише <Control> и задав для нее ограничения, по­
казан н ые на рис. 5 .20.
Aetion Three
./
Tr a:t•ng Spacc 10 Contaiпвr Margin
.,; Vo r t 1cal Spac1ng to Bottom Layout Guide
----- ---------
Cen t•" Но• zo•1 1 ;i;1y о11 Cont ,1 1'11'Г
Centcr \'c · t .c .1 1 у .n C0t1l<Jmer
Рис . 5 . 20 . П е р етас к и в а н и е к н о п ки Action Fou r в п ра в ы й н и жн и й
угол в н е ш н е го п р едста вл е н и я
Затем нажм ите клавишу <Sh i ft>, выберите все четыре кнопки и задайте для
них оди наковую ширину (рис. 5 .2 1 ). Обратите вни мание на то, что сейчас кноп­
ки имеют разную ширину - от очень маленькой до очень большой. Для того
чтобы исправить этот недостаток, необходимо добавить допол н ительные огра­
ничения.
" '
Spacing to nearell neighЬot
0 Constraln to merglnt
(") !!) Wldth
о 161 Нolght
43
f'I 11 Equal Widttis
. (
. �
t
n 11 Equal Нolghtt
1 CJ (ii)
j (") 1!
i
As�ct Ratlo
Allgn
-=�:lJ
::::
-.---( Non
Upd.i• Fnmet -
1 (
l.eldl
Е
8
hld 3 Con•tralnta
:=:J
Рис. 5 . 2 1 . Настро й ка оди наковой ш и р и н ы всех к н о п о к , хотя кон крет­
ное значе н и е ш и р и н ы в раскадро в ке еще не зада н о
Нажм ите клавишу <Control> и перетащите кнопки Action One и Action Three,
образующие верхний ряд кнопок, влево и вправо соответственно, чтобы задать
ограничения Leading Space to Container Margin и Trailing Space to Container Margin
(рис. 5 .22). В резул ьтате левый край кнопки Action One и прав ы й край кнопки
Action Three будут привязан ы к края м п редставления с помощью одной из я кор­
ных точек.
1 90
ГЛАВА 5 lli В РАЩ Е Н И Е УСТРО Й СТВА
Рис. 5 . 2 2 . Н астр о й ка л е во го края к н о п к и Action One и правого
края кнопки Action Three по краям в н е ш н его представл е н и я
П оследние два ограничения, которые мы добавим, будут гарантировать, что
кнопки будут одинаковыми и зан и м ать половину ширины зеленого представле­
н и я . Нажм ите клавишу <Control>, перетащите у казател ь с кнопки Action Опе
на кнопку Action Three и задайте огран ичение H orizontal Spacing. Сделайте то
же самое для кнопок Action Two и Action Four, как показано на рис. 5 .23 . Дл я
этого перем естите я корь каждого края соответствующей к н о п к и на левый и
прав ы й края контей нера (см. рис. 5 .22). Как показано на рис. 5 .2 1 , все кнопки
имеют оди наковую ш ирину. Задав горизонтал ь н ы й отсту п так, чтобы все кноп­
ки были выровнен ы одна относител ьно другой, мы автоматически выровняем
ряд кнопок по центру представления . Поскол ьку зеленое п редставление также
прикреплено к левому и п равому края м, кнопки окажутся посредине зеленого
представлен ия .
Рис . 5 . 23 . Центровка каждого ряда кнопок
отн о с ител ь н о п редставл е н и я ; п о у м ол ч а ­
н и ю п р и это м ш и ри н а каждо й к н о п к и будет
равна полов и н е ш и р и н ы п редста вл е н и я
Еще нем ного, и мы будем готов ы п ротестировать наше приложение на раз­
ных устройствах. Н аж мите клавишу <Control> и перетащите указател ь с кла­
виши Action Three на клавишу Action Fou r, чтобы задать огран ичение Vertical
Spacing, как показано на рис. 5 .24. Сделайте то же самое для кнопок Action Опе
и Action Two.
ГЛАВА 5 1: В РАЩЕ Н И Е УСТРОЙС Т ВА
1 91
Рис . 5 . 24 . Устан овка в е ртикал ь н о го отступа м ежду к н о п ка м и ,
об разующи м и оди н стол бец
В закл ючение нажм ите клавишу <Contro\> и перетащите указатель от зелено­
го представления к кнопке Action One, чтобы зеленое представление и верхни й
ряд кнопок и мел и общую границу (рис. 5 .25).
: 1
J
1
Рис. 5.25. Уста н овка верти кал ьного отступа м ежду
зеле н ы м п редста вл е н и е м и верхн и м рядом кнопок
Теперь, какой бы пол н ы й экран i Phone ил и i Pad в книжной ил и ал ьбом ной
ориентаци и мы н и выбрал и , кнопки должны сохранять свои позиции, как пока­
зано на рис. 5 .26.
о
•
•
О v1ew as: iPhoм se (•с oRJ
cJ O
00000[
!fJ O о О 0 0 0 0 0 0
�
, ...,
.-
Рис. 5 . 2 6 . В ы б о р раз н ы х устройств в кн ижной о р и е н таци и ; к н о п к и дол ж н ы
сохран ять с в о и п о з и ц и и
1 92
ГЛАВА 5 ·""' В РАЩ Е Н И Е УСТРО Й СТВА
Обратите внимание на то, что в навигаторе проблем не осталось никаких сооб­
щений. Систематически добавляя необходимые ограничения, мы смогли создать
макет с минимальными усилиями. Однако не всегда это будет так просто.
Осталось собрать и выпол н ить приложение на симуляторе i Phone. На рис. 5 .27
показаны две ориентации устройства i Phone бs, а на рис. 5 .28 - две ориентации
полного экрана устройства i Pad A i r.
�WPi>�\ '( ' , . \ 'i
ч�����-���
,
f,(. ; ��l
;__
J\Ct1Qr1 l t\O
'J
Action Four
Рис . 5 . 27 . Две о р и е нтаци и устро й ства i Ph o n e бs
ГЛАВА 5 ;; В РАЩ Е Н И Е УСТРОЙ СТВА
1 93
Рис . 5 . 28 . Две о р и е нтаци и устройства iPad Air
Приложение в ы гл ядит неплохо, но мы соб и раемся сделать е ще кое- что.
На экране устройства i Plюne в ал ьбом ной ориентации с конфигурацией wc hC
кнопки должны выровняться в столбик у правого края, а на экране устройства
i Pad в л юбой ориентации с конфигурацией wR hR они должны выровняться в
ряд у н ижнего края .
ЗАМЕЧАНИЕ. w- h - обозначают ширину и высоту в рассматриваемой конфигураци и . В
механизме Auto Layout буква с используется дл я обозначения ком пактной конфигу­
раци и , а R
обычной . Таким образом , возникают варианты wc hC, wC hR, wR hC и wR
hR. Посмотрев на панель Device Coпfi g u ratioп , вы можете увидеть. как эти обозначе­
ния применяются к реал ьным физически м устройствам .
-
Н астройка конфигурации iPhone
в альбомной ориентации (wC hC )
Прежде чем задать ал ьбом ную конфигураци ю wC hC, сохран ите свою рабоrу
и закройте проект Xcode. Для того чтобы закрыть проект, достаточно просто
щел кнуть на красном кружке в левом верхнем углу окна Xcode. Выходить из
среды Xcode совсем необязател ьно.
Откройте окно Finder на ком пьютере М ае и найдите папку Re s t ruc t u r e .
Создайте е е архи в н ы й вариант, как показано на р и с . 5 .29. В резул ьтате будет
создана базовая версия проекта, к которой впоследстви и можно будет вернуться
в любое время, есл и что-то пойдет не так, как ожидалось.
1 94
ГЛАВА 5 � В РА ЩЕ Н И Е УСТРОЙ СТВА
f'\O�t.t \,t..., \ WJ O
• ch02
• сhОЗ
• ch04
о " М!
о
�
о "
New Folder
()pen fn New ТэЬ
Моvе to Trash
ch05
Get lnfo
Рис. 5 . 29 . Созда н и е архи в н о й ко п и и текущей версии проекта
Переименуйте архи вный ziр-файл в Re s t ructureBa s e l i ne, как показано на
рис. 5 . 30, чтобы он имел уникал ьное и м я . Таким образом , в архи вном файле
Re s t ructureBa s e l ine упакован проект, которы й работает на всех устройствах
и во всех видах ориентации одинаково.
сhОб
и
mv
Ov
c!J
0 " • Adapt1
О " ,.. Adapt 1 .ztp
О " 11 Layout
О " 11 Orlentatlons
11 Restructure
U HestrtJctureBasel1ne. 2 1p
О •
о
о "
о "
о "
"
Рис. 5 . 30 . П е р е и м е н о ван и е архи в н о й
ко п и и те куще й в е рс и и п роекта
Сначала измени м проект для ал ьбом ной ориентаци и i Phone. Выберите це­
левое устройство i Phone бs и ал ьбомную ориентацию. В правой части панел и
Device Config uration щелкн ите на кнопке Vагу for Traits и обратите вни мание на
то, что панел ь стала синей, как показано на рис. 5 .3 1 . Выберите во вспл ы ваю­
щем окне ширину и высоту. Как показано на рис. 5 .3 1 , на экран вы водится ин­
формация, которая относится только к устройству i Phone и тол ько в альбом ной
ориентации, поскольку мы собираемся разработать пользовател ьский интерфейс
именно для такой конфигурации.
Теперь щел кните на всех пяти элементах пользовательского интерфейса и на­
жм ите клавишу <Delete>. Этого не нужно бояться, потому что мы сохранил и ба­
зовую версию проекта, к которой всегда сможем вернуться . Есл и вы этого еще
не сделал и, то сделайте обязател ьно. После этого кан ва будет выглядеть так, как
показано на рис. 5 .3 2 . Однако, взглянув на окно Document Outline, можно уви­
деть, что в ней все еще отображаются элементы пол ьзовател ьского интерфейса
ГЛАВА 5 111 В РА ЩЕ Н И Е УСТР ОЙ СТВА
1 95
и даже огран и чен ия. Это объясняется тем , что они существуют в базовой кон­
фигураци и, а мы будем создавать новую конфигурацию и новы й набор характе­
ристи к для ал ьбомной ориентации wc hC.
.
"
.
Рис . 5 . 3 1 . Отп равная точка дл я созда н и я п ол ьзовател ьского и нтерфейса дл я
устройства i Ph o n e в альбо м н о й о р и е нтаци и
• 8 v_ с_....., &с•м
" � v.•" c ..- ..,
!f!l l'\lcl t.,..,1 �
J;J 1o1,- �8)'0ol'I G.n"
•С!""'
".
"
.\с1° ... о...
"
"
"
• 8 t\lf\ftr..,., ,
iilr.��· " •J
•
Atloeti fwt
!lc..,,1>".,.. 11
8 1'f8iO'!т • O
otr.al'<lf' Th<'N
• 8 C:O.!•rf>I•
......
. ,..-Q'\t
11i1:1 .... ,
;; . - .-
•3
• 8 с.ноv..-� �
8"Ч".t • 41
• 8 C-1•.;r1
8 ю_ f _.
......, 11i1:
·�� · Ac!\orl l
. /\GJ !Of' f- - · -­
. Aet_,_.oo\cllll • Ac�O.
1811•�-0" • il<:t- T
18 k'iorl T""M-IМd'r'Q • А.
1i.cr.e11or> riн. � · o1U
8 1м�:1� " """°"' '
· �IDl'I Т..0. 1t111 · 8.1.C1klfi T•wlfltl • .t.cllcl
8J v"" '� · �
liJ V18oo t18'1... • IAI JnoМI .
8 v... «111 - t<>11 � 0
",,.,toO" O... taci • V-ь
. ...'llOl'<O t-' � ­
D ecmo... t...,.,i � ""'"
. f'\tt'C """' '�e.<
ie r�'
Sto<�00-84 Ertrw llo..c
IJ
�
:�,.,
,, .�,,,.Р• 61 ("С r.J
,.,......,; , =,...-.l.J\... .....,_,,". �11··"!, I'(
.
.
.
•
'
11Л
f
.
•
'
.
•
-� -
�
�
. ·
.
" R) ' .,. 11
�·1: ··;r
''' i., ,..:· ;, ; <::;���
1'
·
Рис . 5 .32. Отп равная точка дл я созда н и я конфи гураци и устройства i P h o n e в
ал ьбом ной орие нтаци и . Об ратите в н и м а н и е на то , что в окне Document Outline
п о - п режн ему отображаются все эл е м енты п ол ьзовател ьского и нтерфе йса и
огран и ч е н и я , соответствующие базовой конф и гураци и
1 96
ГЛАВА 5 �• В РАЩЕ Н И Е УСТРОЙСТВА
Как и в базовой версии, перетащите на кан ву объект класса U I View и че­
тыре кнопки, задав их цвет и надписи. Поместите их в позици и , указанные на
рис. 5 . 3 3 , но пока не устанавл ивайте ограничен ия.
о
•
•
·--)
--
�г�����;: :.:!��·:�·., �/" �:
1]
Vrtv1 •ir 1Рhом !'! 1 {"С. • С \
..
��
75"'
.· :. >"�;:·:.: �..;.:�.: _;;: . . .:1";:;1�;;�yui�J:,;�..."
.. . . . .. .
·
� IUt 161
+
·
·�:.::·:".
··�
Рис. 5.33. П е рета щите э л е м енты пол ьзовател ьского и нте рфейса на рас­
кадро в ку и раз м е стите их п р и м е р н о та к , как показа н о н а р и сун ке
В этом разделе наши измерения должны быть немного более точными. Выбери­
те зеленое представление. Используя инспектор размеров, задайте размер 5ООх340
точек, как показано на рис. 5 .34. Ширина (500 точек) выбрана произвольно, а вы­
сота (340 точек) выбрана так, чтобы после деления на 4 получилось 85 . Именно
это значение мы выберем для высоты кнопок. Это не ограничение, а просто аспект
внешнего вида раскадровки. На самом деле мы не задаем для зеленого представ­
ления никакого фиксированного размера, поскол ьку он может изменяться в зави­
симости от устройства (для Plus в бол ьшую сторону, а для SE - в меньшую) .
......
rо
io
С1
о
•
111
sno.
Ananoe
f"rorтte Rectorgte
В
20 :
15 :
500 :
Wldth
340 :
н.Jg�•
PoeJtlon v о·н
.D
l
111111 1
о
Рис . 5 . 34 . Уста н о вка ра з м е ро в зел е н ого п р едставл е н и я
ГЛАВА 5 ·"' В РА ЩЕ Н И Е УСТРО Й СТВА
1 97
Выберите зеленое представление и при креп ите его к верхнему, левому и пра­
вому края м, как показано на рис. 5 .3 5 .
'
ас
с
r.I •
oc- ..:i
r
· •-<О •
I
•· ,
•
'"
'"
20
а CoN'ttain '° maro!fl•
(i1 WklU\
� 1111 "°"'"'
�
11
Action Four
а
1·
ООО
340
Е .;
- 111 - ""
· · �· "'"""'Ч ""•
�=- - Э)1
�
::::-!�
Г:::
.,,.,,,, "_МdГ
---
1
f
Рис. 5.35. П р и крепл е н и е зел е н о го п р едставл е н и я к верхн е м у, л е вому и п р а ­
в о м у к р а я м э к р а н а в ал ьбо м н о й о р и е нтац и и
Теперь м ы исправи м ш и р и ну кнопки Action One, но сделаем это немного
не так, как ран ьше. Нажмите клави шу <Control>, когда указатель находится на
кнопке Action One, и перетащите его из одной точ ки в другую, не выходя за
предел ы красной гран ицы, а затем отпустите кнопку м ы ш и . В ы увидите вспл ы­
вающее меню (рис. 5 . 3 6), в котором необходимо выбрать команду Width . Задайте
ширину кнопки Action One равной 1 20 точ кам, как показано на рис. 5 .3 7 .
Рис . 5.36. Настройка ш и р и н ы к н о п к и Action Button
Мы хотим, чтобы все четыре кнопки имел и оди наковую ширину и высоrу,
причем ширина должна быть равной 1 20 точкам, а высота должна настраиваться
динами чески в зависимости от верти кал ьных размеров доступной области на
экране i Phoпe в ал ьбом ной ориентации . Как и ранее, оди наковую высоrу кнопок
мы обеспеч им, размести в их столбиком. Щел кните на всех четы рех кноп ках,
удержи вая клавишу <Shi ft>, щел кн ите на п и ктограмме Pin, а затем задайте ог­
ран ичения Equal Width и Equal Heig hts (рис. 5 .3 8).
1 98
ГЛАВА 5 � В РА ЩЕ Н И Е УСТРОЙСТВА
8 View ControПer Sc:ene
�---- --�--�-------т
т
View Controller
!В1 Тор Layout Guide
(g} Вottom Layout Gulde
Y lrj} View
lt'J View
... в Ac:tion ом
Constralnta
(1 width • 120
00 Action Two
00 Action Three
ГВl Ac:tion Four
Рис . 5 . 3 7 . П ро в е р ка то г о , что ш и р и н а
к н о п к и Action Button равна 1 20 точ ка м
Shadow Offиt
n
Orawing П
1
Add н- Conatninta
ш:;.: :J
[j
о
7
Spacirщ to noмreat neigl\bor
а Constrain to marg!ns
Г' li) Wldth
Cl W1 Нeight
о
Action Four
о
а
о
о
1
120
вs
f'I Equel Widths
D IJ Equel Нelghta
0 {ii) Aspec:t Retio
0
Allgn
Leed!
1
�
Updete Fr- f.._None
_
_
_
_
_
_
_
�
�)
(���_J
��lvJ�d�8�C�on�s�ttaln���::;_��\.,.
>(
Рис . 5 . 38 . Уста н о в ка оди наковой в ысоты и ш и р и н ы всех кнопок
ЗАМЕЧАНИЕ. В о зм о жн о , вы заметил и , что , хо тя дл я каждо й из четы рех кн о п о к установ­
лены п о два о граничени я , на сам о м деле в п ро ект добавлен о шесть о граничений . Это
о бъясняется тем , что св о йства трех кн о п о к с о впадают с о св о йствам и четверто й .
Прикрепите кнопку Action One к верхнему и правому краям внешнего представ­
ления (рис. 5 . 39), а кнопку Action Four
к правому и н ижнему края м (рис. 5 .40).
-
ГЛАВА 5 "' В РАЩЕ Н И Е УСТРОЙСТВА
1 99
Sl\adow Olfиt ,
Add New Conatrelnt1
у
ОН .7
о
о
Spaclng to nearest neighlюt
D Conatrain to marg1n1
O i) w.dth
0 /W НelQht
Action Four
f!i EQtial Widll'tS
llJ Equ1 № ghts
о liil A8peCt Rallo
r
Г fJD Ai1Qf' ( leadlng �ges
Updete Framet 1 None
�)
Add 2 Constralnb
------....
"_____..,., Sc
Рис . 5 . 39 . П ри крепл е н и е кнопки Action One к верхн е м у и п равому краям
l
L
"
r
"'8\Jtl
88cl<Qr0Unel г
1
;
Shl<klw Offиt _
...11-.
··
Add - Conatr1lnt1
о
-- � о
Он 1
I
о
.
•J
S!>lcing to nнreat nelghЬo<
а Conttrain to marglna
0 IJ Width
о rm Нei;ht
r
(120
[ss
�·
:J
Eq""'I Widths
П liJ Equat Нe>gtrts
о 11 А11*1 "-tio
C 1iD A11fl!' f��.­
Update Fr- ( None
Рис. 5 . 40 . П р и крепле н и е к н о п к и Action Four к н ижнему и п равому краям
200
ГЛАВА 5 ;;, В РАЩЕ Н И Е УСТРОЙСТВА
Н ажм ите клавишу <Coпtrol>, перетащите кнопку Action Two вправо и вы­
берите огран ичение Trailing Space to Container Margin так, чтобы кнопка была
при креплена к п равому краю контейнера (рис. 5 .4 1 ). Повторите эту операци ю
для кнопки Action Three.
Рис. 5 . 4 1 . П р и кр е пл е н и е к н о п ки Action Two к п ра в о ­
м у краю конте й н ера с пом ощью п е ретаскиван и я и ко­
м а нды Trailing Space to Container Marg i n . О п е ра ци и дл я
к н о п к и Action Three в ы п ол н я ются а н ал о ги ч н о
Перетащите указатель с кноп ки Action One на кнопку Action Two, нажав кла­
вишу <Coпtrol>, чтобы установить ограничение Vertical Spacing (рис. 5 .42). По­
вторите эту операцию для установки п росвета между кнопкам и Action Two и
Action Three, а также Action Three и Action Four.
В закл ючение задайте ограничение Horizontal Spaci ng между зелен ы м пред­
ставлением и кнопкой Action One (впрочем , в этом случае можно испол ьзовать
любую из кнопок), как показано на рис. 5 .43 .
Щел кн ите на кнопке Done Varying н а панел и Device Configuration, чтобы за­
кончить добавление, размещение и настройку ограничени й для ал ьбом ной ори­
ентации i Phoпe, как показано на рис. 5 .44.
В каждой из трех конфигураций i Phoпe wc hC кнопки должны размещаться
так, как показано на рис. 5 .4 5 . Обратите внимание на то, что м ы выбрал и устрой­
ство i Phoпe 6/бs P lus, потому что оно имеет нашу базовую конфигурацию wc hC.
ГЛАВА 5 ·"" В РА ЩЕ Н И Е УСТРОЙСТВА
Рис. 5 . 4 2 . Н астр о й ка о г ра н и ч е н и я Vertical Spacing м ежду
каждо й парой кнопок в стол б це . В резул ьтате в ы сота каждой
кнопки станет равной одн ой вос ь м о й в ысоты конте й н е ра
Рис. 5 . 43 . Н астройка огра н и ч е н и я Horizontal Spacing
м ежду зел е н ы м п р едставл е н и е м и рядо м к н о п о к
Рис . 5 . 44 . Заве р ш е н и е н астроек с п о м о щью щел ч ка
на к н о п ке Done Varying на п а н ел и Device Configuration
201
202
ГЛАВА 5 fli. В РАЩЕ Н И Е УСТРОЙ СТВА
'1
.
I
' '
"
. .
-
о • •
-
�l _
+
]Ооооо о:!
-­
\
-
+
!
-)'
-
1
'
] 0 J "' Co О о
J_ ___
-·-
- - +
Рис . 5.45. И з м е н е н и е т и п а устро й ства на п а н ел и Device Confi g u ration пока­
з ы вает, ч т о м ы правильно настроил и огран и ч е н и я дл я альбо м н о й ориентаци и
устройств i P h o п e в ко н ф и гураци и wc hC
В ы полнение п риложе ни й на симул яторе при водит к резул ьтатам , показан­
н ы м на рис. 5 .46. Несмотря на то что по пром ы шлен н ы м стандартам края пред­
ставления следовало бы прижать ближе к краю контейнера, нашей цел ью было
продемонстрировать манипуляции элементами пол ьзовательского и нтерфейса на
разных устройствах с разной ориентацие й . Более глубоко освоив механ изм Auto
Layout, вы сможете точнее настраивать в неш н и й вид своих приложений.
П режде чем п ерейти к устройству i Pad, нам осталось лишь сохранить те­
кущую версию проекта, заархивировать ее и зап исать под у н икал ь н ы м име­
нем. Как показано на рис. 5 .47, дл я нового архива было испол ьзовано имя
Re s t r u c t u r e_wC hC . z i p , соответствующее ком п актной высоте и ш и р и н е .
В ы можете выбирать л юбое имя, главное, чтобы о н о содержало полезную и н ­
формацию о верси и проекта.
Н астройка конфигурации i Pad
(iPhone Plus в альбомной ориентации (wR hR))
В предыдущем разделе м ы рассмотрел и все этапы , которые необходимо вы­
пол н ить, чтобы создать базовый макет и специальные макеты для конкретной
конфигураци и . Для создания макета для устройства i Pad нам придется вы пол­
нить все эти этап ы заново.
ГЛАВА 5 � В РАЩЕ Н И Е УСТРОЙ СТВА
203
Рис . 5 . 46 . Есл и все сдел а н о п равил ь н о , то на экране л юбого i P h oпe
( за искл ю ч е н и е м 6/6s Plus) м а кет в альбо м н о й о р и е нтаци и должен в ы ­
гл ядеть соответствующи м образом
•
•
11 Adapt 1
.
.._ Adapt 1 .zlp
Layout
Orlentatlons
W Rest ructшe
_t Restructure8asellne.zlp
Restructure_wChC.zlp
о "
о
О •
о •
.,.
О
О
"
Рис . 5 . 47 . Сохра н е н и е те куще й версии п роекта
Для того чтобы сэконом ить место в книге, м ы свел и все этап ы в табл . 5 . 1 .
Таблица 5 . 1 . Настройки для всех видов ориентации
i Pad и альбомной ориентации iPhone 6/бs Plus
Этап
2
Действие
Рисун ок
Щелкнуть на кнопке Vary For Traits и внести изменения в зависи мости от ширины
5 . 48
Удал ить пять элементов п ользовательского интерфейса в рас­
кад ровке . Добавить назад пять новых элементов из библиотеки
объектов
5 .49
204
ГЛАВА 5 � В РАЩ Е Н И Е УСТРОЙСТВА
Окончание табл. 5. 1
Этап
Де йст ви е
3
В ыделить только что добавленное зеленое п редставление и , перейдя в инспектор размеров , задать его ширину и в ысоту равны м и 728 и 926 соответствен н о . Это не ограничения ; эти параметры
п росто помогают разместить элементы в раскадровке . (Замечание: эти параметры относятся к устройству i Phone 6s. На устройствах с други м и размерами высоту и ширину нужно изменить соот­
ветствующим образом . )
5 . 50
4
В ыберите кнопку Action Fo ur и задайте ее ш и р и ну равной 1 82 с
пом ощью инспектора размеров . Еще раз напоминаем , что это
значение относится к устройству i Phone 6s . Оно предназначено
только для визуализа ции элемента и не является ограничением
5.51
5
Убедитесь, что панель Device Configu ration остается синей . Это
свидетельствует о том , что м ы по-прежнему находимся в режиме
Vary for Traits. Настройте элементы и нтерфейса следующим образом : зеленое представление расположено вдоль верхнего края , а
кнопки образуют один ряд вдоль н ижнего края
5 . 52
6
Как в предьщущем разделе , прикрепите зеленое представление к
верхнему, левому и правому края м контейнера
5 . 53
7
Прикрепите кнопку Action One к левому нижнему углу контейнера
5 . 54
8
П рикрепите кнопку Action Four к п равому н ижнему углу контейнера
5 . 55
9
П рикрепите кнопку Action Two к нижнему краю контей нера
5 . 56
10
П ри крепите кнопку Action Three к нижнему краю контейнера
5 . 57
11
Добавьте ограничение на высоту кнопки Action One, которая должн а иметь фиксированное значение . М ы использовали высоту, равную 63 точка м , потому что она подходит для макета в нашей раскадровке . Это не еди нственная возможность; настройте высоту
кнопки по своему м акету
5 . 58
12
Н ажмите клавишу < Sh ift> и выберите все четыре кнопки , образующие ряд, задав их высоту и ширину одинаковыми
5.59
13
П еретащите указатель с зеленого представления на кнопку Action
One и задайте огран ичение Vertical Spacing . В результате зеленое
представление будет расположено над рядом кнопок
5.60
14
П еретащите указатель с кнопки Action One н а кнопку Action Two и
задайте ограничение Horizontal Spacing . Повторите эту опера цию
для кнопок Action Two и Action Th ree , а также для кнопок Action
Th ree и Action Four. В результате кнопки будут выровнен ы по краям
и будут занимать одну восьмую ширины контейнера
5.61
15
Щелкните на кнопке Done Varyin g , чтобы закончить изменение параметров
5 . 62
Рисунок
ГЛАВА 5 ·:,; В РА ЩЕН И Е УСТРО Й СТВА
205
! .
� :�·:;. :·,:.���: ._ d,�w•• :.: �:�·' ':,�.:;�,� ":,'�.· ','�·� :'•" \::·.:;:':.�":,;::.:- '·:�-::;:} ;,;�<((.•::�:���:!
J 1 � Ф'l iP.'fd fl 7' ("� · lfJ
•
:••
-
,'; •
'f
1
Ь()�
•
',
•,
Рис . 5 . 48. Выбер ите пункт i Pad , щел кн ите н а к н о п ке Vary For Traits и вы бе р ите
команду Width
Рис . 5 . 49 . Удал ите пять э л е м е нтов п ол ьзо вател ьского и нтерфе йса
ГЛАВА 5 'li В РАЩЕ Н И Е УСТРОЙСТВА
206
Show �F���-- ·
х
20" :1
728
wlclti\
у
:
28 :
928 :
Нelghl
�
а
Рис. 5 . 50 . Доба в ьте пять н о в ы х эле м е нтов и з б и б л и отеки объектов
и задайте и х в ы соту и ш и р и ну с п о м ощью и н сп е ктора раз м е ров . Это
н е огран и ч е н и я , а п росто параметры в изуал изаци и эл е м е нтов в рас­
кадровке
Vtew
Show ! Frame Rectangle
(�- -��вj1�1 �
х
·-
в
953 · :
--- - 1 -
у
[ wJdih1е 21'-:1 - Нelght
63
-
:
· �
Рис. 5 . 5 1 . Задайте ш и ри н у и высоту кнопки Action Four для работ ы
в раскадровке
ГЛАВА 5 "- В РАЩЕН И Е УСТР О Й СТВА
207
Рис . 5 . 52 . В ы ро в н я йте к н о п ки , пока п а н е л ь Device Configu ration остается с и ­
н е й , поз вол яя работать с кон кретн ы м набором парам етров
-
о
----- ---
-
- - -------
о
$
g
J.
11
-------�
g
1 r:=W':,
1
1
о'
10
� 11
а eon."*' 10 �·
Wldlh
728
· 11 - ..."
· ""'� t� td;tJ
828
- - "�
Г--- ARГ
c«iW�:--) J.:
11 €'--'•
r-·- < 1
"••.."._. , ......
Рис . 5 . 53 . П р и креп ите зеленое п редставл е н и е к ве рхн е м у, левому и правому
края м в н е ш н е го п р едставл е н и я
208
ГЛАВА 5 �� В РАЩ Е Н И Е УСТРО Й СТВА
Ad d H ew Contlnllnt•
· нО
I
о
о
8
•j
Speclng to neareat nelgl\Ьo<
а Constt•ln to mazvin•
0 Ё) Widlh
о !l1J Нelght
182
•
83
g fq J;jl W.dthl
1
t(\>j:tl Н.•g t
О f!ll Аарес1 Ra«o
� Ш1 AJ'1n �8'di
no Ed\J••
� Ff- ( None
:}
)
Add 2 С<!!'."!'.!!!!!.. _ __
1
Рис . 5 . 54 . П р и кр е п и те к н о п ку Action One к левому н и жнему
углу в н е ш н е го п р едставл е н и я
' Add н- Conatrainta
(§j
о
,8
CJ
С1
Action Four
D
о
о
4•
·1
·Он о
I
•i
Spac:lng to neareat neighЬor
а Constraln to margins
0 (i} Wldth
о fD) НO!ght
1 -
1 llJ
1
l 1a2
r63
Equal Width�
-
Ещюl Н igl\tS
!· О 1!!) Alpect Ratio
1i91"1 Leading Edoe•
1
•
=::])
Upd.tte Fntmes (N.o!l!.,_____
с-- Add 2 Constraints
�
__
_
_
_
_
__,
Рис . 5 . 5 5 . П р и кр е п ите к н о п ку Action Four к п равому н и ж н е му
углу в н е ш н е го п редставл е н и я
•
n.
ГЛАВА 5 �;; В РАЩ ЕН И Е УСТРОЙ СТВА
Рис . 5 . 56 . П р и к р е п ите к н о п ку Action Two к н иж н е м у
к р а ю в н е ш н е го п р едставл е н и я
Action Three
Action Four
Рис. 5 . 57 . П р и кр е п ите к н о п ку Action Th ree к н ижнему краю
в н е ш н его представле н и я
Add Н.W Conatralnt8
•
{ _]
1'
о
Spaclng to t1U1e1t м.ghЬOt
О Conttr8'" to rnиoin•
W ..ith
182
r 1111 '
rJ 111 Нo1gh1
83
IВ •·it<. 1 ,ч••r�:t
1 IJ �o:w Щ>QI' ·
, l!i) .u.,.et Я.1Jo
J
·
t.lpNtt F,tmN нОi\.е-
Рис. 5 . 58 . Добав ьте огра н и ч е н и е для установки в ы с о ­
ты кнопки Action One равной фиксирова н н о й вел и ч и н е .
М ы и с п ол ьзовал и в ы с оту, равную 63 точ кам , потому
что она хорошо п одходит дл я нашей раскадровки
209
210
ГЛАВА 5 � В РАЩЕ Н И Е УСТРОЙ СТВА
Adcll New Coмtnllnt•
.
-
!>
ActJon Four
о
1 •
11
о
ls*lf\9 10 ,.."" neigl'IЬOI
0 Conttrein ID rмr�s
··111 1 -h
' 1i11 н.�ом
• • •·"" -
....... .......
11 � 'lJlll �(·�
,., \
аз
•
·
�
"
r
['
-,, 1
-, �
--""' -� l1.!'li!'·- -·- ·--"-'
\lpda\· - l�- -== ----;) '
l 1 -_::--.... . .,_�-=- -
"
Рис. 5 . 59 . Н ажм ите кл а в и ш у < S h ift > и выдел ите все к н о п ки , образую щие ряд,
а зате м установите дл я них оди н а ковую в ы соту и ш и ри н у
Рис . 5 . 60. П е р етащите указатель с зел е н ого п ред­
ставл е н и я н а кн о п ку Action О пе и задайте огра н и ч е ­
н и е Vertical Spaci ng . В резул ьтате зел е н о е п р едста в ­
л е н и е будет расп ол оже н о н ад р я д о м кнопок
М ы надеемся, что вы разберетесь в сокращен ном описан ии испол ьзования
механизма Auto Layout. Есл и вам не понравится резул ьтат, можете удал ить про­
ект и вернуться к базовой версии. Пока вы не поработаете с механ измом Auto
Layout хотя бы десять раз, вы, скорее всего, будете делать ошибки. В этом вы не
ГЛАВА 5 :ю В РАЩ Е Н И Е УСТРОЙСТВА
21 1
одиноки . Есл и в работе со средой Xcode и особенно с механизмом Auto Layout
сделать переры в продолжител ьностью нескол ько недел ь, то, скорее всего, еди нс­
твен ным вариантом будет возврат к базовой версии и повторение пройден ного.
Рис. 5 . 6 1 . П е р етащите указател ь с к н о п к и Action One н а
кнопку Action Two, уде ржи вая кл а в и ш у < C o ntrol > и зада вая
огра н и ч е н и е Horizontal Spacing . П о втор ите эту о п е ра ц и ю
дл я к н о п о к Action Two и Act i o n T h re e , а также дл я к н о п о к
Acti o n Th re e и Action Fo u r
Р и с . 5 . 6 2 . Щел кн ите н а кнопке
Done Varyi n g ,
чтоб ы з ако н ч ить и з м е н е н и е параметров
Есл и вам все удалось, то выберите нескол ько разных вариантов устройства
iPad и видов конфигураций, чтобы убедиться, что приложение работает так, как
ожидается (рис. 5 .63).
21 2
ГЛАВА 5 �' В РАЩЕ Н И Е УСТРОЙСТВА
1 [] Vlew•1: � 8t lll\l1 l•l �C:J
0 О о о о о O r ::i
·- .
·-
Рис. 5 . 63 . П рове рка п р а в и л ь н о й о р и е нтаци и п р иложе н и я на канве раскад­
ровки
В заключение запустите си мулятор для разных устройств и убедитесь, что
вне ш н и й вид приложения остается правил ь н ы м . На рис. 5 .64 показано, как
должно в ы глядеть ваше приложение в книжной и ал ьбом ной ориентации на ус­
тройстве i Pad A i r.
--
_,...
Рис . 5 . 64 . П ро в е рка п ра в и л ь н о й работы п р ил оже н и я на с и м уляторе с
и с п ол ьзова н и е м раз н ы х устро й ств и видов о р и е нтаци и
ГЛАВА 5
В РАЩЕ Н И Е УСТРОЙСТВА
213
Р е зю ме
В дан ной гл аве оп исаны основы механ изма автоматического поворота, в
большой степени основанного на ограничениях Auto Layout среды Xcode 8 и
редакторе параметров на панел и Device Configuration. М ы начали с основ меха­
низма автоматического поворота и показал и, что п роизойдет, есл и ориентация
устройства Apple изменится . Наш перв ы й проект, O r i e n t a t i o n s , продемонс­
трировал основы обработки простых поворотов устройства и позицион ирования
меток. Во втором проекте, Layout, м ы уточ н ил и наши знания о позициониро­
ван ии меток, размещая метки по углам, а также у левого и правого краев при
повороте устройства.
В закл юч ител ьном проекте, Re s t r u c t u r e , мы углубились в детал и меха­
низма Auto Layout для создания с пецифи ческих конфигураци й, предназначен­
ных для конкретн ых устройств и видов ориентаци и . Поскол ьку механ изм Auto
Layout очень важен как для понимания остал ьной части кн иги, так для развития
вашей карьеры, постарайтесь разобраться в нем как можно лучше. С начала зто
будет трудно, но по мере приобретения о п ыта работать станет легче - пока
ком пания Apple в следующем году не в ыпустит его новую версию.
ГЛ АВА 6
•
П р ил о ж е н и я с н е с ко л ь к и м и
п ре дста в л е н и я м и
До сих пор м ы разрабатывали приложения с одн и м контроллером представ­
лени я. Несмотря на то что с еди нствен н ы м представлением можно сделать до­
вольно много, реал ьная мощь платформ ы iOS п роя вляется толь ко тогда, когда
вы можете перекл ючать п редставления в зависимости от данн ы х, введенных
пол ьзователем . Приложения с несколькими представлениями и меют нескол ько
стилей, но их основной механизм остается оди наковым независимо от того, как
это проя вляется на экране.
В этой главе мы сосредоточ и м в н и мание на структуре п риложения с не­
сколькими представлен и я м и и основах механ изма перекл ючения п редставле­
ний содержимого, разработав "с нуля" собственное п риложение с несколькими
представления м и . М ы нап и шем свой класс контроллера, который вы пол няет пе­
реключение. Это позвол ит оценить преимущества разнообразных контроллеров
нескол ьких представлений, поставляемых ком панией Арр\е.
Но прежде чем начать разработку приложения, рассмотрим, чем хороши при­
ложения с нескольки м и представления м и .
Осн о вн ы е т и п ы прил ожени й
с н е ск о льки ми п редставления ми
Ст-рога говоря , м ы уже работали с несколькими представлен и я м и в преды­
дущих приложениях, поскол ьку кнопки, метки и другие элементы управления
я влялись подклассам и класса U I View и могли быть отнесены к иерархии пред­
ставлен и й . Однако когда ком пания Apple испол ьзует терм и н п редставление
(view) в своей документации, он обычно означает л ибо класс U IVi ew, л ибо один
из его подклассов, который я вляется соответствующи м контроллером представ­
ления . Эти ти п ы представлений иногда назы вают п редставлен и я м и содержи­
мого (coпtent v iews) приложения .
21 6
ГЛАВА 6 '°" П РИЛОЖЕ Н И Я С Н ЕСКОЛ Ь К И М И П Р ЕДСТАВ Л Е Н И Я М И
Просте й ш и й пример приложения с нескол ьк им и представлениями
-
слу­
же б ное п р иложен и е (uti l ity appl icatio11). Бол ьшую часть работы оно выполняет
с единстве н н ы м п редставлением, но предлагает также второе представлен ие,
с помощью которого можно конфигурировать п редставление приложения ил и
предоставлять пол ьзовател ю бол ьше деталей, чем основное представление. При­
ложение Stocks, поставляемое вместе с устройством i Pho11e, - также хороший
при мер приложения с нескольки м и представления ми (рис. 6. 1 ). Есл и щел кнуть
на мален ькой п и ктограм ме i в правом нижнем углу, то п редставление конфигу­
раци и позвол ит вам задать сп исок цен н ы х бумаг, отслеживаемых этим прило­
жением.
Рис . 6 . 1 . П ри л оже н и е Stocks , поставл я е м о е с устро й ством i Phone ,
и м е ет два п редста вл е н и я : одно - дл я в ы в ода да н н ых , другое дл я конфи гури рова н и я с п и ска це н н ых бума г
Существует несколь ко п р ил оже н и й , и с п ользу ю щ и х п а н ел ь вкладок (tab
bar appl ications), которые поставл я ются вместе с устройством i Phone, напри­
мер п риложения Pho11e (рис. 6.2) и C lock . Приложение, испол ьзующее панел ь
вкладок, - это приложение с •�ескольки м и представлен и я м и, которое вы водит
ГЛАВА б 4'f П Р ИЛ О Ж Е Н И Я С Н ЕСКОЛ Ь К И М И П Р ЕДСТАВЛ Е Н И Я М И
21 7
в нижней части экрана ряд кнопок, н аз ы вае м ы х п а н ел ь ю в кладок (tab bar).
Нажатие одной из этих кнопок активизирует новый контроллер представления и
вы вод на экран нового представления. В приложении Phone, например, касание
вкладки Contacts вы водит на экран представлен ие, которое отличается от пред­
ставления, которое поя вляется после нажатия кнопки Keypad .
ф
1 (234) 667 -89 ®
С) ® ®
0®®
®®®
0®0
Рис. 6 . 2 . П р и л ож е н и е P h o n e
пример
п риложе н и я с н е с кол ьки м и п р едставл е н и ­
я м и , и с п ол ьзующе го п а н ел ь вкладок
-
Другой ш ироко расп ространенной разновидностью приложений для устрой­
ства i Phone с несколькими п редставлени я м и я вляются п риложения, обладаю­
щие свойствам и навигационного контроллера, испол ьзующего панел ь нави га­
ции (nav igation bar) для управления иерархией представле н и й . Ярким примером
является приложе н ие Settings (рис . 6 . 3 ) . П ервое представление в приложении
Settings показы вает пользователю ряд строк, в котором каждая строка соот­
ветствует кластеру настроек или кон кретному приложен ию. Касание одной из
этих строк вызывает новое п редставление, в котором можно задать кон кретны й
218
ГЛАВА б liO П РИЛОЖЕН И Я С Н ЕС КОЛ Ь К И М И П РЕДСТАВЛ Е Н И Я М И
набор настроек. Некоторые п редставления вы водят на экран с писок, позволя­
ющий пол ьзователю загля нуть глубже . Контроллер навигации следит за тем,
наскол ько в ы углубились в иерархию представлений, и позволяет вернуться к
предыдущему представлению.
""" Ylttzol\ LTE
( Sounds
16:81
Ringtone
VIЬration
Alert
RINGTONES
"' Openlng (Default)
Арех
Beacon
Bulletin
Ву Тhе Seaside
Chimes
Circuft
Consteffatlon
Cosmlc
Cryзtals
Рис. 6 . 3 . П р и л оже н и е i P h o n e Setti n g s я р к и й п р и м е р п риложе н и я с н ескольки м и
п р едста вл е н и я м и , и с п ол ьзующего п а н ел ь
н а в и га ции
Например, если в ы в ыбрал и настрой ку Sounds, то увидите представлен ие,
содержащее список настроек, связанных со зву ком. В верхней части этого пред­
ставления расположена п анел ь навигаци и, нажатие которой возвращает вас к
п редыдущему представлению. В настройках звука есть строка с меткой Ring­
tone. Коснитесь ее, и увидите новое п редставление, содержащее с писок мелодий
для телефона и п анел ь нави гаци и, позволяющую вернуться к главному пред­
ставлению Sounds (рис. 6.4). Приложение, испол ьзующее навигацию, полезно,
есл и вы хотите иметь иерархию представлен и й .
ГЛАВА б t!! П РИЛОЖЕ Н И Я С Н ЕСКОЛ ЬК И М И П Р ЕДСТАВЛ Е Н И Я М И
-•••Vlril;on LП
.__
P1•..:.v•_. ",_JJ
__
15"4
219
" . , _.
Q
RECIH TLY A O O f D )
Л. Л. Л.
EY8n ln The
О1.11еtм1 Momttt•t
fj
п
Jj
Jj
Crtt�? WMI Crtsh.?
/R�tllfedl
Comp!lat1ons
1·
' '1'1
Тhе Вез! Of Mendelssolm
Вrahms: Symphooles •з & 4
t'
, ,
C&rpenlero Gold Grealest Н11& (Dloc
21
V
""
A11o"r
Dvo/At<: Symphonies ID!oc 1 1
Рис . 6 . 4 . П риложе н и е M usic испол ьзует
и панель н а в и гаци и , и панель вкл адок
В устройстве i Pad бол ь ш и н ство п р иложе н и й , основан н ы х на навигаци и,
таких как Mail, реализо ваны с помощью разделе нного п редставлен и я (spl it
v iew), в котором элементы нав и гации находятся в левой части экрана, а эле­
менты, которые пол ьзователь выбирает для просмотра ил и редактирован ия, в правой . Более подробно о разделен н ы х представлениях и других элементах
графического пользовательского и нтерфейса, характерн ы х для устройства i Pad,
мы поговорим в главе 1 1 .
Поскол ьку представления сами по себе имеют иерархическую природу, мож­
но сочетать разные механизм ы перекл ючения п редставлений в рам ках одного
приложения . Например, приложение i Pod для устройства i Phone испол ьзует па­
нель вкладок для перекл ючени й между раз н ы м и способами организации аудио­
зап исей, а контроллер навигации и с вязанную с ней нав и гационную панел ь для прослу ш и вания аудиозаписей в соответствии со сделан н ы м выбором их
группировки . На рис. 6.4 панел ь вкладок расположена в н ижней части экрана, а
панель навигации - в верхне й .
220
ГЛАВА 6 lli П РИ Л ОЖЕН И Я С Н ЕСКОЛ Ь К И М И П Р ЕДСТАВ Л Е Н И Я М И
Некоторые nриложения исnользуют панель инструментов (tool bar), кото­
рую часто nутают с nанелью вкладок . Панел ь вкладок исnол ьзуется для выбора
только одного варианта из нескол ь ких, а nанел ь инструментов может содержать
кноп ки и другие элементы управления, которые не я вл я ются взаи моискл юча­
ющим и . Яркий пример панел и и нструментов можно увидеть в нижней части
главного представления браузера Safari (рис. 6 . 5 ). Есл и вы сравн ите nанель ин­
струментов в нижней части nредставления браузера Safari с nанелью вкладок
в н ижней части представлений nриложения Phone или i Pod, то легко их раз­
л и ч ите. Панел ь вкл адок разделена на четко обозначенные сегменты, а панель
инструментов, как правило, нет.
:::.-
=-
-�
::::.
--
�-
,... __
'''
--
/lillo; fol:11-
_...,
• 1''
1
1 1
1
1 111
.......
....,,...
:!!"�
tor!!""
,,.,..,
-
[!J
Zial8.:
•
-
-
�
· --
....
ф
r.I•""""
1
i=t
"'Jl!!il:",,...
......,. iw,-_
<!J
•
."""'1
Рис. 6 . 5 . В б рауз е ре M o b i l e Safa r i есть п а н е л ь
и н стру м е нтов в н иж н е й ч асти экран а . О н а п охо ­
жа на с вободную панел ь , позвол я ю щую в ы б и рать
н ескол ько эл е м е нтов у п р а вл е н и я одн о в р е м е н н о
П риложения с нескол ь ки м и nредставл е н и я м и , относя щиеся к каждому из
этих тиnов, исnол ьзуют особ ы й класс контроллера из nакета U I K it. Интерфейсы
ГЛАВА 6 ", П Р И Л ОЖ Е Н И Я С НЕС КОЛ ЬК И М И П Р ЕДСТАВЛ Е Н И Я М И
221
nанелей вкладок реал изован ы на основе класса U I T abBarCon t ro l l e r, а и нтер­
фейс nанелей навигации исnол ьзует класс U I Navi g a t i onCon t ro l l e r .
А рхитекту ра приложен и я с нескол ьки м и
предста влен и я м и
Приложение View Switcher, которое м ы собираемся разработать в этой главе,
выглядит очень nросто, но код, который мы nланируем наnисать, намного слож­
нее nредыдущих nрограм м . Приложение View Switcher будет состоять из трех
разных контроллеров, раскадровки и делегата nриложения.
При nервом заnуске nрограмма View Switcher будет выглядеть так, как nока­
зано на рис. 6.6, с nанел ью инструментов, содержащей одну кноnку. Остальная
часть nредставления будет состоять из голубого фона и кноnки, готовой для
нажатия .
Рис . б . б . П р и п е р в о м за пуске п р ил оже н и я
м ы увиди м голубое п р едставле н и е с кнопко й
и панел ь и н струм е нтов со с в о е й кн о п кой
222
ГЛАВА 6 1.11 П РИЛОЖЕ Н И Я С Н ЕСКОЛ Ь К И М И П Р ЕДСТАВ Л Е Н И Я М И
Когда пол ьзовател ь нажмет кнопку Switch Views, ф о н окрасится в желтый
цвет, а заголовок кнопки измен ится (рис. 6 . 7).
Если нажата кнопка Press Ме ил и P ress Ме, Тоо, на экране появится предуп­
режден ие, сообщающее, какая из кнопок была нажата (рис. 6. 8).
Cerrltt •
7:44 РМ
-
Press Ме, Тоо
Sw1tch Viows
Рис. 6 . 7 . К о гда п ол ьзо вател ь н а ­
Рис. 6 . 8 . Когда п ол ьзовател ь на­
ж и м ает к н о п ку Switch Views , голубое
ж и м ает кнопку Press Ме и л и Press
п р едставл е н и е з а м е н я ется желты м
М е , Тоо , на э к р а н е п о я в л я ется
п р едуп режде н и е
Несмотря на то что мы могл и бы п олучить тот же сам ы й эффект с помощью
приложения с еди нствен н ы м представлением, мы выбрал и более сложный путь,
чтобы продемонстрировать механизм приложения с нескол ьки ми представлени­
я м и . В этом простом приложении на самом деле скрыты три разных контролле­
ра представления : оди н управляет голубым представлением, второй - желты м,
а третий специал ь н ы й контроллер переключает эти представления, когда пол ь­
зовател ь нажимает кнопку Switch Views.
ГЛАВА 6 � П Р И Л ОЖ Е Н И Я С Н ЕС КОЛ ЬКИ М И П Р ЕДСТАВЛ Е Н И Я М И
223
Прежде чем приступить к разработке приложения, поговорим нем ного об ус­
тройстве приложений с нескол ьким и представления м и для устройства i Phone.
Большинство приложений с нескольки м и представлениям и устроено точно так же.
Корневой контроллер
В приложении с несколькими представлен и я м и ключевую рол ь и грает рас­
кадровка, содержащая все представления и контроллеры представлений нашего
приложения. М ы создадим раскадровку, содержащую экземпляр класса конт­
роллера, выбирающий п редставление, которое должно вы водиться на экран в
текущий момент. Назовем этот контроллер корневым (root contro l ler), по ассо­
циаци и с корнем дерева ил и "корнем всех бед", поскол ьку это первый контрол­
лер, которы й в идит пол ьзовател ь и которы й загружается в память при запус­
ке приложения. Этот корневой контроллер часто я вляется экземпляром класса
UINavi gat i onCon t r o l l e r ил и U I T abBarCont rol l e r, хотя и ногда может быть
наследником класса UIViewCon t ro l l e r .
В приложении с несколькими представлен и я м и работа корневого контрол­
лера сводится к тому, чтобы выбрать одно из двух или нескол ьких представле­
ний и вы вести его на экран в соответствующем виде в зависимости от дан ных,
введенных пользователем. Контроллер панел и вкладок, например, перекл ючает
разные представления и контроллеры представлений в зависимости от того, ка­
кой элемент панели вкладок пол ьзователь нажимал в последни й раз. Контроллер
навигаци и делает то же самое по мере перемещения пользователя по иерархии
представлен и й .
ЗАМ ЕЧАНИЕ. Корневой контроллер - это контроллер основного представлени я для
приложения , и в этой роли именно он определяет, можно ли выпол нить автоматичес­
кий поворот при изменении ориента ц ии . Однако корневой контроллер может переда ­
вать ответственность за такие решения текущему активному контроллеру.
В приложениях с нескольки м и представлениям и большую часть экрана зани­
мает представление содержи мого, причем каждое представление содержи мого
имеет собстве н н ы й контроллер со своим и выходам и и действ и я м и . Нап р имер,
в приложении с панел ью вкладок при нажатии панел и будет вызван контроллер
панели вкладок, а при нажатии любого другого м еста экрана - контроллер те­
кущего представления.
Устр ойство представления содержимого
В приложении с нескольки м и представлениями каждый контроллер представ­
ления управляет каким-то представлением содержимого, и эти п редставления
являются основой и нтерфейса. В совокупности они образуют с ц е н у (scene) в
раскадровке. Каждое представление содержи мого состоит из контроллера пред­
ставления и представления, содержимое которого может быть подклассом клас­
са U IView. Есл и тол ько вы не собираетесь делать нечто совершенно необы ч ное,
224
ГЛАВА 6 w; П Р И Л О Ж Е Н И Я С Н ЕСКОЛ Ь К И М И П Р ЕДСТАВ Л Е Н И Я М И
ваше п редставление содержимого будет всегда иметь соответствующий контрол­
лер представления и иногда подкласс класса U IV i e w . Хотя вы можете запрог­
рам м ировать и нтерфейс, не испол ьзуя n i Ь-файл, лишь некоторые люди выбира­
ют этот путь, потому что он более долгий и трудны й .
В этой главе м ы создадим новы й класс контроллера для каждого представле­
ния содержимого. Корневой контроллер нашего приложения управляет представ­
лением содержимого, которое состоит из панели инструментов, расположенной
в н ижней части экрана. Он загружает контроллер голубого представления, кото­
рый, в свою очередь, вы водит на экран это п редставление в качестве дочернего
представлен ия по отношен ию к п редставлению корневого контроллера. Когда
пользовател ь нажимает кноп ку, перекл ючающую представления и принадлежа­
щую корневому контроллеру (эта кнопка расположена на панели инструментов),
корневой контроллер отключает голубое п редставление и передает управление
контроллеру желтого п редставления, и н и ци и руя его по мере необходимости .
Итак, приступим к созданию проекта - и все станет нам ного яснее.
С о з да ние перекл ю ч а т е ля п редст а вле н ий
Для того чтобы создать наш п роект, откройте среду Xcode и вы полните ко­
манду F i l e c::::> N ew c::::> P roject . " ил и нажм ите комби нацию клавиш <Sh i ft+ 3€ +N> .
Когда откроется окно помощника, выберите п и ктограмму Single View Appl ication
и щел кните на кнопке Next . На следующей странице помощника введите в поле
Prod uct Name строку V i e w S w i t ch e r , установите значение Language равным
Swi f t и выберите пункт U n iversa l в списке Devices . Щел кн ите на кнопке Next.
В открывшемся окне найдите место, где хотите сохранить свой проект, и щелк­
ните на кнопке C reate, чтобы создать папку для нового проекта.
Переименование контроллера предст а вления
К а к м ы уже в идели, шаблон S i n g l e View Appl ication п редоставляет делегат
п риложе н и я , контролл ер п редставления и раскадров ку. Класс ко нтроллера
представления наз ы вается Vi ewCont ro l l e r . В этом приложении мы будем ра­
ботать с тре м я контроллерам и п редставлений, но основная логи ка приложения
будет сосредоточена в контроллере главного представления. Он будет постоя н­
но перекл ючать экран с одного контроллера представления на друго й . Для того
чтобы разъяс н ить рол ь контроллера главного представления, его и м я следова­
ло бы уточ н ить, напри мер назвать его S w i t c h i ngViewCon t r o l l e r . В проекте
есть нескол ько мест, где упоми нается и м я класса контроллера п редставления .
Для того чтобы изменить его и м я , нам необходимо измен ить и н формацию во
всех этих местах . В среде Xcode е сть п ре красная фу н кционал ьная возмож­
ность под названием рефактори н г (refactoring), которая позвол яет сделать это,
но когда м ы п исал и книгу, эта возможность еще не п оддержи валас ь проектами
на языке Swift. По этой п р и ч и не м ы удал и м шаблон н ы й контроллер и добавим
новы й .
ГЛАВА 6 Jf П РИЛОЖЕ Н И Я С Н ЕСКОЛ Ь К И М И П РЕДСТАВЛ Е Н И Я М И
225
Выберите файл ViewContro l l e r . s w i ft в окне навигатора проекта, щелкни­
те на правой кнопке и вы пол ните команду Delete в контекстном меню (рис. 6.9).
Получи в приглашение, переместите исходны й файл в папку Trash .
f:i
�
Q.
&
; /jj ._,--;;;, Swltch•r
У
0
iii
О
Vlew Switctмtr
!! AppDelegate.awlft
·
- .•Mi·'"'№A&M•
• Maln.stOl')'Ьo8/d
Asaets.xcasaeta
i..unchScreen .storyЬoard
•
lnfo.pltat
Products
�
1 88
{
//
11
//
� 11
s //
)
{i) Viow SWitcher !
Vlow S
V lewC011 t ro\ le r . sw 1 f t
V i� Sw 1 t c h e r
C reated Ьу Kll" Top t ey on 9/5
•
· ·
- • • • • · , s s Inc .
•
Show in FJnder
Open with Extemal Edltor
Open As
Show Flle lnspector
New f'ile
Add Files to "Vi ew Swltcher"
l.L()oad()
ie...t o n t
••.
..•
na t
set
ivefole1110
letno ryWa
New Group
New Group from Selection
resour
Sof't ьу Nал:е
Sort by 1yr;�
Find !n �lected GrotJps . .
Source Control
111>
Project Navigator Help
111>
Рис. 6 . 9 . Удал е н и е шабл о н н о го контроллера п р едставл е н и я
Щелкните правой кнопкой м ы ш и на имени гру п п ы View Switcher и вы пол н и­
те команду N ew File" " Выберите п и ктограмму Сосоа Touch Class в разделе IOS
Source. Назовите класс Swi tchi ngVi ewCon t ro l l e r и сделайте его подклассом
класса ViewCont ro l l e r . Сбросьте флажок Also create X I B fi le, установите зна­
чение Language равн ы м Swift ( как показано на рис. 6 . 1 О), а затем щелкн ите на
кнопках Next и C reate .
Новый контроллер представления необходимо добавить в раскадровку. Выбе­
рите файл Ma in . s t o ryboard в окне Document Outline и откройте раскадровку для
редактирования . В ы увидите, что шаблон уже создал контроллер представления,
и нам нужно просто связать его с наш и м классом Swi t ch i ngVi ewContro l l e r .
Выберите контроллер п редставлен ия в окне Document Outl i n e и откройте окно
инспектора иденти ч ности . Измен ите з наче н ие Class с U I Vi ewCont r o l l e r на
Swi tchi ngVi ewCon t ro l l e r в разделе Custom C lass (рис. 6 . 1 1 ).
226
ГЛАВА б '!\\ П РИЛОЖЕ Н И Я С Н ЕСКОЛЬКИ М И П Р ЕДСТАВЛ Е Н И Я М И
Choose options for your new file:
Class:
SwltchlngVlewController
Subctess of: UIViewController
Language:
Also create XIB file
в
Swift
Mt@*
Previous
Cancel
Рис . 6 . 1 О. Созда н и е класса Switc h i n gVi ewContro l l e r
• iPhOne И
'Nw Swttch«. Rнdy 1 Todly .t 8.40 АМ
( ) D, Vltw Switthef ) Y1ew swttehtf \
t Swltc:Nng Vh Controhr �
-"""' - c;otllt•lf•
ТОР L1yout Gtlld.
1o11om L•rout Ouldt:
1 vtew
8 Fifti Afмpotld1r
(1 E11h
Stat'f'Ь081'd Entry Polnt
м.ln.ll°'YЬotrcl ) 8 Мeln.stor,Ьotrd tlltt) ) 8 Vltw Controfltr !сем t SWltehlng Vlew Controllllr
а 8 .8
j
...
1,
1
·
� ф 8 � IJ е
twtom Ctau
c....
(В!s;g;g;;
,,,,.
il2:
o•
•
OltCVМWContron.t
tlty
r �StOt�
1О U1Coo.ttlorNJeweon1rol!1r
1
1
�
lhMOl'Юon Ю
OLPrevlnreontroti.r
Ullrna;ePicklrControИer
uм StOJ)'ЬOlrd 10
tu.. 08flflMINМim.-�
Кеv P1th
ТVО.
V1Ju1
Рис . 6 . 1 1 . И з м е н е н и е класса контролл е ра п редставл е н и я в раскадровке
Теперь в окне Docu ment O u t l i n e вы должны увидеть, что имя контроллера
представления изменилось на Switc h i n g View Controller (рис. 6 . 1 2).
Добавление контроллеров представления содерж и м ого
Для отображения представлен и й содержи мого на экране нам нужны еще два
контроллера представлен и й . Щелкните правой кноп кой м ы ш и на имени группы
View Switcher и выпол н ите команду New F i l e . . . . Перейдите в диалоговое окно вы­
бора шаблонов, выберите п и ктограмму Сосоа Touch C lass в разделе IOS Sou rce
и щел кните на кноп ке Next. Н азовите новый класс B l ueVi ewCont ro l l er и сде­
лайте его подклассом класса U IVi ewCont ro l l e r . Сбросьте флажок Also create
ГЛАВА б !i' П РИЛОЖЕ Н И Я С Н ЕС КОЛ ЬК И М И П РЕДСТАВ Л Е Н И Я М И
227
X I B fi le, потому что мы
план ируем чуть позже добавить этот контроллер в рас­
кадровку. Щел кните на кнопках N ext и C reate, чтобы сохран ить файл ы нового
контроллера представления. Повторите этот процесс, чтобы создать второй кон­
троллер представления содержимого, и назовите его Ye l l owVi ewCont rol l e r .
Дll я правил ьной орган изаци и проекта можно перейти в окно навигатора проекта
и переместить файл ы в пап ку View Swi t che r, как показано на рис. 6 . 1 3 .
r� !- � � >li_;w ;��cher >�_
....
'f
_
Swltchlnt Vtew Contro«
•••
SW\tcblng VJew Oont."
[6} Тор Layout Guide
19] Вottom Layout G ...
tQl viow
ф Flrst Rosponder
а Exlt
) StoryЬoard Entry Polnt
Рис. 6 . 1 2 . Н о в ы й контролл е р п ред­
ставл е н и я в окне Document Outl i n e
.
..,
.., •
..
�
•
А Vlew Swftcher /
Vfew Swftcher
r
"'\
_
"""
IPhone es
1 CIГ
J <
ас
'
Viev
-. YeflowVlewController.swll
View Switcher
·� YellowV!eWControner..swlft
�.
BlueVfewController.swift
}! SwftchlngVlewControlJer.twift
"·
AppDeleg1te.swift
Mefn.storylюilrd
Assets.xcassets
LaunchScre•n.storyЬoard
lnfo.pJist
.._
Products
Рис. б . 1 3 . И сходн ы е фай л ы м ожно переместить в папку
View Switcher в о кн е н а в и гатора п роекта
М одифи кация файла SwitchingViewController. swift
В классе S w i t c h i nVi ewCont ro l l e r нужен метод, вы пол няющий действие,
чтобы перекл ючаться между голубым и желты м представления м и . Нам вообще
не нужн ы выходы, но все же необходимы два других указателя, по одному для
228
ГЛАВА 6 1'11 П Р И ЛОЖЕ Н И Я С Н ЕСКОЛ Ь К И М И П Р ЕДСТАВЛ Е Н И Я М И
каждого контроллера, которые м ы будем перекл ючать. Они не обязаны быть вы­
ходам и, поскол ьку мы собираемся создавать их в исходном файле, а не в раскад­
ровке. Добавьте в файл Swi tchi ngVi ewCont ro l l e r . swi ft следующий код:
p r i v a t e va r Ы u eVi e w C o n t r o l l e r : B l u e V i e w C on t r o l l e r !
p r i v a t e v a r ye l l owVi e w C on t r o l l e r : Y e l l o wVi ewCon t r o l l e r 1
Добавьте в конец класса следующий метод:
@ IВAc tion func swi tchViews ( sender : UIBarButtoni tem)
}
Ранее м ы добавляли методы действия с помощью перетаскивания курсора и
клави ш и <Control>, но теперь поя вилас ь другая возмож1юсть, поскол ьку про­
грам ма 1 В может распознавать выходы и действия, уже определенные в исход­
ном коде. Объя вив необходимое действие, м ы можем настроить м и н и мальный
пол ьзовател ьский интерфейс для дан ного контролера в нашей раскадровке.
Создание представления с панелью инстру м ентов
Н еобходимо создать представл е н ие, чтобы добавить его к контроллеру
S w i t c h i n g V i ewC o n t r o l l e r . Напом н и м , что этот нов ы й контроллер пред­
ставл е н и я будет и грать рол ь корневого контроллера, котор ы й всту пает в
действие п р и запуске п риложе н и я . Представление содержимого контроллера
S w i t c h i ngVi ewCo n t r o l l e r будет состоять из панел и инструментов, рас по­
ложенной в н ижней части э крана. Она должна переключать голубое и желтое
представления, поэтому необходимо предусмотреть способ, с помощью которого
пол ьзовател ь сможет это сделать. Для этого воспол ьзуемся панел ью инструмен­
тов с кнопкой. Итак, сконструируем панел ь инструментов.
В ы берите файл Ma i n . s t o r ybo a r d в окне нави гатора проекта. В окне ре­
дактирован ия программ ы Interface B u i lder вы увидите контроллер переключаю­
щего представлени я . Как в идно на рис. 6 . 1 4, в настоя щий момент оно пустое и
довол ьно неинтересное. Именно здесь м ы нач нем создавать свой графический
пол ьзовател ьский и нтерфейс.
Добави м панель инструментов в н ижней части экрана. Захватите объект Tool­
bar из библ иотеки, перетащите в свое представление и поместите в нижней час­
ти окна, как показано на рис. 6. 1 5 .
М ы хотим растянуть панель инструментов вдоль нижнего края представления
содержимого независимо от его размера. Для этого необходимо установить три
ограничения макета - одно из них прикрепит панел ь инструментов к нижнему
краю п редставления, а два других прикрепят его к левому и правому края м .
Для этого выберите панел ь инструментов в окне Document Outli ne, щел кните на
кнопке Pin панел и инструментов, расположенной под раскадровкой, и измените
значения во вспл ы вающем окне так, как показано на рис. 6. 1 6.
1� <
>
1
j Top ll'fOU\
SWll�
VlowOui<le
Contro4let
l/lew SW"chet
lllow SWitcl>er ) 1 tdlln.1-yЬoard / 1 Мlln. 1 .• (8ut)
1 • !!! Swttehlng Vlew Control\of Шnе
•
229
ГЛАВА 6 rJ П Р ИЛ ОЖЕН И Я С Н ЕСКОЛ ЬКИ М И П Р ЕДСТАВЛ ЕН И Я М И
�e111ng Vlew eon1ro11" r
!
Swltching Vlew CO.ttollO< S..ne
О • •
8onotn Loyout Oulde
\/low
-
ф FJrtt R..-r
IJ E'"1
: StO()"Ьolfd Entry P<Нnt
IJ
V'- 8&: iPhone 8s (wC •R)
000000 : Оо
-
1
?5"
в !О! �дj
+
VlfY ro1 rrart•
Or..... _
1
1
Рис . 6 . 1 4 . Контрол л е р пустого корневого п р едставл е н и я ( Switc h i n g View
Controller) в раскадро в ке
6 �em
L.
one 6& (wC o R)
""
75"
О О О 1' О о
OfMntation
1"1Ьаr • ProYldn • rмe/\anlsm ror
dlaoleylng • rьо1Ь1r 11 the Ьottorn ol
/ lhl 1C1Нn.
+
Vary for Tralts
lll 16 tooJb
о
Рис . 6 . 1 5 . М ы пе ретащили объе кт Tool ba r на н о вое п р едставл е н и е . Об­
ратите в н и м а н и е н а то , что этот объект соде ржит одну к н о п ку с м еткой
230
ГЛАВА б !?J П РИЛОЖЕ Н И Я С Н ЕС КОЛ Ь К И М И П Р ЕДСТАВ Л Е Н И Я М И
Add New Conatralnt•
603
о
l �ument
1·4М
Он о
nherl•
I
Spacing to nearest neighbor
Constrain to margl ns
i1 wю1h
lii) Height
? lten�1
37Б
44
11 Equдl Wid tlis
13 Еq11•· Ho1yh1S
f
,-. f&1 Atpect Ratio
l
fШ Align , Leading Edges
(}
•
_
Updet8 Fremeв �----:D
1 (._
�-
l n""
.;..:
Ad
;;.:d:.;:3;..;
C:.;;.
; on
"'-'
t.;;_
tra
;;
;.; ts'-----')
_
_
_
,_�--�---...,.
,.,, .��:--·�,���-�
мn� 1
р1
F-
1
Рис . 6 . 1 6 . П р и кр е пл е н и е п а н ел и и н струм е нтов к н иж н е м у,
левому и п равому края м конте й н е рн о го п р едставл е н и я
Сбросьте флажок Constrain to margins, поскол ьку м ы хотим позиционировать
панел ь инструментов по отношению к краям представления содержимого, а не
с помощью голубых л и н и й разметки, поя вляющихся возле краев. Затем задайте
расстоя н ие до ближайших левых, правых и н ижних соседей равн ы м нулю (если
в ы правил ьно выбрал и позицию панели и нструментов, эти расстояния уже бу­
дут равн ы нулю). В данном случае ближай ш и м соседом панел и инструментов
я вляется представление содержи мого. Этот факт можно обнаружить, щел кнув на
маленькой стрел ке в одном из флажков, регламентирующих расстоя ния: откро­
ется вспл ы вающее окно, в котором показан бл ижайший и все другие возможные
соседи панел и инструментов, - в данном случае их нет. Для того чтобы указать
на активность ограничени й расстояния, щел кните на трех красных пунктирных
л и н иях, соединяющих пол я редактировани я с маленьким квадратом в центре,
чтобы они стал и сплош н ы м и . В закл ючение измен ите значение U pdate Frames
на I t ems o f New Cons t r a i n t s (чтобы представление панели инструментов в
раскадровке переместилось в новое место, определенное ограничения ми) и щел­
кн ите на кноп ке Add 3 Constraints.
Щел кните на кнопке Run и запустите приложение на симуляторе iOS. Вы
должн ы увидеть пустой бел ы й э кран и серую панел ь инструментов, содержа­
щую одну кноп ку. В противном случае вернитесь назад и повторите все, что
было о писано выше. Поверните симулятор и убедитесь, что панел ь инструмен­
тов по-прежнему прикреплена к н ижнему краю представления и растя нута вдоль
экрана. Если нет, исправьте огран ичения, относя щиеся к панел и инструментов.
ГЛАВА 6 :.li П Р И Л ОЖ Е Н И Я С Н ЕСКОЛ ЬК И М И П РЕДСТАВЛ Е Н И Я М И
23 1
Связывание кнопки панели инструментов
с контроллером представлен ия
Панел ь инструментов содержит еди нственную кноп ку, которую м ы будем
испол ьзовать, чтобы п редоставить пол ьзователю возможность перекл ючаться
между разн ы м и представлениями содержи мого. Дважды щел кн ите на кнопке в
раскадровке (рис. 6 . 1 7) и измените ее название на Switch Views . Нажм ите кла­
вишу <Return>, чтобы подтвердить внесенные изменен ия . М ы можем связать
кнопку на панел и инструментов с наш и м методом , в ы полняющим действие.
Прежде чем сделать это, должны п реду предить: кно п ки на панел и инструмен­
тов не похожи на элементы управления систе м ы iOS. Они поддержи вают тол ько
одно целевое действие и могут и н и циировать его тол ько в четко определен н ы й
момент времени, который я вляется эквивалентом события T o u c h U p I n s ide,
происходя щего с элементам и управления системы iOS .
Switch View3
О
75%
View as: iPhone 6s ( w C h R)
JOoooo Оо
- -
Device
--
Orlentation
--· -
---
+
Vary.!_or Tr�its
------------ __"______
_
Рис. 6 . 1 7 . И з м е н е н и е н адп и с и на к н о п ке на панели и н струме нтов
н а Switch Views
Выбрать кноп ку на панели инструментов может быть сложно. П роще всего
раскрыть п и ктограмму Switc h i n g View Controller в окне Docu ment Outliпe, найти
кнопку Switch Views и щел кнуть на ней . В ыбрав кнопку Switch Views, нажм ите
клавишу <Control> и перетащите указател ь от нее к п и ктограмме Switching View
Controller в верхней части сцены (рис. 6 . 1 8). Отпустите кнопку м ы ш и и выбери­
те действие swi t chVi ewsWi thSende r : из вспл ы вающего меню. Если действие
swi t thVi ewsWi thSende r : на экране не отображается, а вместо него вы видите
указатель, которы й называется делегатом, знач ит, скорее всего, вы перетащил и
указател ь от панел и инструментов, а не от кнопк и . Для того чтобы исправить
эту ошибку, проверьте, что выбрали кноп ку, а не панел ь инструментов, а затем
повторите процедуру.
232
ГЛАВА 6 "" П РИЛОЖЕН И Я С Н ЕСКОЛ Ь К И М И П РЕДСТАВ Л Е Н И Я М И
IPhone 6s
8 (
Vlew Switchtr :
Finlshed runnlng \/1tw Switchef on IPhone 6s
V!Ow
f=i Swltchlng Vlew Conlroller Sceno
•
... �cher ' ·
Maln""oard
1 Moln.-•ИI )
Swltchlng Vlew Controller
"1
У
11>
J Тор Layout Guld•
1 Вottom L1yout Guide
Vlew
Toolьar
-i•@Ji:Pf
fIO Constralnls
ф Flrst Respondor
(g E•lt
4
Storytю1rd Entry Point
Рис . 6 . 1 8. С в я з ы в а н и е к н о п к и п а н е л и и н струм ентов с м етодо м
switchViewWithSender в классе контроллера п редставл е н и я
Отметим еще оди н элемент с це н ы - выход представления Swi tchi ngView
C o n t r o l l e r . Он уже связан с представлением на с цене. Выход view я вляется
наследником класса U IVi ewCont ro l l e r и предоставляет контроллеру доступ к
своим элементам управлен ия . При создании проекта п рограм ма Xcode создает
как контроллер, так и его п редставлен ие, и связы вает их оди н с други м . Это
все, что м ы должн ы были сделать, поэтому сохраните раскадровку. Перейдем к
реал изации класса Switchi ngVi ewCont ro l l e r .
Создание корневого контроллера представления
Настало время создать корневой контроллер представлен и я . О н п редна­
значен для перекл ючения между желты м и голуб ы м п редставлениями, ког­
да пол ьзовател ь щел кает на кнопке Switch Views. В несем изменения в файл
Swi t c h i ngViewC o n t ro l l e r . s w i f t и модифицируем метод viewDidLoad ( ) ,
добавив строки, при веденные в л истинге 6 . 1 .
Л и стинг 6 . 1 . Код метода viewDi dLoad контроллере корневого представления
ove r r i de f u n c v i e w D i d Load ( )
s up e r . v i e w D i d L o a d ( )
/ / Дополнител ь н а я н а с тройка п о сле з а гру з ки предс т а вл е ния .
Ы u eVi ewCo n t ro l l e r
s t o r yb o a rd ? . i n s t a n t i a t e V i e w C o n t r o l l e r ( w i t h i de n t i f i e r : " B l u e " )
a s ! B l ueVi ewControl l e r
Ы u e V i ewCo n t r o l l e r . v i e w . f r ame
v i e w . f rame
s w i t c h V i ewCon t r o l l e r ( f r om : n i l ,
to :
Ы u e V i ewCo n t r o l l e r ) / / в с п омо г а т ел ь ный метод
=
=
ГЛАВА 6 �1 П РИЛОЖЕ Н И Я С Н ЕСКОЛ Ь К И М И П РЕДСТАВЛ Е Н И Я М И
233
ЗАМЕЧАНИЕ. Есл и вы введете код, показ а н н ы й в л исти н ге 6 . 1 , в файл с расширен и ­
е м swi f t , то получите сообщение о б ошибке в строке , содержащей вызов м етода
swi t chViewCon t ro l l e r . Это объясн яется тем , что м ы еще не написал и код вспо­
могательного метода . Вскоре м ы это сделае м .
.
М од и ф и ц и рован н ы й н а м и м етод v i e w D i d L o a d з а м е щает м етод
U IVi ewCont ro l l e r, которы й вызывается при загрузке раскадровки . Откуда м ы
зто знаем? Н ажмите клавишу <Option>, дважды щел кните на имени метода и
посмотрите на окно с документацией, которое поя вится на экране (рис. 6 . 1 9).
Кроме того, м ожно выбрать команду View i::> U t i l ities i::> Show Qu ick H e l p l пspector.
Этот метод определен в родительском кл ассе U IVi ewCont ro l l e r и предназна­
чен для замещения классами, которые должны получать у ведомления о том, что
загрузка представления завершена.
Рис. 6. 1 9 . Это о к н о с докуме нтаци е й п о я в л я ется п осл е того , как
в ы дважды щел кнете н а м етоде v i e w D i dLoad, удерживая нажатой
кла в и ш у < O ption >
Этот вариант метода v i e w D i dL o a d создает э кземпляр кл асса B l u e V i e w
Con t r o l l e r . М ы испол ьзуем метод i n s t a n t i a teViewCont ro l l e r ( w i t h i d
e n t i f i e r : ) для загрузки э кземпляра кл асса B l ueViewC o n t r o l l e r и з рас­
кадровки . Для доступа к кон кретному контроллеру представления из раскад­
ровки , м ы испол ьзуем строку-идентификатор - в дан ном случ ае " B l ue", которая задается при настрой ке раскадров к и . После создан ия э кзе м пляра
класса B l uwViewC o n t ro l l e r м ы присваиваем этот новый экземпляр свойству
ЫueVi ewCont ro l l e r .
Ы u e V i ewCo n t r o l l e r =
s t o ryb o a rd ? . i n s t a n t i a t e V i ewCon t r o l l e r ( w i t h l de n t i f i e r : " B l ue " )
a s ! BlueVi ewCont rol l e r
234
ГЛАВА 6 !:i П Р ИЛОЖЕН И Я С Н ЕС КОЛ ЬК И М И П Р ЕДСТАВ Л Е Н И Я М И
Затем зададим рамку голубого представления такой же, как у п редставления
содержимого, и переключимся на контроллер голубого представления.
Ы u e V i ewCont r o l l e r . vi e w . f r ame = v i ew . f r ame
s w i t chViewCo n t r o l l e r ( f rom : n i l , t o : Ы u eVi ewCo n t r o l l e r )
П о с кол ь ку контроллер п редставл е н и я н еобход и м о в ы п ол н ить в , не­
с кол ьких м естах, мы в с коре нап и ше м для этого вспомогател ь н ы й метод
swi t chVi ewCon t ro l l e r ( f rom : , t o : ) .
Почему бы нам не загрузить также желтое представление? Нам ведь все равно
придется это сделать, так почему бы не сейчас? Хорош и й вопрос. Ответ состо­
ит в том, что пол ьзователь может н и когда не нажать кнопку Swi t ch Views. Он
может просто испол ьзовать представление, которое видит на экране, а затем вый­
ти из приложения . В этом случае нет смысла испол ьзовать ресурсы для загруз­
ки желтого представления и его контроллера. В место этого мы загрузим желтое
представление толь ко тогда, когда оно действительно понадобится . Этот подход
называется ленивой загрузкой (lazy loading) и стал стандартным способом эко­
номи и памяти. Фактическая загрузка желтого п редставления выпол няется мето­
дом swi tchVi ews ( ) . Добави м в этот метод строки, приведенные в листинге 6.2.
Л истин г 6.2. Реализация метода swit chV i ews
@ I BAc t i o n func s w i t ch V i e w s ( s e nde r : U I B a r B u t t on i t em )
1 1 С о з д а е м но вый к о н троллер п р е д с т а вл е н и я при н е о б х о димо сти
i f ye l l owV i e wCo n t r o l l e r ? . vi ew . s up e r v i e w == n i l {
i f y e l l owViewCo n t r o l l e r == n i l {
ye l l owV i ew C o n t r o l l e r =
s t o r yboa rd ? . i n s t a n t i a t eV i ewCon t r o l l e r ( w i t h i de n t i f i e r : " Y e l l o w " )
a s ! Y e l l ow V i e w C on t r o l l e r
e l s e i f Ы u eVi ewCon t r o l l e r ? . vi ew . s up e r v i e w = = n i l {
i f Ы u e V i ewCon t r o l l e r == n i l {
Ы ueViewCont rol l e r =
s t o rybo a r d ? . i n s t a n t i a t e V i e wC o n t ro l l e r ( w i t h i de n t i f i e r : " B l ue " )
a s ! B l u e V i ew C o n t r o l l e r
1 1 П ере ключ а ем к о н тр оллеры пр е дс т а вл е ни я
i f Ы ueViewCont ro l l e r ! = n i l
& & Ы u e V i ewCon t r o l l e r ! . v i e w . s up e r v i e w ! = n i l (
ye l l ow V i e w Co n t r o l l e r . vi ew . f r ame = v i ew . f r ame
s w i t ch V i ewCon t r o l l e r ( f r om : Ы u e V i e w C o n t r o l l e r ,
t o : ye l l owV i e w C o n t r o l l e r )
else (
Ы u e V i e w Co n t r o l l e r . vi ew . f r ame = v i e w . f r ame
s w i t ch V i ewCont r o l l e r ( f rom : ye l l ow V i e w C o n t r o l l e r ,
t o : Ы ue V i ewCon t ro l l e r )
ГЛАВА 6 � П Р И Л ОЖ Е Н И Я С Н ЕСКОЛ Ь К И М И П Р ЕДСТАВЛ Е Н И Я М И
235
Сначала метод swi tchV i ews ( ) проверяет, какое п редставление было вкл ю­
чено, проверяя, не равно л и значение ye l l owVi ewCont ro l l e r в родител ьском
представлении значению n i l . Метод возвращает значение t rue, есл и выпол ня­
ется одно из двух услови й .
!%
;i,i
Есл и представление ye l lowVi ewCont rol l e r существует, но н е показано
пол ьзователю, значит, оно не имеет родительского п редставления, потому
что его в дан н ы й момент нет в иерархии представлений, и в ы числяемое
выражение станет равным t rue .
Если представления ye l l owVi ewCont r o l l e r не существует, потому что
оно еще не было создано ил и было удалено из памяти, метод тоже вернет
значение t rue.
Затем проверяем, равен л и объект ye l l owVi ewCont ro l l e r з начен и ю n i l .
i f ye l l owViewCo n t ro l l e r ? . v i e w . s up e r v i e w
= =
nil {
Есл и результат равен n i l, значит, экзе м пляра класса ye l lowVi ewCont rol l e r
нет, и м ы должн ы его создать. Это может произойти, есл и кнопка нажимается в
первый раз ил и если система наводила порядок в памяти и удалила этот экзе м пляр.
В этом случае м ы должны создать экзе м пляр класса Ye l lowViewCont ro l l e r так,
как мы это делал и с экзем пляром класса B l ueViewCont r o l l e r в методе view
DidLoad.
if ye l l owV i ewCon t r o l l e r
nil {
ye l l owV i ewCont r o l l e r
s t o ryboa rd ? . i n s t a n t i a t e V i e wC on t r o l l e r ( w i t h i de n t i f i e r : " Y e l l ow " )
a s ! Y e l l owViewCo n t r o l l e r
==
=
Есл и м ы перекл ючились н а голубое представление, то должн ы п роверить,
существует ли он (поскольку он мог б ыть удален из памяти), и создать его, есл и
его нет. Код, вы полняющий эти операции, точно такой же, как и выше, только
на этот раз он относится к голубому п редставлению.
e l s e i f Ы ue V i e w C o n t r o l l e r ? . vi e w . s up e r v i e w
nil
i f Ы u eVi ewCo n t r o l l e r = = n i l {
Ы u e V i ewCon t r o l l e r
s t o r ybo a rd ? . i n s t a n t i a t e V i e w C on t r o l l e r ( w i t h i de n t i f i e r : " B l ue " )
a s ! B l ueVi ewCont r o l l e r
} '
==
=
Поскол ьку нам известно, что экзе м пляр контроллера представления сущест­
вует (он создан л ибо системой, л ибо нами), задаем оди наковые рам ки контрол­
лера представления и контроллера представлен ия содержи мого и в ы пол няем
переключение с помощью метода s w i t chVi ewCont r o l l e r ( from : , t o : ) , как
показано в л истин ге 6.3 .
236
ГЛАВА 6 !ti П Р И Л ОЖ Е Н И Я С Н ЕСКОЛ Ь К И М И П РЕДСТАВ Л Е Н И Я М И
Л истинг 6 . 3 . Перекл ючение контроллера в зависимости от текущего представления
11 П е р е ключ аем к о н т р оллеры предс т а вл е н и я
i f Ы ueViewCoпt rol l e r ! = n i l
& & Ы ue V i e w C o n t r o l l e r ! . v i e w . s up e r v i e w ! = n i l {
ye l l owV i e w C o n t ro l l e r . v i e w . f r ame = v i e w . f r ame
s w i t c h V i e w C o n t r o l l e r ( f r om : Ы u e V i e w C o n t r o l l e r ,
t o : ye l l owV i e wCo n t r o l l e r )
else {
Ы ue V i ewCont r o l l e r . vi e w . f r ame = v i ew . f r ame
s w i t c h V i ewC o n t r o l l e r ( f r om : ye l l ow V i e w C on t r o l l e r ,
t o : Ы u e V i ewCon t r o l l e r )
Первая ветвь оператора i f выпол няется, есл и м ы перекл ючил ись с голубого
есл и с желтого на голубое.
представления на желтое, а ветвь e l s e
Пом и м о отказа от испол ьзования ресурсов для желтого п редставления и
контроллера, есл и кнопка Switch Views н и когда не была нажата, ленивая за­
грузка позволяет удал ить из памяти представление, которое не будет показа­
но на экране. Если объем с вободной памяти опускается н иже установленного
порога, система iOS вызовет метод d i d Re c e i veMemo ryWa r n i n g ( ) из класса
U IVi ewCont ro l l er, который наследуется каждым контроллером представления.
Так как нам известно, что представление, загружен ное в следующий раз, бу­
дет п редъявлено пол ьзователю, м ы можем безопасно удал ить контроллер, если
он не связан с п редставлением, демонстрируе м ы м на экране . Для этого в су­
ществующий метод d i dRe ce iveMemoryWa r n i n g ( ) необходимо вставить стро­
ки, показанные в листин ге 6.4.
-
Л истинг 6 . 4 . Безопасное освобождение памяти от ненужных
контроллеров при сильных ограничениях на объем памяти
ove r r i de func d i d Re c e i veMemo r yW a r n i n g ( )
s up e r . d i dR e c e i veMemo r yWa r n i ng ( )
1 1 О с в о б ождаем в о з о б н о в л я емые р е сурсы
i f Ы ueViewCon t ro l l e r ! = n i l
& & Ы u e V i ewC o n t r o l l e r ! . v i ew . s up e r v i e w
Ы u e V i ewCon t r o l l e r = n i l
==
nil {
i f ye l l owV i e wCo n t r o l l e r ! = n i l
& & ye l l ow V i e wC o n t ro l l e r ! . v i e w . s up e r v i e w = = n i l {
ye l l owVi ewCo n t r o l l e r = n i l
Этот код проверяет, какое и з п редставлений в дан н ы й момент демонстриру­
ется пользовател ю, и удаляет контроллер другого представления, присваивая его
свойству значение n i l . В результате этот контроллер и представление, которым
он управляет, будут удалены из памяти .
ГЛАВА 6 �� П РИ Л О Ж Е Н И Я С Н ЕС КОЛ ЬКИ М И П РЕДСТАВЛ Е Н И Я М И
237
ПОДСКАЗКА. Лени вая загрузка - кл ючевой ком понент управления ресурсам и в системе
IOS, и его следует применять всегда . В сложн ых приложениях с нескольки м и п ред­
ставлениями аккуратное обращение с пам ятью и удаление неиспользуемых объектов
гарантирует безотказную работу, в п ротивном случае приложение будет периодичес­
ки давать сбои из-за исчерпания памяти .
Последн ий фрагмент мозаи ки - м етод s w i t chVi ewC o n t ro l l e r ( f r om : ,
to : ) , отвечающий за перекл ючение контроллера представления. Перекл ючение
контроллеров представления п редставляет собой двухэтапн ы й процесс. Сначала
необходимо удал ить представление для текущего контроллера, а затем добавить
представление для нового контроллера представления. Но это еще не все - не­
обходимо вы пол н ить уборку. Добавьте в програм му реал изацию метода, при ве­
денного в листи нге 6 . 5 .
Листи нг 6 . 5 . Вспомогательн ы й метод s w i t chVi ewcont r ol l e r
p r i va t e f u n c s w i t c h V i e w C o n t r o l l e r ( f r om f r omVC : U I Vi e w C o n t r o l l e r ? ,
t o toVC : U I V i ewC o n t r o l l e r ? ) {
i f f r omVC ! = n i l {
f r omVC ! . w i l l Move ( t o P a r e n tV i e w C o n t r o l l e r : n i l )
f r omVC ! . v i e w . r emove F r omSupe r v i ew ( )
f r omVC ! . r emove F r om P a r e n tVi e w C o n t r o l l e r ( )
i f t oVC ! = n i l {
s e l f . addC h i l dV i ewC o n t r o l l e r ( t oVC ! )
s e l f . v i e w . i n s e r t S ub v i e w ( t oVC ! . v i e w , a t : 0 )
t oVC ! . d i dMove ( t o P a r e n t V i ewCo n t r o l l e r : s e l f )
Первы й блок кода удаляет текущий контроллер п редставления, н о сначала
м ы разберем второй блок кода, в которы й добави м контроллер следующего
представления . Первая строка этого блока и м еет следующий вид:
s e l f . addC h i l dV i ewC o n t r o l l e r ( t oVC ! )
Этот код делает контроллер следующеm представления дочерним классом кон­
троллера переключающеm представления. Контроллеры представления, такие как
Swi t ch i ngVi ewCon t r o l l e r, управляющие други м и контроллерами представ­
лени�, называются контроллера м и конте й нерных п редставлен и й (container
view controllers). Стандартные классы U I T abBarCont r o l l e r и U I Navi g a t i o n
Cont ro l l e r представляют собой контроллеры контейнерных представлений, а
их код похож на код метода swi t chVi ewCont ro l l e r ( from : , t o : ) . Блаmдаря
тому, что контроллер новоm представления задается как дочерний класс класса
Swi t c h i ngViewCont ro l l e r, определенные события, поступающие в контрол­
лер корневоm представления, при необходимости корректно передаются дочерне­
му контроллеру. Например, контроллер позволяет правильно обработ�пь вращение.
238
ГЛАВА 6 � П РИЛОЖЕ Н И Я С Н ЕСКОЛ Ь К И М И П РЕДСТАВЛ Е Н И Я М И
Зате м представл е н и е добавл я ется в объе кт класса S w i t c h i n g V i e w
Cont r o l l e r :
s e l f . vi ew . i n s e r t S ub v i e w ( t oVC ! . vi e w , a t i ndex : 0 )
Обратите внимание на то, что п редставление вставляется в список дочерних
представлений класса Swi t ch i ngVi ewCon t ro l l e r с нулевым индексом, давая
системе iOS указание вставить это представление позади всех остальных. ' Бла­
годаря этому панел ь инструментов, создан ная в среде l nterface B u i l der, будет
всегда видимой на экране, посколь ку представление содержимого вставляется
за н и м . В закл ючение мы уведомляем контроллер следующего представления о
том, что он был задан как дочерний класс другого котроллера.
t oVC ! . d i dMove T o P a r e n t V i ewCo n t r o l l e r ( s e l f )
Это необходимо, есл и дочерний контроллер представления замещает этот ме­
тод для выполнения другой операции .
Теперь, когда м ы показал и, как добавляется контроллер представления, код,
удаляющий контроллер п редставления, становится понятнее - м ы просто вы­
пол няем операци и в обратном порядке.
i f f r omVC ! = n i l {
f r omVC ! . w i l l Move T o P a r e n t V i e w C o n t r o l l e r ( n i l )
f r omVC ! . v i e w . r emove F r omSupe r v i e w ( )
f r omVC ! . r emove F r omP a r e n tV i ewCon t r o l l e r ( )
Реализация представлений содержимого
Итак, код завершен, но пока м ы не можем запустить приложение, потому что
еще не вкл ючил и контроллеры голубого и желтого представлений в раскадровку.
Эти контроллеры чрезвычайно простые. Кажд ы й из н их содержит один метод
действия, который в ыполняется при нажатии клавиши, и выходы совершенно не
нужны . Голубое и желтое п редставления почти идентич н ы . Они настол ько по­
хожи, что их можно было бы реал изовать с помощью одного и того же класса.
Но мы создал и два разных класса, потому что эта ситуация я вляется типичной
для большинства приложений с нескол ьки м и представления м и .
Два метода действия, которые м ы намереваемся реал изовать, просто выводят
на экран предупреждение (см . главу 4). Добавим метод, представленн ы й в лис­
тин ге 6.6, в файл В lueViewCont ro l l e r . swi f t .
Листи н г 6 . 6 . Нажатие кнопки на голубом контроллере вызывает предупреждение
@ I BAc t i on func Ы u e B u t t o n P r e s s e d ( s e n de r : U I Bu t t o n ) {
l e t alert = UIAlertControl l e r ( ti t l e : " Blue View Button Pres sed" ,
me s s a g e : " Y ou p r e s s e d t h e b u t t o n оп t h e Ы u е v i e w " ,
p r e f e r r e dS t y l e : . a l e r t )
l e t a c t i on = U I Al e r tAct i o n ( t i t l e : " Ye s , I d i d " , s t yl e : . de f a u l t ,
handl e r : n i l )
a l e r t . a ddAc t i o n ( a c t i o n )
p r e s e n t ( a l e r t , a n i m a t e d : t r ue , c omp l e t i o n : n i l )
ГЛАВА б 11 П Р ИЛОЖЕН И Я С Н ЕСКОЛ Ь К И М И П Р ЕДСТАВЛ Е Н И Я М И
239
Сохраните файл . Затем откройте файл Ye l l owVi ewCont r o l l e r . swi ft и до­
бавьте в него метод из листи нга 6 . 7 .
Листинг 6 . 7 . Нажатие кнопки на желтом контроллере
также вызывает предупреждение
I BAc t i on f u n c ye l l ow Bu t t o n P r e s s e d ( s e nde r : U I Bu t t o n ) {
let alert
U I Al e r t C on t r o l l e r ( t i t l e : " Ye l l ow V i e w B u t t o n P r e s s e d " ,
me s s a g e : " You p r e s s e d t h e b u t t o n on t h e ye l l ow v i ew " ,
p r e f e r r e dS t y l e : . a l e r t )
let action
U I Al e r t Ac t i o n ( t i t l e : " Y e s , I d i d " , s t y l e : . de f a u l t ,
hand l e r : n i l )
a l e r t . addAc t i o n ( a c t i o n )
p r e s e n t ( a l e r t , a n i ma t e d : t r u e , comp l e t i o n : n i l )
=
=
Теперь откройте файл Ma i n . s t o rybo a r d в среде l nterface B u i lder, чтобы
внести в него нескол ько измене н и й . Сначала необходимо добавить новую сце­
ну для класса B l ueViewCont ro l l e r . До сих пор все раскадровки, с которым и
м ы работал и, содержал и только одну пару "контроллер-представлен ие", н о на
самом деле они могут иметь несколько сце н . Перетащите из библиотеки объек­
тов на область редактирования еще оди н элемент View Controller и оставьте его
рядом с существующи м . Теперь ваша раскадровка содержит две сцены, каждую
из которых можно загружать динамически и независимо во время выпол нения
приложения. В строке п и ктограмм, расположенной в верхней части новой сце­
ны, щел кн ите на желтой п и ктограм ме View Controller и нажм ите комбинацию
клавиш <Option+3C+3>, чтобы открыть и нспектор идентичности. В разделе Cus­
tom Class атрибут Class по умолчанию имеет значение U IVi ewCon t ro l l e r; из­
мените его на B lueVi ewCont ro l l e r, как показано на рис. 6 .20.
D • •
L... -fted · l-1
в
Notм • • • • ·- IZJ liJ ...•
(f) :
- -·
Рис. 6 . 20. Добавл я е м н о в ы й контролл ер п редставл е н и я и свя з ы ­
ваем е г о с файло м кл асса B l ue V i ewCon t ro l l e r
240
ГЛАВА 6 "� П Р И Л ОЖЕН И Я С Н ЕСКОЛ ЬК И М И П РЕДСТАВ Л Е Н И Я М И
Необходимо также создать идентификатор для нового контроллера представ­
ления, чтобы наш код мог найти его в раскадровке. Под разделом Custom Class
в окне инспектора идентичности находится поле Story board I D . Щел кните в нем
и в ведите слово B l ue, которое м ы испол ьзовали в коде (рис. 6.2 1 ).
·) ) 11 View Controller Scene ) О Blue View Controller < Л >
о
� cv f-�
о ь� ) о
() Ф m.!1 -0 [) G>
---------------
Cuetom CI•••
Class , BlueViewController
-1
1
Modute i C p r r ···f'1
l dentlty
\
w S,,- �с t
О8
•
Jfl!l'I
G
Storyboard ID в 1u e________
"._
Restoratlon 10 l
) Use Storyboard ID
1"
J
uaer Defined Auntlme Attrlbutes
Ке у Path
Туре
Va lue
Рис . 6 . 2 1 . Зада е м иде н т и фи катор раскадро в к и в раскадр овке контролл ера
голубого п р едста вл е н и я равн ы м B l ue
Итак, у нас есть две сце ны. Ранее м ы показал и, как настроить приложение на
загрузку раскадровки в ходе запуска, но м ы ничего не рассказали о сценах. Отку­
да приложению известно, какое из двух представлений следует показать на экра­
не? Оrвет кроется в бол ьшой стрел ке, указы вающей на первую сцену (рис. 6 .22).
Эта строка указы вает на сцену, заданную по умолчанию, с которой приложение
начинает рабоrу. Если вы хотите задать по умолчан и ю другую сцену, то должны
перетащить Э1)' стрел ку, чтобы она указ ы вала на желаемую сцену.
Щелкните на большом квадратном представлении на новой сцене, добавлен­
ной нами в раскадровку, а затем нажм ите комбинацию клавиш <Option+X +4>,
чтобы открыть инспектор атрибутов. В разделе и нспектора View выберите цвет
Backgrou n d и с помощью селектора цвета измен ите цвет фона этого представ­
ления на тем но-голубой. Если вам нравится этот цвет, закройте селектор цвета.
Перетащите элемент Button из библиотеки на представлен ие, испол ьзуя ли­
н и и раз метки , расп оложите кно п ку в центре п редставления, выровняв ее как
по вертикал и , так и по горизонтал и . М ы хоти м, чтобы кнопка всегда остава­
лась в центре, поэтому должны задать соответствующие огран ичен ия. Выберите
кнопку и щел кните на кноп ке A l i g n под раскадровко й . Во вспл ы вающем меню
выберите команды H o rizonta l ly i n Conta i n e r и Vertica lly i n Container, выберите в
раскр ы вающемся с п иске U pdate F ra mes пункт l te m of N ew Con stra i n ts, а затем
ГЛАВА 6 � П РИЛОЖЕ Н И Я С Н ЕСКОЛЬК И М И П Р ЕДСТАВЛ Е Н И Я М И
24 1
щелкните на кноп ке Add 2 Constrai nts (рис. 6.23). Целесообразно изменить цвет
фона на бел ы й, чтобы выровнять элементы интерфейса, а затем, закончив ра­
боrу, вернуть синий цвет. Кроме того, текст на кно п ке следует сделать бел ы м ,
чтобы он был виден на с и н е м фоне.
-
Рис. 6 . 2 2 .
М ы до ба в и л и вторую с це н у. Бол ь ш а я
стрел ка указ ы вает н а с це н у, зада н ную по умол ч а н и ю
�re� 1!И
Add New Allgnment Constralnts
1
. L.�--
lmage
ral
J?1 f(1L
Le.;d:ng Eug�s
f:il) Trэ1ling Eoges
1Ш Тор �rJges
l!J Bottom Edges
fJD Horlzontal Centers
@1 Vertical Centers
- @1 Baseiines
а GD Horizontally in Container
11 @1 Vertically ln Container
WI
Sh1
Hig
Dis
Trun•
�-
Cont
�п :::э
L1
LO
Bot
,.,.
r·
Рис. 6 . 23. В ы равн и ва н и е к н о п ки п о це нтру п редста влен и я
242
ГЛАВА 6 :u П РИЛОЖЕ Н И Я С Н ЕСКОЛЬКИ М И П РЕДСТАВ Л Е Н И Я М И
Дважды щел кн ите на кнопке и измен ите е е назван ие на Press М е . В ы ­
брав кнопку, перейдите в окно и нспектора связей ( нажав комбинацию клавиш
<Option+ :М: +б> ) , перетащите оттуда событие Touch U p l nside на желтую пиктог­
рамму View Controller, расположенную в верхней части сцены, и соедините ее с
методом действия ЬlueButton Pre s s e dWi thSende r .
Теперь необходимо сделать то же самое для п редставления Ye l l owV i e w
C o nt r o l l e r . Перетащите элемент View Control ler из библиотеки объектов в
область редакти ровани я . Есл и элементы сцен начнут тесн иться, не беспокой­
тесь: каждая из сцен будет перекры вать другую, так что все будет в порядке !
Щел кн ите на п и ктограм ме View Controller для новой сцены в окне Docu ment
Outline и с помощью инспектора идентич ности измените ее класс на Ye l l ow
Vi ewCon t ro l l e r, а ее иденти ф икатор Storyboard ID - на Ye l l ow.
Затем выберите представление Ye l l owVi ewCont ro l l e r и перейдите в окно
и нспектора атрибутов. После этого щел кните на селекторе Background, выберите
ярко-желты й цвет и закройте селектор цвета.
Перетащите объект Button из библиотеки на представление и с помощью ли­
ний разметок установите его в центре. Испол ьзуя меню, установите ограниче­
ния по верти кал и и по горизонтал и, как м ы делал и для последней кноп ки. Пос­
ле этого измените его заголовок на Press Ме, Тоо. Выбрав кнопку, перейдите в
окно и нспектора связей, перетащите оттуда событие Touch U p l nside на желтую
пиктограм му View Controller, расположенную в верхней части сцены, и соедини­
те ее с методом действия ye l l owBu t t on Pre s s edWi thSende r .
Закончив работу, сохран ите раскадровку и при готовьтесь к тестирован ию
приложения . Н ажм ите клавишу Run в среде Xcode. Ваше приложение должно
запуститься и запол н ить весь экран голубым цветом. При запуске приложение
демонстрирует голубое представление. Когда пол ьзователь нажмет кнопку Switch
Views, произойдет перекл ючение на желтое представление. Есл и он нажмет ее
еще раз, то на экране отобразится голубое представление. Есл и пол ьзовател ь
нажмет кнопку, расположенную в центре голубого ил и желтого представления,
на экране поя вится предупрежден ие, подтверждающее, что кнопка была нажата.
Это предупрежден ие свидетел ьствует о том , что при вы воде представления на
экран был вызван правил ь н ы й контроллер.
Тем не менее переход от одного представления к другому происходит доволь­
но резко, поэтому нужно как-то сгладить эти переходы .
Анимация перехода
Класс U IView содержит нескол ько методов, с помощью которых можно ука­
зать, что переход следует ан и м ировать, выбрать вид ани маци и и указать ее про­
должител ьность.
Верн итесь к ф айлу S w i t c h i ngVi ewCont r o l l e r . s w i f t и замен ите метод
swi t chVi ews ( ) кодом, представлен н ы м в листинге 6 . 8 .
ГЛАВА 6 "' П РИЛОЖЕН И Я С НЕСКОЛ ЬКИ М И П Р ЕДСТАВЛ Е Н И Я М И
243
Л истинг 6 . 8 . Модифици рованный метод swi t chViews с анимацией
@ I BAc t i on f u n c s w i t c h V i e w s ( s ende r : U I Ba r B u t t o n i t em ) {
1 1 С о здаем но вый контроллер предс т а вл е ни я при необходимо с т и
i f ye l l owViewCo n t r o l l e r ? . vi ew . s up e r v i e w
nil {
i f ye l l owV i e wCont r o l l e r
nil {
ye l l ow V i e w C o n t r o l l e r
s t o r yb o a r d ? . i n s t a n t i a t e V i ewCon t r o l l e r ( w i t h i de n t i f i e r : " Ye l l ow " )
a s ! Ye l l owV i e w C o n t r o l l e r
==
==
=
e l s e i f Ы u e V i e w Co n t r o l l e r ? . vi e w . s up e r v i e w
nil {
i f Ы ue V i ewCo n t r o l l e r
nil {
Ы u eVi ewCont r o l l e r
s t o r yb o a r d ? . i n s t a n t i a t eV i e w Co n t r o l l e r ( w i t h i de n t i f i e r : " B l ue " )
a s ! B l ueVi ewCo n t r o l l e r
==
=
U I V i e w . b e g i nAnima t i o n s ( " V i e w F l i p " , c o n t ex t : n i l )
U I V i e w . s e tAnima t i o n D u r a t i o n ( 0 . 4 )
U I V i ew . s e tAnima t i onCurve ( . e a s e i nOut )
1 1 Пере ключ аем контроллеры предс т а вл е ни я
i f Ы u e V i ewCont r o l l e r ! = n i l
& & Ы u eVi ewCo n t r o l l e r ! . vi e w . s up e rvi e w ! n i l {
U I V i e w . s e tAn i ma t i o n T r a n s i t i on ( . f l i p F r omR i g h t ,
for : view , cache : true )
ye l l owViewCo n t r o l l e r . vi ew . f r ame
v i e w . f r ame
s w i t c h V i ewCon t r o l l e r ( f r om : Ы u e V i ewCon t r o l l e r ,
t o : ye l l ow V i e w C o n t r o l l e r )
else {
U I V i ew . s e tAn i ma t i o n T r a n s i t i on ( . f l i p F r omLe f t ,
f o r : v i e w , c a c h e : t ru e )
Ы u eVi ewCon t r o l l e r . v i e w . f r ame = v i e w . f r ame
s w i t c h V i e w C o n t r o l l e r ( f r om : ye l l owV i ewCont r o l l e r ,
t o : Ы ue V i ewCon t r o l l e r )
=
=
U I V i e w . comm i tAn ima t i o n s ( )
С ком п ил и руйте и вы пол н ите новы й вариант. Теперь при нажатии кнопки
Switch Views вместо м гновенной замен ы одного п редставления другим старое
представление будет переворачиваться и заменяться новым .
Для того чтобы сообщить системе iOS, что м ы хотим ани м ировать замену
представлений, необходимо объя вить блок анимации (animation Ыосk), испол ь­
зуя класс U IVi ew, и указать, как долго она должна продолжаться. Блоки анима­
ции объявля ются с помощью метода p r e s e ntVi ewCon t ro l l e r ( : anima t e d :
comp l e t i o n : ) из класса U IView:
U I V i e w . P r e s e n t V i ewCon t r o l l e r ( " V i e w F l i p " , c o n t e x t : n i l )
U I V i ew . s e tAnima t i o n Du r a t i on ( 0 . 4 )
Метод pre s entViewCont r o l l e r ( _ : a n imated : compl e t i on : ) получает два
параметра. Первы й из них представляет собой заголовок блока. Он испол ьзуется
244
ГЛАВА 6 � П Р И ЛОЖЕ Н И Я С Н ЕСКОЛ Ь К И М И П Р ЕДСТАВЛ Е Н И Я М И
тол ько в тех случаях, когда вы хотите непосредствен но испол ьзовать технологию
ан и мации Core Animation . Для наших целей достаточ но задать этот параметр
равн ы м n i l . Второй параметр - это указател ь, позволяющий задать объект
(ил и другой ти п данн ы х язы ка С ), указател ь которого м ы хотел и бы связать с
блоком анимаци и . В дан ном случае м ы испол ьзовал и значение n i l , поскол ьку
ничего такого делать не хотим . Кроме того, м ы задал и продолжител ьность , ани­
мации, которая указы вает классу U I Vi ew, как дол го, в секу ндах, должна про­
должаться анимаци я .
В закл ючение зададим к р и вую а н и м а ц и и (an i m ation curve), определя ющую
скорость анимаци и . По умол чанию анимация с л и ней ной кривой вы полняется за
постоя нное время . Мы выбрали вариант U IVi ewAn ima t i onCurve . Ea s e i nOut,
который означает, что ани мация должна начи наться медлен но, ускоряться в се­
редине, а в конце снова замедляться . Это делает анимацию более естественной
и менее механистичной.
U I V i e w . s e tAn ima t i onCu rve ( . e a s e i nOu t )
Далее нам необходимо указать вид перехода. Н а момент нап исания кн иги в
системе iOS существовал и пять видов перехода.
",, UIVi ewAnima t i onT ran s i t i on . f l ip FromLe ft
*
•\'
-�
,�i
U IVi ewAnima t i onT r ans i t i o n . f l ipFromRi ght
UIVi ewAnima t i onT r a ns i t i o n . c u r l Up
U IVi ewAn ima t i onT r ans i t i on . curl Down
UIVi ewAn ima t i onT ran s i t i on . none
Мы выбрал и два разных эффекта, соответствующих раз н ы м перекл ючаемым
представлен и я м . Лев ы й поворот для одного перекл ючен ия и правый поворот для
другого и м итируют ситуаци ю, когда представление будто опрокиды вается назад
и вперед. Значение U IViewAn ima t i onTran s i t i on . none соответствует резкому
переходу от одного контроллера представления к другому. Разумеется, есл и вас
устраивает резкий переход, то создавать блок анимации вообще не нужно.
Испол ьзован ие кеша ускоряет анимацию, поскол ьку в начале ан имаци и со­
здается его с н и мок, который испол ьзуется вместо прорисовки каждого этапа.
При испол ьзовании анимации всегда следует испол ьзовать кеш, за искл ючением
случаев, когда представление в ходе ан имаци и не изменяется.
U I V i e w . s e tAnima t i o n T r a n s i t i on ( . f l i p F romR i g h t ,
forView : view , cache : true )
Затем удалим текущее представление из представления контроллера, вместо
того чтобы добавлять другое представление.
Когда зако н ч и м в носить изменения, обеспеч и вающие ани мацию, вызовем
метод comm i tAn ima t i o n s ( ) из класса U I V i e w . Теперь все этап ы выпол не-
ГЛАВА 6 ·�� П Р И Л ОЖ Е Н И Я С Н ЕСКОЛ Ь К И М И П РЕДСТАВ Л ЕН И Я М И
245
ния приложения от запуска до в ызова метода commi tAn ima t i ons ( ) будут ани­
мирован ы .
Благодаря тому, что каркас испол ьзует технологию Саге Animation, м ы мо­
жем реал изовать скол ь угодно сложную анимацию с помощью небольшого ко­
личества строк в програм ме.
Р е з ю ме
Создав такое приложение с несколькими п редставления м и "с нуля", вы долж­
ны был и получить ясное п редставление о его устройстве. Нес мотря на то что
среда Xcode содержит шаблоны проектов для бол ь ш и нства типичных приложе­
н и й с несколькими представлениями, необходимо пони мать общую структуру
этих приложений, чтобы создавать их самостоятел ьно. Шаблонные контроллеры
(UI TabBarCont ro l l e r, UI Navi gat i o nCont ro l l e r и U I PageViewCont ro l l er)
очен ь экономят время, но иногда они просто не могут удовлетворить наш и по­
требности .
В следующих главах м ы продолжи м создавать приложения с нескол ь к и м и
представления м и . В частности, в главе 7 м ы создадим панель вкладок.
ГЛ АВА 7
•
П ан е л и в кл а до к
и сел е к т о р ы
В предыдущей главе вы создал и свое пер­
вое приложение с несколькими представле­
ния м и . В этой главе мы сконструируем пол­
ноценное приложение с панел ью вкладок с
пятью разл и ч н ы м и вкладкам и и п ятью раз­
личными представления м и содержимого. Со­
здание этого приложения призвано закрепить
материал, с которы м вы ознаком ил ись в гла­
ве 6. Мы вос пол ьзуемся эти м и пятью пред­
ставлен ия м и содержим ого для демонстра­
ции управляющего элемента с исте м ы iOS,
с которым вы еще не сталкивались. Это
п редставлен ие селектора (picker v iew) или
просто селектор (picker). Возможно, вам не
знакомо это назван ие, но вы почти наверня­
ка испол ьзовал и селектор, есл и работал и с
устройствами i Phone или i Pod более 1 О ми­
нут. Селекторы представля ют собой у п рав­
ляющий элемент с вращающейся ш калой .
Они испол ьзуются, нап ри мер, для ввода дат
в календаре ил и установки тай мера в часах
(рис. 7 . 1 ). В устройстве i Pad представление
селектора не стол ь рас пространено, так как
бол ь ш и й дисплей допускает другие, бол ее
удобные способы выбора среди нескол ьких
элементов, но даже там он испол ьзуется в
приложении Calendar.
••••• v.rtzOf\ Ltt.
Cancel
1э:11
Edit AJarm
20
" . t ••
Save
45
-
Repeat
LaЬel
д1 :1rm
Soo nd
Snooze
Delt>te Alorm
Рис. 7 . 1 . Сел е ктор в п р и ­
ложе н и и Clock
248
ГЛАВА 7 ,," П А Н ЕЛ И В КЛАДОК И СЕЛ ЕКТОРЫ
Селекторы nредставляют собой более сложные уnравл яющие элементы сис­
тем ы iOS, чем те, с которыми вы стал кивал ись до сих nop, и как таковые заслу­
жи вают немного бол ьше внимания . Селекторы могут быть настроены для отоб­
ражения одной ил и нескол ьких шкал . По умолчанию о н и вы водят текстовые
элементы, но могут быть настроены и для вы вода изображений.
П риложение Pickers
Приложение Pickers, создавае м ое в этой главе, будет оснащено nанелью
вкладок. При создании nриложения вы измените nанел ь вкладок, заданную no
умол чан ию, так что она будет содержать п ять вкл адок, добавите п и ктограм м ы к
каждому элементу панел и вкладок, а затем создадите ряд представлен ий содер­
жимого и подкл юч ите каждое из них к вкладке.
П редставления содержи мого прил ожения будут оснащены nятью селекторам и.
'"'' Селектор даты. Первое п редставление содержимого, которое м ы созда­
ди м , будет селектором даты, которое я вляется селектором nростейшего
типа с точ ки зрени я реализации (рис. 7.2). В nредставлении будет также
кно п ка, при н ажатии которой nоя вится сообщение о выбранной дате.
Carrlltf 9'
a:stPм
"'
IL
.,.
t.
Today
3
-
,.
38
РМ
р :--
Sf?lt-c:!
Рис . 7 . 2 . На первой в кл адке
распола гается сел е ктор даты
ГЛАВА 7 '!"! ПАНЕЛИ В КЛ АДОК И С ЕЛ Е КТОРЫ
249
Одноком понентны й селектор . Вторая вкладка оснащена селектором с
единственным списком значений (рис. 7.3). Реализация этого селектора тре­
бует немного больше работы, чем селектор даты. В ы узнаете, как указывать
значения, выводимые селектором, с помощью делегата и источника данн ых.
Leia
f,
Рис . 7 . З . Селектор в ы водит
еди н ствен н ы й с п и с о к з н ач е н и й
'':
М ногоком понентны й селектор. На третьей вкладке м ы собираемся создать
селектор с двумя отдельными колесами . Технический термин для каждого
из этих колес - ком понент селектора (picker component), так что, другими
словам и, здесь м ы создаем селектор с двумя компонентам и. В ы узнаете, как
испол ьзовать источн и к данных и делегат, чтобы обеспечить два независи­
мых списка данных для селектора (рис. 7.4). Каждый из ком понентов этого
селектора может быть изменен без воздействия на другой.
�·
С електор с завис и м ы м и ком понентами . В четвертом представлении со­
держи мого мы создадим еще оди н селектор с двумя ком понентам и . Но на
этот раз значение, отображаемое в п равом ком поненте, будет меняться в
зависимости от значения, выбранного в компоненте слева. В данном при­
мере мы собираемся отображать в левом ком поненте с п исок штатов, а в
правом - сп исок почтовых и ндексов выбранного штата (рис. 7 . 5 ) .
250
ГЛАВА 7 ii ПАН ЕЛ И В КЛАДОК И СЕЛЕКТОРЫ
N e w York
Nort ! , ( '" " ' "
1 0280
1
( ) ' ' i /i !
$1_1lcct
Рис. 7 .4. Двухко м п он е нтн ы й се ­
л е кто р , де м о н ст р и рующи й сооб ­
Рис. 7 . 5 . В этом сел е кторе оди н
к о м п о н е н т зависит от другого . П ри
ще н и е о сдел а н н о м в ы боре
в ы боре штата в левом ком поне нте
в п равом ком п о н е нте соответств у ­
ющи м об разом и з м е н я ется с п и сок
почтовых кодо в
�
П ользовательски й селектор с изо б ражен и я м и . С помощью пятого пред­
ставления содержимого м ы покажем, как добавить изображения в селек­
тор, и сделаем зто в виде небол ьшой игры, которая испол ьзует селектор с
пятью ком понентами . В нескол ьких местах в документации Apple селек­
тор о п исывается как аналог и грового автомата. Следовател ьно, его можно
испол ьзовать для создания маленького и грового автомата (рис. 7 .6). Здесь
пол ьзователь не может изменять вручную значения ком понентов, но будет
и меть возможность с помощью кнопки Spin заставить пять колес выбрать
новые, случайные значен и я . Есл и в строке окажутся три коп и и одного и
того же изображения, пользовател ь выиграет.
ГЛАВА 7 и ПАНЕЛИ В КЛАДОК И С Е Л Е КТОРЫ
251
WI N N E R !
Sp<n
Рис. 7 6
.
.
П ят ы й ком п о н е нт - селе к ­
тор , и м ити рующи й и гровой авто м ат
Д ел егаты и исто ч н ики д а н ных
П режде чем приступ ить к созданию приложения, посмотрим, что же делает
селекторы более сложны м и по сравнению с други м и элементам и управления,
которые вы испол ьзовал и до сих пор. За исключением селектора даты, невоз­
можно просто выбрать селектор в библиотеке объектов, перенести в п редстав­
ление содержимого и настроить. Кроме того, необходимо обеспечить каждый
селе ктор как делегатом селектора, так и и сточ н и ком дан н ы х .
Мы уже испол ьзовал и делегаты приложений ; их основная идея относится и к
селекторам . Селектор передает часть работы делегату. Наиболее важной я вляет­
ся задача определения того, что должно отображаться в каждой строке каждого
из ком понентов селектора. Селектор запраши вает у делегата строку либо пред­
ставление, которое будет показано в о пределенном месте дан ного компонента.
Селектор получает эти данные от делегатов.
252
ГЛАВА 7 оо ПАН ЕЛИ В КЛАД О К И С Е Л Е КТОРЫ
В дополнение к делегату селекторы должны и м еть источн и к данных. В этом
случае терм и н uсточиuк данных применен не совсем верно. Источ ник данных
говорит селектору, со с кол ь ки м и компонентам и о н будет работать и скол ько
строк в каждом из его ком понентов. Источн и к данных подобен делегату в том ,
что его методы вызываются в некоторые предопределенные моменты . Без источ­
ников данн ы х и делегатов селекторы не могут делать свою работу; фактически
они даже не могут быть нарисованы .
Достаточно расп ространенной я вляется ситуация, когда источ н и к дан ных и
делегат представля ют собой оди н и тот же объект, который хран ится в файл е
Swift; нередко этот объект я вляется контроллером представления, содержащего
селектор. И менно этот подход м ы испол ьзуем в дан ном приложен и и . Контрол­
леры представлен и й для каждой из панелей нашего приложен ия будут источ ни­
кам и данных и делегатам и для их селекторов.
ЗАМЕЧАНИЕ. Часто воз н и кает вопрос : является л и источ н и к дан ных селектора частью
модел и , п редставления или контролл ера? И сходя из терм и н а ис точник данных ка­
жется , что он должен быть частью модел и , но на самом деле это часть контроллера .
И сточн и ком данных обычно является не объект, сп роектирова н н ы й дл я хранения дан­
ных. В п ростых п риложениях источ н и к данных может хранить дан ны е, но истинная его
работа закл ючается в получении дан н ых из м одел и и их передаче селектору.
Создание п риложения Pickers
Несмотря на то что среда Xcode п редоставляет шаблон для приложений с
панел ью вкл адок, м ы собираемся создать н аше "с нуля". Это потребует не так
уж м ного дополнител ьной работы, зато это очен ь хорошая практи ка.
Создайте новый п роект, вновь выбрав шаблон S i n g le View Application, и щел к­
н ите на кнопке N ext на следующей стра н и це экрана. В ведите в поле P roduct
N a m e и м я P i c ke r s . Убедитесь, что флажок U se Саге Data сброшен, задайте
значение Language рав н ы м Swi ft и выберите в сп иске Devices пун кт U n iversa l .
С нова щел кните на кнопке N ext. П рограм ма Xcode предложит вам выбрать пап­
ку для хранения п роекта.
Мы собираемся провести вас через процесс создания всего приложения, но
есл и вы чувствуете в себе силы двигаться самостоятел ьно, сделайте это. Даже
оказавш ись в туп и ке, в ы всегда сможете вернуться .
Создание контроллеров представлени й
В п редыдущей главе м ы создал и корневой контроллер п редставления ( или,
для краткости, корневой контроллер) для управления процессом обмена пред­
ставлен и й приложен и я . М ы сделаем так же и на этот раз, но теперь м ы не
хотим создавать собствен н ы й класс корневого контроллера. Ком пан ия Apple
предоставляет очен ь хорош и й класс для у правления представления м и панел и
ГЛАВА 7 "' П А Н ЕЛ И В КЛАДОК И СЕЛЕКТОРЫ
253
вкладок, так что мы просто воспол ьзуемся экземпляром U I T abBarContro l l e r
в качестве корневого контроллера. С начала нам надо создать пять новых клас­
сов в среде Xcode
пять контроллеров представления, которые будут пере­
ключать корневой контроллер. Раскройте папку P i c ke r s в навигаторе проекта.
Здесь отображаются исходные файл ы, созданные программой Xcode для вашего
проекта. Щел кните на папке P i c ke r s и нажм ите комби нацию клавиш < 3€ +N>
или вы пол н ите команду Filec:> Newc:> File . " .
Выберите на левой панел и помощни ка по создани ю нового файла пункты IOS
и Source, затем выберите п и ктограм му Сосоа Touch Class и щел кн ите на кнопке
Next. На следующей стран и це экрана можно задать имя нового класса. Введите
в поле Class строку Date P i c ke rVi ewCont ro l l e r . Поле Subclass of должно со­
держать имя UIViewCont ro l l e r . Сбросьте флажок Also create X I B file, устано­
вите значение атрибута Language рав н ы м Swi f t и щел кните на кноп ке Next.
В заключение на э кране откроется окно, в котором можно выбрать папку
для хранения классов. Выберите папку P i c ke r s , которая уже содержит класс
App De l e g a t e и нескол ько других файлов. В ы берите также папку P i c ke r s
в списке Group и установите целевой флажок для п роекта P i c ke r s . Пос­
ле того как вы щел кнете на кноп ке C reate, в пап ке P i c ke r s появится файл
Da t a P i c ke rVi ewCont r o l l e r . swi f t .
Повторите эти шаги еще четыре раза, испол ьзуя имена S i n g l e Component
P i c kerViewCon t ro l l e r, DouЬ l e C ompone n t P i c ke rVi ewC ont ro l l e r, Depen
dentCompo n e n t P i c ke rVi ewC o n t r o l l e r и C u s t om P i c ke rVi ewCon t r o l l e r
(рис . 7.7). После щелч ка н а кнопке C reate в пап ке P i c ke r s появятся новые
файл ы .
-
"
"
Pk:kers
Plckers
AppDelegate.swlft
� VleWControtler.sw!ft
�
� DatePlckerViewController.aw!ft
� SlngJeCompone".ControJler.swllt
�. DouЫeCompon."wContrOller. swlft
"' OependentCom".Controtler.swtft
•
M1ln.storyЬoard
Alaetl.iц:assets
"'
LlunchScreen.storyЬoard
tnfo.pllJt
J Products
Рис . 7 . 7 . П осл е созда н и я пяти кл ассов контроллеров
п р едста вл е н и й окно н а в и гато ра п р о е кта дол ж н о со­
держать все эти фа йлы
254
ГЛАВА 7 111! ПАНЕЛИ В КЛАДОК И СЕЛЕ КТО Р Ы
Со эдание контроллера представления панели вкладок
М ы собираемся создать контроллер представления панел и вкладок. Шаблон
проекта уже содержит контроллер представления Vi ewControl l e r, который яв­
ляется подклассом класса UIViewCon t ro l l e r . Для того чтобы превратить его в
контроллер панел и вкладок, необходимо изменить его базовый класс. Откройте
файл Vi ewCont r o l l e r . swi ft и вставьте в него строку, выделенную ниже по­
лужирн ы м шрифтом .
class ViewController : UI TaЬBarController {
Теперь необходимо настроить контроллер панел и вкладок в рас кадровке,
поэтому откройте файл Ma i n . s t o ryboa r d . Ш аблон уже содержит начальный
контроллер представления, которы й мы должны замен ить, поэтому выберите
его в окне Document Outl i n e ил и в области редактирования и удал ите его, нажав
клавишу <Delete>. Найдите в библиотеке объектов элемент ТаЬ Ваг Contгolleг и
перетащите его в область редактирован ия (рис. 7 . 8 ) .
11;1 (
f'lcWI
) - �;
• C! !tмt t SO...
" ••:i
(Jтep
� Ol.l!Ot
8otfOlf! LtyO\lt OUlc!e
.;:
�'----"""""'"-'-=:=< -""'==-==
· "'""� l to111rutotyЬoм1 ia-) ll 1ttм 2 S-. 1 \°1 11-'1 J
!
J«•
[] . ·-
. .... ,
8 Ar1t Aн�
. ...
" "'"",
•J1W�� �
""' 8o!;1Qm l� Gllolo.
."
"' "" '
• nrм -.�·
11 ".
,
. ,.� ...
8 Rn1 1!н�
. ...
! '
� ·'tlitw controllin" lil "-
-- --� � ·-
1
1 '
1
'
1 1
1 1
1
1
1 1
1
Рис. 7 8
.
.
таь Sгr Controller
1 '
1 !
•
/-)
j
-
•
j
<
> 1
1
D Ф 8 <
r-,,
•
!1 t,; . ,
� .,."
D
о <
.... ... .....
-�··
lhlt .....,.ММ IW
тм .., . "'_
dhitlafirlf • 18ll l
• ··· lfle -
Перетаски ва н и е объекта ТаЬ Ваг Contгolleг из б и бл и отеки в область
редакти рова н и я
В ы у видите, что, в отличие от других контроллеров, которые м ы ранее пе­
ретаскивали из библиотеки объектов, при перетаскивании объекта ТаЬ Ваг Con­
troller одновременно будут перемещаться три пары "представление-контроллер",
связанные между собой изогнуты м и л и н и я м и . На самом деле это больше чем
ГЛАВА 7 '!!' ПАН ЕЛ И В КЛАДОК И СЕЛ ЕКТО Р Ы
255
обы ч н ы й контроллер панел и вкл адок; у него есть два дочерних контроллера,
уже связан н ы х между собой и готовых к испол ьзованию.
После размещения контроллера панели в кладок в области редактировани я
в раскадровке поя вятся т р и н о в ы е сце н ы . Откры в о к н о структуры докумен­
та в левой части экрана, вы увидите подроб н ы й обзор сцен, содержащихся в
раскадровке (рис. 7 .8). В ы увидите, что изогнутые л и н и и по-прежнему связы­
вают контроллер панел и вкл адки с его дочерн и м и п редставлениям и . Эти ли­
н и и всегда автомати чески настраи ваются при перемеще н и и сце н . П оложение
каждой сцены в рас кадровке не вл ияет на внеш н и й вид приложения в ходе его
работы .
Этот контроллер панел и вкладок будет наш и м корневым контроллером . На­
помним, что корневой контроллер - это самое первое п редставление, которое
видит пользовател ь, запустив приложение. Он отвечает за перекл ючение других
представлен и й . Поскол ьку мы будем связы вать эти представления с кнопками
панел и вкладок, логично выбрать в качестве корневого и менно контроллер па­
нел и вкладок. Нам необходимо сообщить системе iOS, что контроллер панели
вкладок необходимо загружать из файла Ma i n . s t o rybo a r d при запуске при­
ложения. Для этого выберите п и ктограмму Та Ь Ваг Controller в окне Docu ment
Outl ine и откройте окно и нспектора атрибутов . Затем установите флажок l s l n i­
tial View Contro l l e r в разделе View Contro l l er. В ыдел и в контроллер представле­
ния, перейдите в окно и нспектора идентичности и измените значение C lass на
ViewCont ro l l e r .
Н а панел и вкладок для представления каждой вкл адки испол ьзуются п и к­
тограм м ы , поэтому мы должн ы также добавить п и ктограм м ы , которые будем
испол ьзовать, до того, как присту п и м к редактировани ю раскадровки дл я это­
го класса. Подходя щие п и ктограм м ы можно найти в архиве проектов в папке
07
Image Sets в архиве исходных кодов. Каждая папка в папке 0 7 ImageSets
содержит три изображения (одно для устройств со стандартны м экраном и два
для устройств с экраном Retina). В окне навигатора п роекта выберите пап ку
As se t s . xcas s e t s , уже содержащи й стандартное изображение для п и ктограм­
мы и заставки . Перетащите все пап ки из папки 0 7
Image S e t s в левый стол­
бец области редактирования под п и ктограм му Applcon и скопируйте их в свой
проект (рис. 7.9).
Есл и вы хотите создать свою пиктограмму, то должны придерживаться опре­
деленных правил . Используемые п и ктограм м ы должны иметь размер 24 х 24 п и к­
селя и' храниться в формате . png. П и ктограм м ы должн ы иметь прозрач н ы й фон .
Не беспоко йтесь о том , как именно п и ктогра м м ы будут в ыведены на панел и
вкладок. Так же, как и в случае знач ков приложения, i O S самостоятел ьно сде­
лает все необходимые преобразован ия для того, чтобы пиктограм ма в ы глядела
корректно.
-
-
-
256
r 88 (
•
ГЛАВА 7 ;jl\ ПАНЕЛИ В КЛАДОК И С ЕЛ Е КТОРЫ
Plckert )
Applcon
Pickert ) " AIИlt.XCISSOil
.!_ tppl8
•
1х
,,
.;
,,
• •
2х
2х
4 4
2х
З•
�
"
�
Univ•rul
c1oclde\llt
�
,,
Зх
2х
Unlverиt
3,
Рис . 7 . 9 . В ыдел е н и е и з об раже н и й , распол оже н н ых н и же п и ктогра м м ы
Applcon в каталоге As s e t s . x ca s s e t s в с реде Xcode
ЗАМЕЧАНИЕ. Раз м е р изображе н и я 2 4 х 2 4 п и ксел я п редназначен для обычных дис ­
плеев; дл я дисплеев Retiпa н а устройствах i Phone 4 и более поздних верси й , а так­
же для н ового устройства i Pad нуж н ы изображения вдвое большего размера , и наче
они будут выгл ядеть мозаи ч н о . Для устройства iPhone 6/бs необходимо изображе ­
н и е , которое в три раза бол ьше оригинал а . Это очень легко : л юбому изображению
foo . png сопутствует изображение f o o @ 2 x . png , имеющее вдвое больший размер,
а также изображение fоо @ З х . p n g , имеющее втрое больший размер. И н струкция
U I Image ( n amed : " f о о " ) вернет изображение нормал ьного или двойного размера,
наилуч ш и м образом подходя щее для текущего п риложен и я , вы пол н яемого на уст­
ройстве .
Вернемся к раскадров ке . Как в идите, кажд ы й из дочерних контроллеров
представления имеет имя вроде " l te m 1" в верхней части представления и одну
панел ь в н ижней части, а также п росrую метку, соответствующую н азван ию
ГЛАВА 7
ПАНЕЛ И В КЛАДОК И СЕЛ ЕКТОРЫ
257
вкладки . Эти и мена можно выбрать точ нее, поэтому выберите контроллер пред­
ставления ltem 1 , а затем щел кн ите на вкладке в н ижней части представления
ил и в окне Document Outline. Откройте окно и нспектора атрибутов, и вы увидите
текст для настройки атрибута Title элемента Ваг ltem, которы й в данн ы й момент
представляет собой строку ltem 1 . Замените этот текст строкой Da te и нажм ите
клавишу <Return>. В резул ьтате текст вкл адки в н ижней части представления
и в контроллере панел и вкл адок немедленно изменится. Оставаясь в окне инс­
пектора атрибутов, щел кните на вспл ы вающем меню l mage и выберите пункт
clockicon. Повторите все предыдущие этап ы для второго контроллера представ­
ления, назвав его Single и испол ь·ю вав изображение singleicon дл я вкл адки .
Теперь мы должны закончить контроллер панел и с пятью вкладками (рис. 7.2).
Каждая из этих пяти вкладок соответствует одному из селекгоров. М ы сделаем
зто, просто добавив в раскадровку еще три контроллера представления (в допол­
нение к двум контроллерам, которые м ы добавил и вместе с контроллером панел и
вкладок) и соеди н и в их между собой, чтобы контроллер панел и вкладок м о г и х
акти визировать. Для начала перетащите обы ч н ы й элемент View Controller из биб­
л иотеки объектов на раскадровку. Затем нажм ите клавишу <Control>, перетащите
указател ь от контроллера панел и вкладок к новому контроллеру представления,
отпустите кноп ку мыши и выберите контроллер представления из раздела Rela­
tionship Segue в маленьком вспл ывающем меню. Тем сам ы м мы сообщаем кон­
троллеру панел и вкладок о том, что у него появился новый дочерний класс, по­
этому панел ь вкладок немедленно запросит новый элемент, а новый контроллер
представления получит элемент вкладки в н ижней части своего представления,
как и все остал ьные. То же самое необходи мо сделать для последнего контрол­
лера представления с заголовком DouЫe и изображением douЫeicon.
Перетащите еще два контроллера п редставления и соедин ите их с контрол­
лером панел и вкладок, как оп исано в ы ше. В ы берите по очереди каждую из их
вкладок, наз вав одну из них Dependent с изображением dependenticon, а другую
Custom - с изображением toolicon . П осле этого у вас должен поя в иться оди н
контроллер с вашей панел ью и нструментов и пятью связанн ы м и оди н с другим
контроллерами представления, как показано на рис. 7. 1 О.
Теперь задади м дл я каждого контроллера п редставления соответствующи й
класс контроллера. Это позвол ит обес печ ить фун кционал ь н ы е возможности
для каждого из этих п редставлен и й . В ы берите контроллер представления Date
в окне Document Outline и откройте окно инспектора идентич ности . В разделе
CustQm Class измен ите имя класса на Date P i c ke rVi ewCont ro l l e r и нажм ите
клавишу <Return> ил и <ТаЬ>, чтобы подтвердить изменен ия (рис. 7. 1 1 ).
Повторите этот же процесс для следующих четырех контроллеров представ­
лений. В и нспекторе атрибутов убедитесь в корректности установки флажков для
каждого из них и в ведите имена S i n g l eC omponen t P i c ke rVi ewC on t ro l l e r,
DouЫ eComponent P i c ke rVi ewCont ro l l e r, Depende ntComponent P i c ke rView
C o n t r o l l e r и C u s t om P i c ke rVi e w C o n t r o l l e r соответственно. Сохран ите
файл раскадровки .
ГЛАВА 7 !ii!i ПАН ЕЛ И В КЛАДОК И С ЕЛ Е КТОРЫ
258
lf! <
11 V\ew Controller S<:tne
а ....... ,
,
8 F1t1t RtsJ)Ol'l(tef
. ."
• 81ngle
J lttm ) * Cuttom
j VJeW
"""""
8 Rrtt Rttpandef
. ."
... 11 DelМAdtl'lt kent
.
·-
·-
-�8ottom Lll)'OUt O\>lde
Т09 L8yctVt Ouldt
ll"•w
ft O.P4"1dent
• FIA:I �IPoNNt
ll E•ll
• ll oouoм �
.
,...,
1
. ,ltt1. R11ponde1
fil Ex1t
* OouЬll
•
l! Dltt le.n.
•
Dltt
Too Ll)'OVI O�
J sottcмn L8'(0Ut Ould8
"''"
'/t Dlte
e F1rs1 R11pOfldtf
•
1В ь11
1:1 V18w Controll... Sоем
CJ
1I µ
1
1 [)
-
25"
+
О
@ D
ltory8oatll Jlel'� . �· 1
cit� b 1 vlew con1row.r -. .,.
••lefnt/lklryЬoatd.
Ttlitte Ylew Convot• · А
llO/!Uflllff m.t � · i-. ..........
о
Рис. 7 . 1 0 . Добавл е н и е пяти ко нтролл еров представл е н и й , доступ к кото р ы м
обеспечи вает панель и н струм е нтов и з корневого ко нтролл ера предста вл е н и я
" ".._
8 F1r11 �цмinder
. ".
• eJ �t lk.-r!I
. """
r...li тop 1...-,ov1 0uld1
[' вettomUyout Oum
а-
D •
8 Flttt AtaponOtr
.. "
•
* 0.P8ndent
•
ll OouDN SC­
• (') -
Т09 Ll�I (Mdo
f! Вottom La'(ou1 Ou4<St
"••
•
vi.w
• "°""''
. .... ..._
. ."
' U.. О."'*6 llhmtt.. Attr"""'t_;
1 К.., PtrJI
�Р8
VtИ
г)
i
1
С! Dltt SO.nt
·�°'"'
f'Ч TQP Ll";'IМ Ouid8
� ВOttom Layau1 Ouloe
(.� vi.w
1
t+
1_
!
,".
..
"
�tlO t41t·Rl·n&O
Lott IМ«lttd • (НOtttlntl
а
Not"8 • • • • ·-_0 111 .
cr; :
Г\
r 1
�
n
Рис . 7 . 1 1 . С в я з ы в а н и е представл е н и я Date с е го контролле ром
Первичный т ест на симуля торе
В данн ы й момент панел и в кл адок и предста вления содержимого должн ы
быть работоспособ н ы м и . Вернитесь в Xcode, выпол н ите ком п иляцию и запуск,
ГЛАВА 7 !!!i ПАНЕЛИ В КЛАДОК И С ЕЛ ЕКТО Р Ы
259
и ваше приложение должно заработать, вы ведя панел ь фун кцион и рующих вкла­
док (рис. 7. 1 2). Щел кн ите по очереди на каждой из вкладок. Каждая из них
должна реагировать на в ыбор .
...
""'
·-
IPhone 6s - IOS 10.О (14д5i6tu)
2о27 РМ
Cerrler •
1
2
.... '
""'
1
"'"
Рис. 7 1 2
.
.
-
(;....-...;-')•
, ".
2
П р иложе н и е с п ятью пусты м и , н о
работоспособн ы м и в кладка м и
В представлениях содержимого в настоящий момент пусто. Но есл и все про­
шло нормал ьно, то базовый каркас п риложения с нескольки м и представления м и
настроен и работает, и м ы можем приступить к разработке отдельных представ­
лений содержимого.
260
ГЛАВА 7 \t ПАН ЕЛ И В КЛАДОК И С Е Л Е КТОРЫ
ПОДСКАЗКА. Есл и после щелчка на одной из вкладок ваш си мулятор даст сбо й , то ,
скорее всего , вы либо п ро пустил и какой -то шаг, л и бо сделали опечатку. Вернитесь
назад и убедитесь в корректности всех соеди нений и правильности ввода всех имен
классов .
Есл и хотите дважды убедиться, что все работает, добавьте другие метк,и ил и
некоторые другие объекты к каждому п редставлен и ю содержи мого и вновь за­
пустите приложение. При этом в ы должн ы ув идеть измен и вшееся содержимое
представлени й при селекторе разных вкладок.
Реализация селектора даты
Для реал изации селектора даты нам требуются один выход и одно действие.
Выход будет испол ьзован для получения значения от селектора даты. Действие
будет запускаться кнопкой и вы водить сообщение о выбран ной дате. Мы созда­
дим выход и действие с помощью програм м ы I nterface B u i l der, поэтому выбе­
рите файл Ma i n . s t o ryboa rd в окне нави гатора п роекта.
Найдите в библиотеке объектов элемент Date Pi cker и перетащите его в об­
ласть редактирован и я на с цену Date Sce n e . Щел кн ите на п и ктограм ме Date в
окне Document Outli ne, чтобы требуем ы й контроллер представления оказался на
переднем плане, затем перетащите селектор даты из библ иотеки объектов в вер­
хнюю часть представления, вплотную к верхнему краю. Он может перекры вать
строку состоя ния, потому что этот элемент у правления содержит вертикальные
запол н ител и .
Теперь применим ограничения Auto Layout, чтобы селектор даты правил ьно
отображался на экране л юбого устройства. Мы хотим, чтобы селектор даты на­
ходился в центре представления по горизонтал и и был прикреплен к его верхне­
му краю. Мы также хотим, чтобы его размер соответствовал его содержимому.
Следовател ьно, нам нужны три ограничен и я . В ыдел и в селектор даты, выберите
команду Ed itorq Size to Fit в меню Xcode. Есл и эта команда заблокирована, то
щел кн ите на кнопке A l i g n в н ижней части раскадровки, установите флажок Hori­
zoпta l ly i n Container, а затем щелкн ите на кнопке Add 1 Co nstraint. Щел кн ите на
кноп ке Pin (следующей за кнопкой Align). Испол ьзуя четыре поля редактирован ия
в верхней части всплы вающего меню, задайте расстоя ние от селектора до вер­
хнего края п редставления рав н ы м нул ю, а затем щел кн ите на красной пунктир­
ной л и н и и под ним, чтобы она стала сплошной. В н ижней части вспл ы вающего
окна установите значен ие U pdate F ra mes рав н ы м I t ems o f New Cons t ra i n t s
и щел кните на кнопке Add 1 Constra i n t . Размер селектора даты изменится , а сам
он переместится на правил ьную позици ю (рис. 7 . 1 3 ) .
Щел кн ите на селекторе даты, есл и он еще не выбран, и верн итесь к и н ­
спектору атрибутов . Как показано на рис. 7 . 1 4, имеется ряд атрибутов, которые
можно настроить для селектора даты . Мы оставим для бол ьш инства атрибутов
их значения по умолчанию (но не бойтесь экспери ментировать со значениями
ГЛАВА 7 :,-:; ПА НЕЛ И В КЛАДО К И СЕЛ ЕКТО Р Ы
26 1
no окончан ии работы над nриложен ием, чтобы увидеть, что они делают). Един­
ствен ное, что м ы сделаем, - это ограничим диаnазон селектора разу м н ы м и сро­
кам и . Взглян ите на заголовок Constra i nts и установите флажок M i n i m u m Date, ос­
тави в значение no умолчан и ю 1 /1 / 1 970. Установите также флажок Maxi m u m Date
и значение 1 2/3 1 /2200.
зin.storyЬoard (Ввsв) ) !�И D<lte Scene )
Oate ) U View ) - • Oate Picker
•
Tlm J u l �>
Wed Jul 6
Q
Today
F r i JtJI 8
S<it J<il 9
6
7
8
9
о
Q
•
49
50
51
52
53
АМ о
РМ
Q
1
Se ct
о"
]
75%
View as: iPhone 6s (wC hR)
]Ооооо Оо
O<ientвtion
+
Рис . 7 . 1 3 . Селектор даты , расположе н н ы й в верхней ч асти п редставл е н и я
262
ГЛАВА 7 й ПАНЕЛИ В КЛАДОК И СЕЛ Е КТОР Ы
------·-
Oate Plcker
моеsе .
oate,��d 1!�
__
Locale Def�I!._.
_8
�
1nterva1 :,•.1�� _____
Date
Current Date _ __
Constralnts [l Mlnlmum Oate
- -·
-
1/ 1 / 1 970.
В
_8
-·r••_____._
•
6:00:00 АМ
�
8 Maxlmum Oate
t2131/2200, 6:00:00 АМ �
--
Timer
___ _ _ _ .__
i Couiit Down 1n Seconcss О : �1
_,__"___
_____
_
_
_
_
__
Рис . 7 . 1 4. И н с п е ктор атри бутов для селе ктора даты , М ы
уста н а вл и ваем м и н и м ал ьную и м а кс и м ал ьную даты , ос­
тавл я я дл я других атри буто в знач е н и я по умолчан и ю
Теперь свяжем этот селектор с его контроллером . Н ажм ите комбинацию кла­
виш <Option+X + Enter>, чтобы открыть окно помощн и ка редактора, и устано­
вите панел ь быстрого перехода в верхней части в режим Automatic. В резул ь­
тате откроется файл D a t e P i c k e rVi ewCont ro l l e r . swi f t . Нажм ите клавишу
<Control> и перетащите у казатель от селектора к пустой строке между объя вле­
н ием класса и м етодом v i ewDidLoad ( ) и отпустите кнопку м ы ш и , когда поя­
вится подсказка l nsert Outlet, Action ил и Outlet Col lecti o n . В появи вшемся вспл ы­
вающем окне установите значение C o n n ection рав н ы м Out l e t, введите в поле
Name строку da te P i c ke r, а затем н ажмите клавишу <Retum>, чтобы создать
выход и соединить его с селектором .
Захватите элемент B utton в библ иотеке и поместите его нем ного н иже селек­
тора даты . Дважды щел кн ите на кнопке и н азовите ее Select. Мы хотим, чтобы
эта кнопка находилась в центре представления по горизонтал и и на фиксирован­
ном расстоя н и и под селектором даты . Выбрав эту кнопку, еще раз щел кните на
кнопке Al i g n , расположенной в н ижней части раскадровки, установите флажок
Horizontally in Container и щелкните на кно п ке Add 1 Constraint. Для того чтобы
задать правильное расстоя ние м ежду кно п кой и селектором даты, перетащите
кнопку на селектор даты, нажав клавишу <Contro l>, и отпустите кнопку м ы ш и .
В поя в и вшемся м е н ю вы пол ните команду Vertical S paci n g . В закл ючение, щелк­
н ите на кноп ке Resolve Auto Layout l ssues в н ижней части раскадровки, а затем
на кнопке U pdate F ra mes в верхней части вспл ы вающего окна (есл и этот эле­
мент недоступен, значит, ваша кнопка уже находится в правил ьной позиции).
ГЛАВА 7 '"' ПАНЕЛИ В КЛАДО К И С ЕЛ ЕКТО Р Ы
263
Кнопка должна переместиться в правильную позицию, и п редупреждения Auto
Layout бол ьше поя вл яться не должн ы .
Убедитесь, что файл Da t e P i c ke rVi ewCoЬt ro l l e r . swi f t по-прежнему ос­
тается види м ы м в окне помощн и ка редактора; есл и это не так, перейдите на
панел ь быстрого перехода и с помощью элемента M a n u a l найдите и откройте
этот файл . Нажм ите клавишу <Control> и перетаски вайте указател ь от кнопки
к строке над закры вающей фигурной скобкой в кон це класса в окне помощ­
ни ка, пока не увидите подсказку l n sert O u tlet, Action и Outlet Col lecti o n . Изме­
н ите значение C o n n ection type на Ac t i o n, присвойте новому действию и м я
onBbut t o n P re s s ed и нажм ите клавишу <Return>. В резул ьтате возн икнет пус­
той метод onBut t o n P re s s e d ( ) , котор ы й необходимо запол н ить кодом, пред­
ставлен н ы м в листи н ге 7. 1 .
Л истинг 7 . 1 . Код действия при выборе кнопки
@ I BAc t i o n func o n Bu t t o n P re s s e d ( s e n de r : U I Bu t t o n )
l e t da t e
d a t e P i c ke r . da t e
l e t me s s age
" T h e d a t e a n d t ime y o u s e l e c t e d i s \ ( d a t e ) "
let alert
U I Al e r t C o n t r o l l e r (
t i t l e : " Da t e and T i me S e l e c t e d " ,
me s s a g e : me s s a g e ,
p r e f e r redS t y l e : . a l e r t )
let action
U I A l e r tAc t i on (
t i t l e : " That ' s so true ! " ,
s t y l e : . de f a u l t ,
hand l e r : n i l )
a l e r t . addAc t i o n ( a c t i on )
p r e s e n t ( a l e r t , a n ima t e d : t r u e , c omp l e t i o n : n i l )
=
=
=
=
В методе viewDi dLoad ( ) м ы создаем новый объект класса N S Da t e . Создан­
ный таким образом объект N S Da t e содержит текущие дату и время. Затем м ы
передаем эту дату для date P i c ke r, что гарантирует, что всякий раз п р и загруз­
ке представления из раскадровки селектор будет сбрас ываться к текущим дате
и времени (л исти нг 7.2).
Л истинг 7 . 2 . Н астройка даты в методе viewDidLoad ( )
ove r r i de f u n c v i e w D i dLoad ( )
s upe r . vi e w D i d L o a d ( )
'
/ / дополнител ь н а я н а с тр о й к а п о с л е з а гру з ки пре д с т а в л е ни я .
let date
N S Da t e ( )
d a t e P i c ke r . s e t Da t e ( da t e a s Da t e , a n im a t e d : f a l s e )
=
Вот и все. Теперь создадим и запустим приложение, чтобы убедиться, что
селектор даты работает правил ьно. Есл и все получилось как надо, ваше прило­
жение при работе должно в ы глядеть так, как показано на рис. 7.2. При выборе
кнопки Select поя вится предупрежден ие с выбранн ы м и датой и временем .
264
ГЛАВА 7 r,, П А Н Е Л И В КЛАДОК И С Е Л Е КТОРЫ
ЗАМЕЧАНИЕ. Селектор даты не позволяет указать секунды или часовой пояс . П редуп ­
реждение же отображает время с секунда м и и по Гри н вичу (GMT). М ы могл и бы до­
бавить код дл я упроще н и я отображаемой строки , но не сл и ш ком ли бол ьшой станет
наша и так немаленькая глава? Есл и вас и нтересует форматирование даты , обрати ­
тесь к классу N S Da t e Forma t t e r .
Р е али з ация од ноко м понентного селе ктора
Наш следующи й селектор позволяет пол ьзовател ю выбирать значение из
списка. В этом при мере мы создадим м асси в для хранения значений, которые
будут вы водиться селектором . С електор ы сами по себе не хранят н и каких дан­
н ых. Вместо этого для п олучения вы води м ы х дан н ы х о н и вызы вают методы
своего источ н и ка дан н ы х и делегат. Селектору совсем не и нтересно, где и в
каком виде хранятся испол ьзуемые и м дан н ы е . Он запраш и вает дан ные тогда,
когда они ему нужны, и источн и к данн ых, и делегат ( которые на практи ке час­
то представля ют собой оди н и тот же объект) вместе п редоставля ют ему эти
дан н ы е. В резул ьтате дан н ы е могут поступать, в частности, из статического
с п иска. Дан н ые м о гут быть также счита н ы из файла или U R L и даже выч ис­
ляться "на лету".
Для того чтобы класс селектора запраш и вал дан ные у контроллера, необхо­
димо, чтобы в контроллере были реал изован ы соответствующие методы . Для
этого нужно объя в ить в определении класса контроллера, что он будет реал и­
зовы вать ряд протоколов. Перейдите в окно навигатора проекта и щел кните на
файле S i ng l eComponent P i c ke rVi ewCont ro l l e r . swi f t . Наш класс контрол­
лера будет действовать и как источ н и к данн ых, и как делегат селектора, поэтому
он должен поддерживать оба протокола для этих ролей . Добавьте в програм му
следующий код:
c l a s s S i n g l e C omp o n e n t P i c ke r V i e w C on t r o l l e r : U I V i e wCo n t r o l l e r ,
U I P i c k e rV i e w De l e g a t e , U I P i c ke r V i e w Da t a S o u r ce {
После этого в ы увидите в окне редактирования сообщение об ош ибке. Это
объясняется тем , что м ы пока не реал изовал и требуем ые методы протокола.
Вскоре мы это сделаем, поэтому пока эти сообщения можно и гнорировать.
Создание представления
Выберите файл Ma i n . s t oryboa rd, чтобы отредактировать представление со­
держимого на второй вкладке на панел и вкладок. Перейдите в окно Document
Outl ine и щел кн ите на п и ктограмме Single, чтобы контроллер п редставления
вышел на перед н и й план области редактирован и я . Перетащите из библ иотеки
объект Picker View (рис. 7 . 1 5 ) и добавьте его в верхнюю часть вашего представ­
ления, как вы это делали с представлением селектора даты .
ГЛАВА 7 'i{ ПА НЕЛ И В КЛ АДОК И С Е Л Е КТО Р Ы
265
-
Suп11yv<il<o
Cupertino
Santэ C!.=n.:i
а
Рис . 7 1 5
.
.
П еретащите объект Picker View
и з б и бл и оте ки на второе п редставл е н и е
Селектор должен быть отцентрован по горизонтал и и прикреплен к верхнему
краю сцен ы . Для этого можно задать для селектора те же самые ограничения
A uto Layollt, которые были добавле ны в приложение Date P icker в предыду­
щем при мере. Кроме того, мы хотим, чтобы размер селектора соответствовал
его содержанию, поэтому нам нужны три огран ичен и я . Выдел ив селектор даты,
выберите команду Editorc> Size to Fit в меню Xcode. Есл и эта команда заблоки­
рована, то щел кн ите на кноп ке Align в н ижней части раскадровки, установите
флажок Horizontally in Container, а затем щел кн ите на кно п ке Add 1 Constraint.
Щел кн ите на кнопке Pin (следующей за кнопкой Align). Испол ьзуя четыре поля
редактирования в верхней части вспл ы вающего м е н ю, задайте расстоя ние от
селектора до верхнего края представления рав н ы м нулю, а затем щелкн ите на
красной пунктирной л и н и и под ним , чтобы она стала сплошной. В н ижней час­
ти вспл ы вающего окна установите значение U pdate Frames равн ы м I t ems o f
New Co n s t r a i n t s и щел кн ите на кнопке Add 1 Constraint. Размер селектора
даты изме н ится, а сам он переместится на п равил ьную позицию (рис. 7 . 1 6).
Теперь соеди н и м селектор с контроллером . Эта п роцедура напом инает п ре­
дыдущую: откройте окно помощни ка редактора и настройте панель быстрых
переходов на демонстраци ю файла с расширением S i n g l eComponent P i c ke rV
iewCont ro l l e r . swi f t . Нажм ите клавишу <Control>, перетащите указатель от
селектора к верхней части класса S i n g l eCompone nt P i c ke rVi ewCont ro l l e r и
создайте выход s i ng l e P i c ke r .
Далее, выбрав селектор, нажм ите комби нацию клавиш <Opt ion+:t€ +6>, что­
бы вызвать инспектор связе й . Есл и вы посмотрите на связи, доступные пред­
ставлению селектора, то увидите, что перв ы м и двумя элементам и я вл я ются
dataS ource и de legate. Есл и вы их не видите, проверьте, выбран ли селектор!
Нажмите клавишу <Control> и перетащите указатель от кружка, расположенного
рядом с элементом d a t a S ource, к п и ктограмме View Controller в верхней части
сцены раскадровки или панел и Document Outline (рис. 7 . 1 7), а затем еще раз - от
кружка, расположенного рядом с элементом de legate, к п и ктограмме View Con­
troller. Теперь данн ы й селектор знает, что э кзе м пляр класса S in g l eComponent
266
ГЛАВА 7 t« ПАН ЕЛ И В КЛАДОК И СЕЛЕКТОРЫ
P i c ke rVi ewCont r o l l e r в раскадровке я вляется его источ н и ком дан ных и де­
легатом, и будет запраш и вать у него вы води мые данные. И наче говоря, когда
селектору потребуется информация о в ы води мых данн ы х, он запросит ее у эк­
зем пля ра S i ng l eCompo nent P i c ke rVi ewCont ro l l e r, которы й управляет этим
представлением для данной и нформации .
•
с: �Лl
yv-:.slP
Cup rtino
Sanr Clara
о
.... tr
J,
о
f
о
о
Рис. 7 . 1 6 . Селекто р , расположе н н ы й
в верхней ч асти п редставл е н и я
.
.
.
"
.
. ,,_._.
-
·-
. �.....,"
· -­
· � �.....
· -­
- �...... ....
" Q;a • .., Окмi4 ..,..
·
�
�� . .... ... """'
-­
UWlllllМ•••.......
-
"' " 4>) *"• Wlcl 7•11 AМ Мolf�
{, . ... l
Q 1К.
- �1
" " ...... ....
•
,. , ....... о­
'"
___
....... ...,.,.
-­
" .с-..,.
. ....
. �... ._.._
1:<4
• Cl c.... "­
о
-
D • •
•
о
CuJ)eftlno
• CI -.... *­
• 13 0..- a.­
" tl o... -.-
. ...
- �" а.·-
ООооос ol
(J ..... "' ,,.,..,. " ' с �
1
--
"'
'
""- °"'*811W • - ­
-·-
Рис . 7 . 1 7 . Связы ван и е и сточ н и ка да н н ых с контроллером п редставле н и я
ГЛАВА 7 � ПАНЕЛИ В КЛ АДОК И С ЕЛ ЕКТОРЫ
267
Перетащите кнопку на представление и разместите ее непосредственно под
селектором . Дважды щел кните на ней и дайте ей имя Select. Перейдите в окно
инспектора связей, нажм ите клавишу <Co11trol>, перетащите указател ь от круж­
ка, расположенного рядом с событием Touch Up l nside, в код, показанн ы й в окне
помощн ика редактора, и отпустите кнопку м ы ш и над закрывающей фигурной
скобкой в конце определения класса, чтобы создать новый метод действия. П ри­
свойте этому пустому методу имя onBut tonPre s s ed, и увидите, что програм ма
Xcode автоматически его запол нит. Н а этом построение графического пол ьзо­
вател ьского и нтерфейса для второй вкладки завершено. Кнопка должна быть
отцентрована по горизонтали и находиться на фиксирован ном расстоя н и и под
селектором . Щел кн ите н а кнопке Align в нижней части раскадровки, установите
флажок H o rizonta l l y in Conta i ner, а затем щел кните на кнопке Add 1 Constra i n t
(рис.7 . 1 8).
ф
1!11
-
M o t J I 1. •1 1 1 1 v' н 1v-1
St1nnyvale
Cupertino
Santa Clara
о о о
CЬelecD
о о о
Add н- Allgnment Constralnta
ll 1.<;ad01 •g c<Jg";
В T1 ..:t1l!ng [:cqe�
fiiil Тор f:dg<'<,
ll!iJ BottOfn (d(JP.S
QD Нощ.олtаl Center:;
lili1 Verticaf (;e111вrs
iJ Bиselln�s
ll 11 ".,,.,"" "' С."lм•
·-� 11 Vertlcally ln Contalner
•
•
1i
о
.
!
1
�1
:
Update Frames ( None
)1
.:.:.::.:�==...:=============�
:
�����
Ad
�d�_
1 C�
o_
nя
_r_
aln
_t����-'·
�����....-..... �-...�
..
� �
Рис. 7 . 1 8 . Це нтро в а н и е к н о п к и по гор и зонтал и относител ьно
j
представл е н и я
Для того чтобы задать правил ьное расстояние между кнопкой и селектором
даты, перетащите кнопку на селектор даты, нажав клавишу <Co11trol>, и отпус­
тите кнопку м ы ш и . В поя в и вшемся меню выпол н ите команду Vertical Spac i n g
(рис. 7. 1 9). Щел кн ите на кнопке Resolve Auto Layout l ssues в н ижней части
раскадровки, а затем на кнопке U pdate F rames в верхней части вспл ы вающе­
го окна (если этот элемент недоступен, знач ит, ваша кнопка уже находится в
правил ьной позиции). Кнопка должна переместиться в п равил ьную позицию, и
предупреждения Auto Layout бол ьше поя вляться не должн ы .
268
ГЛАВА 7 !§ ПАН ЕЛ И В КЛАДОК И С Е Л Е КТОРЫ
о
•
11
-
S ш 1 yvale
Cup rtino
'3<1nt Clara
Рис. 7 . 1 9 . Н астро й ка рассто я н и я п о
верти кал и м ежду кноп кой и сел е ктором
Реализация контроллера как источника данных и делегата
Для того чтобы контроллер корректно работал в качестве источника данных
и делегата, нач нем с кода, с которым вы знаком ы и который не должен пред­
ставлять для вас н и каких трудностей, а затем добавим нескол ько методов, с
которы м и вы ранее не стал к и вались.
Щел кн ите на файле S i ng l e C ompo n e n t P i c kerViewCont r o l l e r . s w i f t и
добавьте следующий код в его начало:
@ I B Ou t l e t w e a k va r s i n g l e P i c ke r : U I P i c ke rV i e w !
private let characterNames = [
" Luke " , " Leia " , " Han " , " Chewbacca " , "Artoo " ,
" Threepio " , " Lando " ]
Загем добавьте в метод onButtonPres sed ( ) код, представленный в листинге 7.3 .
Л исти нг 7 . 3 . Метод onBut t onPre s s e d для п редставления контроллера
@ I BAc t i on f u n c o n Bu t t o n P r e s s e d ( s e nde r : U I B u t t o n ) {
l e t row = s i n g l e P i c ke r . s e l e c t e dRow ( i nCompo n e n t : 0 )
l e t s e l ected
c h a r a c t e rName s [ r ow )
let title
"You selected \ ( selected ) ! "
=
let alert
UIAle rtCon t ro l l e r (
title : title,
me s s a g e : " T h a n k you f o r c h o o s i n g " ,
p r e f e r r edS t y l e : . a l e r t )
l e t a c t i o n = U I A l e r tAct i o n (
t i t l e : " Yo u ' r e we l c ome " ,
s t y l e : . de f a u l t ,
h a n dl e r : n i l )
a l e r t . a ddAc t i o n ( a c t i o n )
p r e s e n t ( a l e r t , a n i ma t e d : t r u e , comp l e t i on : n i l )
ГЛАВА 7 \\'! ПАН ЕЛ И В КЛАДОК И СЕЛ ЕКТОРЫ
269
Как было показано ранее, селектор Date Picker содержит все необходи м ые
данн ые, но обы ч н ы й селектор поручает эту работу делегату и источн и ку дан­
ных. Следовател ьно, метод onButtonPre s s ed ( ) должен спросить у селектора,
какая строка выбрана, а затем попросить данные об этой строке у нашего мас­
сива p i c kerData. Вот как мы запрашиваем информацию о выбранной строке:
l e t row
=
s i n g l e P i c ke r . s e l e c t edRow ( i n Compon e n t : 0 )
Обратите внимание на то, что м ы должны указать ком понент, о котором хо­
тим получить информацию . В дан ном случае у селектора тол ько оди н ком по­
нент (вращающаяся ш кала), поэтому просто передаем в метод значение О, я вля­
ющееся и ндексом первого ( и единствен ного) ком понента.
В объя влении класса мы создаем масси в с нескольки м и символьными стро­
ками, так что у нас есть дан ные для поставки селектору. Обычно ваши данные
будут поступать из других источников типа с п иска свойств или запроса веб-служ­
бы. Встраивая массив элементов в код, как это сделано здесь, мы усложняем за­
дачу его обновления или перевода приложения на другие языки . Но такой подход
представляет собой быстрый и простой способ размещения данных в массиве в
демонстрационных целях. Даже если вы обычно не создаете такие массивы, как
здесь, вы все равно настраи ваете доступ к данн ы м в методе viewDidLoad ( ) ,
чтобы не искать их на диске или в сети каждый раз, когда селектор их запросит.
ПОДСКАЗКА. Есл и вы не плани руете создавать массивы из списков объектов в вашем
коде , как м ы тол ько что сделал и в v i e w D i dL o a d ( ) , то как в ы должн ы поступить?
Вставить списки в файлы списка свойств и добавить эти файлы в свой проект. Файлы
списков свойств могут изменяться без переком пиляции исходного кода , а это означа­
ет отсутствие риска внесен ия новых ошибок. Можно также указать различные версии
списков для разных языков, как это будет сделано в главе 22. Списки свойств более
подробно описываются в главе 1 3 .
Наконец вставьте в конец файла код, при веде н н ы й в л истинге 7.4.
Л исти нг 7 . 4 . М етоды и сточ н и ка дан н ы х и дел егата селектора
// MARK : / / MARK : P i c k e r D a t a S o u r c e M e t h o d s
f u n c n umbe rOf Comp o n e n t s ( i n p i c ke rV i e w : U I P i c ke r V i ew ) - > I n t {
return 1
func p i c ke r V i e w ( _ p i c ke r V i e w : U I P i c ke rV i e w ,
numb e r O fRow s i nComp o n e n t comp o n e n t : I n t )
r e t u r n c h a r a c t e rName s . c o u n t
-
> I nt {
1 1 MARK : P i c k e r De l e g a t e M e t h o d s
f u n c p i c ke r V i e w ( _ p i c ke r V i e w : U I P i c ke r V i e w , t i t l e Fo r Row r o w : I n t ,
f o r Comp o n e n t comp o n e n t : I n t ) - > S t r i n g ? {
r e t u r n c h a r a c t e rName s [ r ow ]
270
ГЛАВА 7 u ПАНЕЛИ В КЛАДОК И СЕЛЕКТОРЫ
Эти три м етода необходим ы для реал изации селектора. Первые два метода
взяты из nротокола U I P i c ke rViewDa t a S ource, и оба они необходи мы для всех
наших селекторов (за искл ючением селектора даты). Вот nервы й из них:
f u n c n umb e r O f Comp o n e n t s ( i n p i c ke rV i ew : U I P i c k e r V i e w ) - > I n t {
return 1
Селекторы могут и м еть более одной вращающейся ш кал ы , или ком nонен­
та, и с nомощью этого метода селектор заnраш и вает, скол ько ком nонентов он
должен выводить. В дан ном случае мы хотим отображать тол ько один сn исок,
nоэтому возвращаем значение 1 . Обратите в н имание: в качестве nараметра nе­
редается объект класса U I P i c ke rView. Этот nараметр указы вает nредставление
селектора, которое вы nол няет заnрос, что nозволяет иметь нескол ько селекторов
с одн и м и тем же источ н и ком данных. В дан ном случае мы знаем , что у нас
есть тол ько один селектор, nоэтому можем игнорировать этот аргумент ( м ы и
так з наем, какой селектор нас заnраш ивает).
Второй метод источн и ка данных исnользуется селектором для заnроса о ко­
л ичестве строк данных для данного ком nонента:
f u n c p i c ke r V i ew ( _ p i c ke r V i ew : U I P i c ke r V i ew ,
n umb e r O fRow s i n C omp o n e n t c omp on e n t : I n t ) - > I n t {
r e t u r n c h a r a c t e r Name s . c o u n t
Итак, мы узнали, какое nредставление селектора выnол няет заnрос и о каком
ком nоненте оно сnрашивает. Так как м ы и так знаем, что у нас есть тол ько один
селектор, состоящий из еди нственного ком nонента, нас не и нтересуют значения
nередаваемых аргументов, и мы nросто возвращаем кол и чество объектов в на­
шем единствен ном масси ве данных.
После этих двух методов источн и ка данн ы х м ы реал изуем оди н метод деле­
гата. В отл и ч ие от методов источн и ка дан н ых, все методы делегата не я вляются
обязател ь н ы м и . Терм и н необязательны й немного некорректен, nоскол ьку вам
нужно реализовать no крайней мере оди н метод делегата. Обычно реал изуют тот
метод, который м ы реал изуем сейчас и здесь. Однако, есл и вы хотите вы водить
в селекторе что-то и ное, а не текст, необходимо реал изовать другой метод, об этом м ы nоговорим, когда доберемся до nол ьзовател ьского селектора.
f u n c p i c ke rV i e w ( _ p i c ke r V i e w : U I P i c ke rV i e w , t i t l e Fo r Row r o w : I n t ,
f o r Comp o n e n t c omp o n e n t : I n t ) - > S t r i n g ? {
r e t u r n c h a r a c t e rName s [ r ow ]
В этом методе селектор nросит нас nредоставить данные для кон кретной стро­
ки кон кретного ком nонента. М ы nолучаем указател ь на заnраш ивающи й селек­
тор, а также ком nонент и строку, для которых требуются данные. Поскол ьку наше
nредставление и меет единственн ы й селектор с единственным ком nонентом, будем
игнорировать все, за исключением аргумента, указ ы вающего строку, и исnользо­
вать его для возвращения соответствующего элемента из нашего массива данных.
ГЛАВА 7 11< П А Н ЕЛ И В КЛАДОК И СЕЛ ЕКТОРЫ
27 1
ЧТО ТАКОЕ ДИРЕКТИВА MARK?
Обратили ли вы внимание на следующие строки кода из файла:
/ / МАRК : / / МАRК : Picker Data Source Мethods
Любая строка кода , которая начинается символами / / , является комментарием .
Комментарии , начинающиеся символами / / МАRК : , представля ют собой дирек­
тиву, которая указывает программе Xcode на необходимость изменения выпада­
ющего меню методов и функций на панели редактора . Первая директива поме­
щает в меню разделитель, а вторая создает текстовую запись, в которую вносит­
ся текст, содержащийся в оставшейся части строки директивы и который можно
рассматривать как описывающий заголовок для группы методов в исходном коде .
Некоторые из ваших классов , особенно классы контроллеров, могут оказаться
довольно дли н н ы м и , и контекстное меню с методам и и функциями существен­
но облегчает навигацию по коду. Аккуратное применение директивы / / МАRК :
и логичная организация кода позволяют использовать контекстное выпадающее
меню гораздо более эффективно.
С ком пилируйте и запустите приложение снова. Затем переключ итесь на вто­
рую вкладку, помеченную Single, и проверьте, как работает новый пользовател ь­
ский селектор, которы й должен выглядеть так, как показано на рис. 7.3 .
Верн итесь в среду Xcode, и м ы покажем, как реализовать селектор с двумя
ком понентам и. Есл и считаете, что разобрал ись в последнем селекторе, то у вас
есть отл и ч н ы й шанс убедиться в этом, создав селектор с двумя компонентами
самостоятел ьно. В ы уже видел и все необходим ы е методы, которые требуются
для этого селектора, так что можете идти вперед и проби вать эту стену. М ы
пока подождем вас здесь. Можете начать с рассмотрения рис. 7.4, чтобы ос­
вежить все в памяти. Когда законч ите, ч итайте дал ьше, чтобы узнать, как эту
проблему решали м ы .
Р еализа ци я м ногоком пон е нтного селектора
Следующим м ы рассмотрим селектор с двумя независи м ы м и оди н от дру­
гого ком понентам и . Левая вращающаяся ш кала содержит назван ия нач и нок бу­
терброда, а правая - сорта хлеба. М ы нап и шем такие же источ н и к дан ных и
делегат, как и для одноком понентного селектора. Все, что нам надо, - это на­
писать небол ьшой допол н ител ь н ы й код в некоторые из методов, чтобы они воз­
вращали корректные значения и кол ичество строк дл я каждого из компонентов.
Щел кните на файле DouЬ l eComponent P i c ke rVi ewCo n t r o l l e r . swi f t и до­
бавьте следующий код:
c l a s s DouЬ l e C omp one n t P i c ke r V i ewCont r o l l e r : U I V i e w C o n t r o l l e r ,
U I P i c ke r V i e w De l e g a t e , U I P i c ke r V i e w Da t a S o u r c e {
272
ГЛАВА 7 � ПАНЕЛИ В КЛ АДОК И С ЕЛ Е КТОРЫ
Здес ь мы просто подтверждаем , что наш класс я вляется контроллером как
делегата, так и источн и ка данных. С охраните его и щел кните на файле Ma in .
s t o ryboa rd для работы над графическим пользовател ьским интерфейсом .
Создание п редставления
Выберите п и ктограм му DouЫe Scene в о к н е Document Outline и щел кщпе на
п и ктограм ме View Controller, чтобы контроллер п редставления вы шел на пер­
вый план области редактировани я . Теперь добавьте представление селектора и
кноп ку. Измените м етку кнопки на Select, а затем установите необходим ые свя­
зи. Поскол ьку контроллеры представления в нашем приложении с точки зрения
связей в раскадровке совершенно идентичны, мы не будем приводить детальную
пошаговую инструкцию - за указаниями вы можете обратиться к предыдуще­
му разделу. Н иже кратко описано, что вам нужно сделать.
1 . Создайте выход douЬ l e P i c ke r в расширен и и класса DouЬ leComponen t P
i c ke rVi ewCon t ro l l e r, чтобы соединить контроллер с селектором .
2. Установите связь между элементам и dataSource и delegate на представле­
н и и селектора, испол ьзуя и нспектор с вязей .
3. Установите связь между событием кнопки Touch U p l nside и новы м мето­
дом действия onBut tonPre s s ed в контроллере представления, испол ьзуя
и нспектор связей.
4 . Добавьте в селектор и кнопку ограничения Auto Layout, фиксирующие их
на месте.
Сохраните и закройте раскадровку, п режде чем перейти к работе с кодом .
Сделайте закладку на этой страни це, так как вам еще придется к ней вернуться .
Реализация контроллера
Выберите файл DouЬ l eComponent P i c ke rViewContro l l e r . swi ft и добавь­
те в начало определения класса код, представлен н ы й в л исти н ге 7 . 5 .
Листинг 7 . 5 . П араметры , необходимые для двухкомпонентного селектора
@ I BO u t l e t w e a k va r douЫ e P i c ke r : U I P i c ke r V i e w !
p r i va t e l e t f i l l i n g C omp o n e n t
О
p r i va t e l e t b r e adComp o n e n t = 1
p r i v a t e l e t f i l l i ng T yp e s = [
" H am " , " T u r ke y " , " P e a n u t B u t t e r " , " T una S a l a d " ,
" C h i c ke n S a l a d " , " Roa s t B e e f " , " Vegem i t e " ]
p r i v a t e l e t b r e a d T yp e s = [
" W h i t e " , " W h o l e W h e a t " , " Rye " , " S o u r d o u g h " ,
" S e ven G r a i n " ]
=
Как види м , сначала м ы оп ределяем две константы , определяющие и ндекс
ком понента, чтобы повысить ч итабел ьность кода. Обращение к ком понен­
там селектора вы п ол няется по номерам, при чем край нему слева компоненту
ГЛАВА 7 jt; ПАН Е Л И В КЛАД О К И СЕЛЕКТОРЫ
273
присваивается нулевой и ндекс, а и ндексы остал ьных по очереди увеличи ваются
на един и цу. Затем м ы объя вляем два масси ва, в которых хранятся данные для
ком понентов селектора.
Реализуем метод onBut tonPre s s ed ( ) , как показано в л истин ге 7 . 6 .
Л истинг 7 . 6 . Действия при нажатии выбранной кнопки
@ I BAct i o n func o n Bu t t o n P re s s e d ( s e n de r : O I Bu t t o n )
l e t f i l l i n gRow
douЫ e P i c ke r . s e l e c t e dRow ( i n C omp on e n t : f i l l i n g C omp o n e n t )
l e t b r e a dRow
douЬ l e P i c ke r . s e l e c t e dRow ( i n C omp on e n t : b r e a dC ompo n e n t )
=
=
let f i l l ing
f i l l i n g T y p e s [ f i l l i n gRow ]
let bread
b r e a d T yp e s [ b r e a dRow ]
l e t me s s a g e
" Yo u r \ ( f i l l i n g ) o n \ ( b r e a d ) b r e a d w i l l Ье r i g h t up . "
=
=
=
let alert
O I Al e r t C o n t r o l l e r (
t i t l e : " T h a n k you f o r y o u r o r de r " ,
me s s a g e : me s s a g e ,
p r e f e rredS tyl e : . a l e r t )
l e t a c t i o n = O I Al e r tAc t i o n (
t itle : "Great " ,
s t y l e : . de f a u l t ,
handler : n i l )
a l e r t . addAc t i on ( a c t i o n )
p r e s e n t ( a l e r t , a n i ma t e d : t r ue , comp l e t i o n : n i l )
=
Теперь добавим в конец определения класса методы делегата и источн и ка
данных, как показано в л исти н ге 7.7.
Л истинг 7 . 7 . Методы источника дан н ых и делегата
/ / MARK : / / MARK : P i c ke r D a t a S o u r ce M e t h o d s
f u n c numb e r O f C omp o n e n t s ( i n p i c ke rV i e w : O I P i c ke rV i e w ) - > I n t {
return 2
f u n c p i c ke rV i ew ( p i c ke rV i e w : O I P i c ke r V i e w ,
numb e r O fRow s i n Comp o n e n t c omp on e n t : I n t ) - > I n t {
i f c omp o n e n t
b r e adComp o n e n t {
r e t u r n b r e a d T yp e s . c o u n t
�lse {
r e t u r n f i l l i n g T yp e s . c o u n t
==
/ / MARK : / / MARK : P i c ke r De l e g a t e M e t h o d s
f u n c p i c ke r V i e w ( p i c ke rV i e w : O I P i c ke r V i e w ,
t i t l e Fo rRow row : I nt , f o rComponent component : I n t ) - > S t r i n g ? {
i f comp o n e n t
b r e adComp o n e n t {
==
274
ГЛАВА 7 е ПАН ЕЛ И В КЛ АДОК И С ЕЛ ЕКТО Р Ы
r e t u r n b r e a d T yp e s [ r ow ]
else {
r e t u r n f i l l i n g T yp e s [ r ow ]
Метод onBut t o n P re s s e d ( ) на этот раз нем ного сложнее, но нового для
вас в нем оче н ь мало. М ы просто указы ваем, о каком ком поненте идет ' реч ь
при запросе в ыбран ной строки с помощью констант b r e a d C omp o n e n t и
f i l l i ngComponent.
l e t f i l l i ng Row
douЬ l e P i c ke r . s e l e c t edRow ( i n C ompon e n t : f i l l i ngComponent )
l e t b r e a dRow
douЫ e P i c ke r . s e l e c t e dRow ( i n Comp o n e n t : b r e a dCompone n t )
=
=
Здесь можно увидеть, наскол ько испол ьзование констант вместо О и 1 делает
код знач ительно более понятн ы м . Сам по себе метод o n Bu t t o n P r e s s ed ( ) , в
прин ципе, такой же, как и написан н ы й перед эти м .
Когда м ы присту п и м к методам источн и ка данн ых, нам нужно будет кое-что
изменить. В первом методе м ы указ ы ваем , что наш селектор должен состоять
не из одного, а из двух ком понентов.
f u n c numb e r O f Compon e n t s ( i n p i c ke r V i e w : U I P i c ke rV i e w ) - > I n t {
return 2
В этот раз, когда запраши вается кол ичество строк, необходимо проверить,
какой ком понент селектора запраш и вает это кол и чество, и вернуть корректное
значение для соответствующего масси ва.
f u n c p i c ke r V i ew ( p i c ke rV i e w : U I P i c ke rV i e w ,
numb e r O f R ow s i n Comp o n e n t comp o n e n t : I n t ) - > I n t {
i f comp o n e n t
b r e a dC omp o ne n t {
r e t u r n b r e a d T ype s . c o u n t
else {
r e t u r n f i l l i n g T yp e s . c o u n t
==
Затем в методе нашего делегата делаем то же самое. Проверяем компонент и
испол ьзуем массив, соответствующий запраш и вающему компоненту, для извле­
чения и возврата п равил ьного значения.
f u n c p i c ke r V i ew ( p i c ke r V i ew : U I P i c ke rV i e w ,
t i t l e Fo r Row r o w : I n t , f o r Comp o n e n t comp o n e n t :
Int ) -> String? {
i f c omp o n e n t
b r e a dComp o n e n t
r e t u r n b r e adT yp e s [ r ow ]
else {
r e t u r n f i l l i n g T yp e s [ r ow ]
==
Это было не так уж и трудно, не правда ли? С ком п илируйте и запустите при­
ложение и убедитесь, что панель DouЫe выглядит так, как показано на рис. 7.4.
ГЛАВА 7 ,,, ПАНЕЛИ В КЛ АДОК И С ЕЛ ЕКТО Р Ы
275
Обратите внимание на то, что каждая вращающаяся шкала пол ностью неза­
висима от другой шкал ы . Вращение одной никак не влияет на другую. В данном
случае это впол не уместно. Но бы вают ситуации, когда оди н из ком понентов
зависит от другого. Хорошим примером я вляются даты . При изменении меся ца
ш калу, которая показы вает дни месяца, возможно, потребуется измен ить, пото­
му что не все месяцы и меют одно и то же кол ичество дне й . Реал изовать это
не очень трудно, когда вы знаете, как это делается, но это не настол ько легкая
вещь, чтобы разобраться в ней самостоятельно. В следующем разделе м ы будем
решать именно эту задачу - реал изацию зависим ы х ком понентов .
Реализация зависи мых компонентов
В этом разделе м ы не будем вести ч итателя за руку, как делал и это ран ьше,
особенно есл и тема уже рассматривалась. В место этого сосредоточи мся на но­
вом материале. Наш новый селектор будет отображать в левом ком поненте спи­
сок штатов С ША, а в правом - список почтовых и ндексов, соответствующих
штату, выбран ному в левом компоненте.
Нам понадобится отдельный список значений почтовых и ндексов Дll Я каждого
элемента левого ком понента. М ы объявим два массива, по одному Дll Я каждого ком­
понента, так же, как делали это в прошл ы й раз. Нам также потребуется словарь
NSDictiona ry, в котором мы собираемся хранить объект класса NSArray Д11 Я каж­
дого штата (рис. 7.20). Позже мы реализуем метод делегата, который будет уведом­
лять нас при изменении выбранного элемента. При изменении значения слева мы
будем брать в словаре соответствующий массив и передавать его Дll Я использования
правому компоненту. Не беспокойтесь, если вы не уловил и все тонкости; более под­
робно все эти вопросы будут раскрыты при их реализации в коде.
Добавьте в файл DependentComponent P i c ke rVi ewCon t r o l l e r . swi f t сле­
дующий код:
c l a s s Depende n t Comp o ne n t P i c ke r V i ewCont r o l l e r : U I V i ewCont r o l l e r ,
UIPi ckerViewDelegate , UI Pi ckerViewDataSource {
private let s tateComponent
О
private let zipComponent
1
[ S tring ] ] !
private var s tateZips : [ String
private var s tate s : [ String ] !
private var z ips : [ String ] !
=
=
При шло время для создания содержания . Этот п роцесс будет практически
иденти чен соответствующему процессу для двух предыдущих представлен и й .
Если запутаетесь, вернитесь к разделу "Создание представления" для однокомпо­
нентного селектора и следуйте приведенным там пошаговым и нструкци я м . Под­
сказка: откройте файл Ma i n . s t o ryboa rd, найдите класс DependentComponent
P i c ke rVi ewCont r o l l e r и повторите те же основные шаги, которые делали для
всех других представлени й в этой главе. Когда закончите, сохраните раскадровку
и вернитесь в среду Xcode. Вы должны закончить работу, задав свойство выхода
dependent P i c ke r, связан ного с селектором, пустой метод onButtonPre s s ed : ,
276
ГЛ АВА 7 \О. ПАН Е Л И В КЛАДОК И С ЕЛ Е КТОРЫ
связан н ы й с кнопкой, а также свойства d e l e g a t e и da t a S ource для селекто­
ра, связан ного с контроллером п редставления. Не забудьте добавить ограниче­
ния Auto Layout в оба представления ! Закончив работу, сохраните раскадровку.
99501
9 9 502
99503
99504
7 1601
7 1602
7 1603
7 16 1 1
Рис . 7 . 20 . Да н н ы е н а ш е го п риложе н и я . Каждому штату соот­
ветствует одна з а п и с ь в сл оваре с назва н и е м штата в качест­
ве кл юча . С эти м кл ю ч о м хран ится э кзе м п л я р A r r a y< S t r i n g > ,
в кото ром содержатся в с е п очто в ы е коды дан н ого штата
П ристу п и м к реал изаци и класса контроллера. На первый взгляд, эта реал и­
зация может показаться немного сложно й . Сделав один из ком понентов завися­
щим от другого, мы добавил и новы й урове н ь сложности в класс контроллера.
Хотя селектор вы водит одновременно тол ько два списка, наш кл асс контроллера
должен знать 5 1 список и у правлять и м . Испол ьзованная здесь методика упро­
щает этот процесс. Методы источ н и ка данн ы х почти идентич н ы тем, которые
м ы реал изовал и для п редставлен ия DouЫePickerViewControl ler. Все допол н ител ь­
ные сложности обрабаты ваются в другом месте, между методом viewDidLoad
и новы м методом делегата
p i c ke rView ( : d i d S e l e c t Row : i nComponent : ) .
Перед тем как п исать код, нам потребуются некоторые данные для вы вода.
До сих пор м ы создавал и массивы в коде, п росто при водя список строк. По­
скол ьку нам не хотелось бы вводить нескол ько тысяч значен и й , а также пото­
му, что м ы хотим показать, как правил ьно решать такие задачи, м ы собираемся
загружать данные из списка свойств. Как уже упом иналось, объекты NSArray
и N S D i c t i onary могут создаваться из с войства списков. М ы вкл ючил и список
свойств s t at e d i c t i onary . p l i s t в папку 07
P i c ke r Da t a архи ва проекта.
-
-
ГЛАВА 7 '" ПА НЕЛ И В КЛАДО К И СЕЛ ЕКТО Р Ы
277
С коnируйте этот файл в nanкy P i c ke r в своем nроекте Xcode. Если вы щелк­
нете на plist-фaйлe в окне навигатора n роекта, то увидите и даже сможете отре­
дактировать данн ые, которые он содержит (рис. 7.2 1 ).
i Plckers )
1 ва <
r- Кеу
statedlctlonary.pllst \ No Selection
Туре
' • Root
Dlctlonary
Array
• Alaska
Array
• Atizono
Array
(376 ltems)
• Arl<ansas
Array
(6 1 8 items)
Аtтау
(1 757 ltems)
• Colorado
Array
(501 ltoms)
Array
(276 ltems)
Аtтау
(68 ttems)
• Florida
Аtтау
• Georgla
Array
(736 items)
• Hawall
Array
• ldaho
Array
(292 ltams)
Array
{780 1tems)
• Connectlcut
• Dolawore
Array
• llllnols
• lndlana
• Kanaaa
Array
Array
• Loulll1ona
Аtтау
• lowo
• Кentucky
• Malne
Arra y
Array
Arrry
1
1
Array
"' Montana
Array
• NoЬroaka
Array
8" Nevada
Array
• New Ho.mpshlre
Array
8" Now Jersey
Array
• N- Mexlco
Array
8" New Yoli<
Arroy
• North C aro\in a
Array
'Y Ohlo
Array
8" North Oakota
Аtтау
ltem О
ltem 2
--
(972 1tom1)
(72 1 1t en1s)
__
(542 items)
(466 1tems)
(5 1 9 ltems)
(987 1tems)
(892 ltems)
(447 1tems)
(1 040 items)
(364 1tems)
{590 items)
(1 58 ttams)
(238 ltems)
(604 ltoms)
(366 ltems)
( 1 677 1toms)
(809 items)
(392 ltems)
(1 1 89 1tems)
Strtng
4300t
Strlng
43003
Strlng
ltem t
1t11т :\
( 1 3 75 ltems)
(4 1 5 ltems)
Array
... Mlsslulppl
(92 ltams)
Array
Array
... M11180Url
(972 ltems)
(799 itams)
• Massachusetts
• M ln nesota
{25 1 ltems)
Array
... Maryland
• Mlchigan
1
(657 ltems)
• Alabama
• Calllornla
1
Value
(50 1tems)
sц1no - -
43002
..А3004 -- - -
Рис. 7 . 2 1 . Файл s t a t e d i c t i on a r y . p l i s t со с п и с к о м штатов .
Дл я штата Огайо откр ыто начало с п и с ка почтовых и нде ксов
278
ГЛАВА 7 а ПАНЕЛИ В КЛАДОК И СЕЛ ЕКТОРЫ
Добавьте в файл DependentComponent P i c ke rViewCont ro l l e r . swi ft не­
с кол ько методов, которые потом мы раздел и м на более удобные фрагменты .
Начнем с реал изации метода onBut t o n P re s s e d ( ) , показанной в листинге 7 . 8 .
Л истинг 7 . 8 . Методы источника данных и делегата
@ I BAc t i o n f u n c o n B u t t o n P r e s s ed ( s e n de r : U I Bu t t o n )
l e t s t a t e Row
dependent P i c ke r . s e l e c t e dRow ( i n C omp o n e n t : s t a t e Comp o ne n t )
l e t z i p Row
dependent P i c ke r . s e l e c t edRow ( i n C ompo n e n t : z i p C omp o n e n t )
=
=
let state
s t a t e s [ s t a t e Row ]
let zip
z i p s [ z i pRow ]
=
=
l e t t i t l e = " Y o u s e l e c t e d z i p code \ ( z i p ) "
l e t me s s a g e
" \ ( z ip ) i s i n \ ( s tate ) "
=
l e t a l e r t = U I A l e r t C on t r o l l e r (
title : title ,
me s s a g e : me s s a g e ,
p re f e r redS t yl e : . a l e r t )
let action
U I A l e rtAc t i on (
t i t l e : " ОК " ,
s t y l e : . de f a u l t ,
h a n dl e r : n i l )
a l e r t . a ddAc t i o n ( a c t i o n )
p r e s e n t ( a l e r t , a n im a t e d : t r u e , comp l e t i o n : n i l )
=
Теперь добавьте в существующий метод viewDidLoad ( ) код, показанн ы й в
листинге 7.9.
Л истинг 7 . 9 . Метод viewDidLoad ( )
ove r r i de f u n c v i e w D i d L o a d ( )
s upe r . v i e w D i dLoad ( )
1 1 Дополнител ь н а я н а стройка после з а гру з ки представл е н и я .
l e t bundl e = B u n dl e . ma i n
l e t p l i s t URL
b u n d l e . u r l Fo r R e s o u r c e ( " s t a t e d i c t i o n a r y " ,
withExtens ion : "pl i s t " )
s t a t e Z i p s = N S D i c t i o n a r y . i n i t ( c o n t e n t s O f : ( p l i s t URL ) ! ) a s !
[ String ] ]
l e t a l l States = s t a t e Z i p s . keys
states
a l lStates . sorted ( )
l e t s e l e c t e dS t a t e
states [ O ]
z i p s = s t a t e Z i p s [ s e l e c t e dS t a t e ]
=
[ S t r i ng
=
=
Наконец добавьте в конец файла методы делегата и источн и ка данн ы х, при­
веденные в л истинге 7 . 1О.
ГЛАВА 7 n ПАНЕЛИ В КЛАДОК И СЕЛ ЕКТО Р Ы
279
Л истинг 7 . 1 О. Методы источника дан н ых и делегата
для вывода почтовых индексов штатов
/ / MARK : 1 1 MARK : P i c k e r Da t a S o u r c e Me t h o d s
func numb e r O f C ompone n t s ( i n p i c ke rV i e w : U I P i c ke rV i ew ) - > I n t {
return 2
func p i c ke rV i e w ( _ p i c ke rV i e w : U I P i c ke rV i e w ,
n umb e rOfRow s i n C ompo n e n t comp o n e n t : I n t ) - > I n t {
i f comp o n e n t == s t a t e C omp o n e n t {
return states . count
else {
return z ips . count
/ / МАRК : / / MARK : P i c ke r De l e g a t e Me t h o d s
func p i c ke rV i e w ( p i c ke rV i ew : U I P i c ke rV i e w , t i t l e Fo r Row row : I n t ,
f o r C omp o n e n t
comp o n e n t :
I nt ) - > String? {
i f c omp o n e n t == s t a t e C omp o n e n t
r e t u r n s t a t e s ( r ow ]
else {
r e t u r n z i p s [ row ]
func p i c ke rV i e w ( _ p i c k e rV i ew : U I P i c ke rVi e w , d i dS e l e c t Row row : I n t ,
i nComp o n e n t comp o n e n t : I n t ) {
i f comp o n e n t == s t a t e C omp o n e n t {
l e t s e l e c t e dS t a t e
s t a t e s [ row ]
z i p s = s t a t e Z i p s ( s e l e c t e dS t a t e ]
depende n t P i c ke r . r e l o adComp o n e n t ( z i p C omp o n e n t )
depende n t P i c ke r . s e l e c t Row ( O , i n Comp o n e n t : z i p C ompo n e n t ,
a n ima t e d : t r u e )
=
Нет необходимости говорить о методе onBut t o n P re s s ed ( ) , поскольку он,
по сути, такой же, как и предыдущи й . Однако м ы должны поговорить о методе
viewDidLoad ( ) . В нем п роисходит кое-что важное, в чем вам надо разобрать­
ся, так что садитесь поудобнее, и п ристу п и м . Первое, что нам надо сделать в
этом новом м етоде viewDidLoad ( ) , - это п олучить ссыл ку н а основной пакет
приложения .
l e t b u n d l e = Bund l e . ma i n
Пакет (bundle) - это особый т и п папки, содержимое которой имеет определен­
ную структуру. Приложения и каркасы представля ют собой пакеты, и показанный
выше вызов возвращает объект пакета, который представляет н аше приложение.
280
ГЛАВА 7 11< П АН Е Л И В КЛАДОК И СЕЛ ЕКТОР Ы
ЗАМЕЧАНИЕ. В последних версиях среды Xcode и библиотек IOS компания Apple п ред­
ложила более удобн ый способ ссылаться на такие элементы , как N S Bund l e в языке
Swift. Вместо вы ражения наподобие l e t bun d l e = NSBundl e . ma i n ( ) теперь можно
использовать более удобные варианты .
Одн и м из главных применений класса N S Bund l e я вляется обращение к, ре­
сурсам, которые вы добавил и в п роект. Эти файлы будут скопирован ы в пакет
вашего приложения при его сборке. Есл и м ы хотим получить эти ресурсы в
коде, то нам понадобится класс N S Bund l e . Основной пакет испол ьзуется для
получения пути и нтересующего нас ресурса.
l e t p l i s tURL
=
b u n dl e . U R L F o r Re s o u r c e ( " s t a t e d i c t i o na r y " ,
wi t h E x t e n s i o n : " p l i s t " }
Этот вызов возвращает строку с расположением s t a t e d i c t i onary . p l i s t .
Затем этот путь можно испол ьзовать для создания объекта класса NSDictionary.
Как тол ько мы это сделаем, все содержимое списка свойств будет загружено во
вновь создаваем ы й объект класса N S Di c t i onary, который м ы затем присвоим
переменной s t a t e Z i p s .
stateZ ips
=
NSDictionary . init ( contentsOf : ( p l i s tURL } ! } a s ! [ S tring : [ String ] ]
Тип D i c t ionary в языке Swift не и меет удобного способа для загрузки дан­
ных из внеш него источ н и ка, а тип N S D i c t i o n a r y в каркасе Foundation имеет
такие возможности . Этот код испол ьзует такие возможности, загружая содержи­
мое файла s t a t e d i c t i onar y . p l i s t в объект класса N S D i c t i ona ry, который
при водится к ти пу языка Swift [ S t r i n g : [ S t r i ng ] ] . И наче говоря, словарь, в
котором каждый кл юч представляет штат и соответствующее значен ие, я вляется
масси вом почтовых и ндексов, представленных в виде строк. Это соответствует
структуре, показанной на рис. 7 . 1 8 .
Для того чтобы запол н ить масси в левого ком понента селектора, соберем спи­
сок всех кл ючей нашего словаря в масси ве s t a t e s . Однако перед присваивани­
ем отсортируем этот масси в в алфавитном порядке.
l e t a l l S tates = s t a t e Z i p s . keys
states
a l l S t a t e s . s o r t ed ( )
=
Есл и только м ы не указываем и ное значен ие, селектор нач инает работу с вы­
бран ной первой строкой (строка с и ндексом О). Для того чтобы получ ить массив
индексов, соответствующий первой строке массива штатов, м ы получаем из мас­
сива объект с и ндексом О. Это даст нам название штата, который будет выбран
в момент запуска. Затем испол ьзуем наз ван ие штата для получения масси ва поч­
товых и ндексов для этого штата, которы й присвоим переменной z i ps, которая,
в свою очередь, будет испол ьзоваться для передачи данных в правый ком понент.
let selectedState
states [ O ]
zips
s tateZips [ se l ectedS tate ]
=
=
ГЛАВА 7 �; ПАНЕЛИ В КЛАДОК И С ЕЛ Е КТО Р Ы
281
Эти два метода источ н и ка дан н ы х п рактически идентич н ы п редыдущей вер­
сии. Мы возвращаем кол ичество строк в соответствующе м масси ве. То же самое
верно и для первого реал изован ного метода делегата. Второй метод делегата
является новы м и в нем происходит нечто загадочное.
f u n c p i c ke r V i ew ( _ p i c ke rV i e w : U I P i c ke r V i e w ,
d i d S e l e c t Row r o w : I n t , i n Comp o n e n t c ompo n e n t :
Int ) {
i f comp o n e n t
s t a t e C omp o n e n t {
l e t s e l e c t e dS t a t e = s t a t e s [ row ]
zips
s t a t e Z i p s [ s e l e c t e dS t a t e ]
depende n t P i c ke r . r e l o a dComp o n e n t ( z i p C ompo n e n t )
depende n t P i c ke r . s e l e c t Row ( O , i n Comp o n e n t : z i pComp o n e n t ,
a n im a t e d : t r u e )
==
=
В этом методе, которы й вызывается вся кий раз при изменении выбранной
строки в ком поненте селектора, мы изучаем ком поненты и п роверяем, не изме­
нился ли селектор левого ком понента. Есл и это произошло, получаем массив
индексов, который соответствует новому селектору левого ком понента, и присваиваем его
массиву z i p s . Затем правы й компонент вновь
настраивается на показ первого ряда дан н ы х
lv1ar vla11d
и перезагружается . Метод зам е ны масси ва
Massachus . . .
01 001
M1ch1gaп
01002
z i p s при изменени и состояния позволяет ос­
тавить прочи й код почти нетронутым , таки м
же, каки м он был в примере DouЫePicker.
Но м ы еще не закончил и . С ком пил ируйте
Select
и запустите приложение и п роверьте работу
вкладки Dependent (рис. 7.22). Два ком понен­
та имеют одинаковые размер ы . Хотя почто­
вый индекс н и когда не будет состоять более
чем из пяти с и м волов, дл я него выделяется
такое же пространство, как и для назван ия
штата. Поскол ьку назван ия таких штатов, как
М иссис и п и ил и Массачусетс, не помещают­
ся в половину экрана на устройствах i Phoпe,
это решение кажется далеким от идеального.
К счастью, есть еще оди н метод делегата,
1
''"'
" "
который м ы можем реал изовать, чтобы у ка­
зать, насколько широким должен быть каждый
Рис. 7 . 2 2 . В ы в самом деле
ком понент. Добавьте метод из л истин га 7 . 1 1 в хотите , чтоб ы раз м е р ко м ­
раздел делегата в файле Depende n t C ompone п о н е нтов б ы л оди н а к о в ы м ?
n t P i c ke rViewCont ro l l e r . swi f t . Результат Обратите в н и м а н и е на обры в
вы увидите на рис. 7 .23 .
дл и н н о го назва н и я штата
282
ГЛАВА 7 � ПАН ЕЛ И В КЛАДОК И С ЕЛ Е КТО Р Ы
Л истинг 7 . 1 1 Методы источн и ка данных и делегата
для вывода почтовых и ндексов штатов
•
func pickerView ( pickerView : UI Pi ckerView ,
widthForComponent component : Int) -> CGFloat
let pickerWidth
pi ckerView . bounds . si ze . width
if component "'"" zipComponent {
return pickerWidth/ 3
8188 {
r8turn 2 * pi ckerWidth / 3
=
Carrler •
iPho,ne 6s - IOS 10.О (1'\A5261u}
11:41 АМ
Marylarкi
Massachusetts
M 1 ch1gan
-
01 001
0 1 00 2
Select
0;1'Р
1
Рис . 7 . 23 . П о с л е н астр о й к и ш и р и н ы
ком п о н е нтов сел е ктора п ол ьзо вател ь ­
с к и й и нте рфейс стал н а м н о го луч ше
В данном методе мы возвращаем ч исло, п редставляющее собой ширину в
п и кселях каждого ком понента, и селектор будет делать все возможное, чтобы
учесть эти данн ые . Экспериментируя с раз н ы м и значен и я м и , можно увидеть,
как распределяется п ространство между ком понентам и при их изменен и и . Со­
хран ите файл , скомпилируйте приложение и запустите его, и ваш селектор будет
выглядеть так, как показано на рис. 7 . 5 .
ГЛАВА 7 •Чi ПАНЕЛИ В КЛАДОК И С Е Л Е КТОРЫ
283
К этому моменту вы уже должны хорошо знать не тол ько селекторы, но и
приложения с панел я м и вкл адок. Нам осталось показать вам еще тол ь ко одну
вещь, связанную с селекторам и .
Создание п рос т о й и гры
с пользовательски м селе ктор ом
Следующим наш и м занятием будет создание простого и грового автомата.
Верн итесь к рис. 7.6, прежде чем продолжить чтение, чтобы понимать, что м ы
создаем .
П одготовка контроллера представления
Добавьте следующий код в файл C u s t omPi c ke rVi ewCon t ro l l e r . swi f t :
c l a s s C u s t om P i c ke r V i e w C o n t r o l l e r : U I V i ew C o n t r o l l e r ,
UIPickerViewDelegate , UIPickerViewDataSource {
private var images : [ UI Image ] !
Здесь м ы добавляем в класс свойство масси ва, содержащего изображения,
которые будут вы водиться селектором .
Создание представления
Хотя селектор на рис. 7.6 и меет вид, отличающийся от вида созданных нами
ранее селекторов, на самом деле очень мало разл и ч и й в том, как мы разраба­
ты ваем наши раскадровки. Все допол нительные работы в ыполняются в методах
делегата нашего контроллера.
Убедитесь, что вы сохранили свой новый исходны й код, а затем дважды щелк­
ните на файле Ma i n . s toryboard в навигаторе проекта и выберите пиктограм му
Custom Scene для редактирован ия графического интерфейса. Добавьте представ­
ление селектора, метку под ним, а еще ниже - кнопку. Дайте кнопке имя S p i n .
В ыбрав метку, вызовите инспектор атрибутов. Установите выравн и ван ие по
центру. Затем щелкн ите на кнопке Text color, чтобы изменить цвет текста на что­
то более яркое. Затем обратитесь к настрой кам Font в инспекторе и щел кн ите
на пиктограм ме (она выглядит как буква Т в рам ке), чтобы открыть селектор
шрифтов . Этот элемент управления позволяет перекл ючать системные шрифты
ил и просто изменять их размер. Пока просто измените размер шрифта на 4 8 и
удал ите слово Labe l, так как м ы не хоти м, чтобы до момента выигрыша пол ь­
зователя в метке вы водился какой-либо текст.
Добавьте огран ичения Auto Layout для центрования селектора, метки и кноп­
ки по горизонтал и и фиксации верти кальных просветов между н и м и, а также
между меткой и селектором с одной сторон ы и верхни м краем представления
с другой. Вероятно, проще всего перетащить указател ь мыши с кноп ки в окне
Docu ment Outl i n e при добавлении огран ичени й Auto Layout, потому что метка на
раскадровке я вляется пустой и ее очен ь трудно найти .
ГЛАВА 7 tJэ ПАН ЕЛИ В КЛАДОК И СЕЛ Е КТОР Ы
284
После этого выпол н ите все соединения с выходам и и действия м и . В а м необ­
ходимо соединить выход p i c ke r контроллера представления с п редставлением
селектора, а также выход wi nLabe l контроллера представления с меткой. Про­
ще всего испол ьзовать метку в окне Docu ment Outline. Затем свяжите событие
Touch Up l nside кнопки с методом действия s p i n ( ) . После этого свяжите селек­
тор с делегатом и источ н и ком данных.
Есть одна дополнительная вещь, которую следует сделать. Вызовите инспектор
атрибутов для селектора. Вам нужно сбросить флажок User l nteraction EnaЫed в
нижней части настроек View, чтобы пользователь не мог нарушать правила. После
тоm как вы сделали все описанное, сохраните изменения, внесенные в раскадровку.
Ш РИФТЫ , ПОДДЕРЖИВАЕМЫЕ 105-УСТРОЙСТВАМИ
Будьте осторожн ы при использовании палитры ш рифтов в l пterface Builder при
разработке интерфейсов IOS. П рограмма lnterface B uilder позволяет назначать
меткам любой шрифт, который и меется на вашем компьютере Мае, но ЮS-уст­
ройства имеют очень огран ичен н ы й селектор шрифтов . Вы должны ограничиться
одним из семейств шрифтов, имеющихся на целевом ЮS-устройстве. Сообщен ие
h t t p : / / i phonedeve l opme n t . Ы o g s po t . com / 2 0 1 0 / 0 8 / fon t s - a nd - fo n t ­
fami l i e s . h tml в посвященном IOS блоге Джеффа Л амарша рассказывает, как
программно получить этот список.
Если говорить в двух словах, то следует создать приложение на базе представ­
ления и добавить приведенный код в метод appl i c a t ion ( : d i d F i n i shLaunc
h i ngWi thOp t i on s : ) делегата п риложения.
for fami l y in U I Font . fami l yName s ( ) a s [ S t r i ng ]
p r i nt l n ( fami l y )
for font in U I Font . fontName s Fo r Fami l yName ( fami l y ) {
print l n ( " \ t \ ( font ) " )
}
}
Выполните проект в соответствующем симуляторе или на устройстве , и ш рифты
будут выведен ы в консольный журнал проекта .
Реализация контроллера
В реал изаци и дан ного контроллера и м еется масса новинок. Добавьте в ме­
тод s p i n ( ) в файле Cu s t omPi c ke rViewCont r o l l e r . swi f t код, при веденный
в листинге 7 . 1 2 .
Л истинг 7 . 1 2 . Метод spin ( )
@ I BAc t i on f u n c s p i n (
va r w i n = fa l s e
va r numi nRow
-1
v a r l a s tVal
-1
=
=
s e n de r : U I B u t t o n ) {
ГЛАВА 7 1'11 П А Н ЕЛ И В КЛАДОК И СЕЛ ЕКТОРЫ
285
for i in О <5 {
l e t newVa l u e = I n t ( a r c 4 r a ndom_ u n i f o rm ( U i n t 3 2 ( i mage s . c o u n t ) ) )
i f newVa l u e = l a s tV a l {
1 1 n um i n Ro w + + * * * УЧ Т И Т Е : в S w i f t 3 и н креме н т а ци я и де креме н т а ци я
/ / объя в л е ны у с т а р е вшими
numi nRow + = 1
} else {
n um i nRow = 1
•
•
=
l a s tVa l = newVa l u e
p i c ke r . s e l e c t Row ( newVa l u e , i n C omp o ne n t : i , a n ima t e d : t r u e )
p i c ke r . r e l o a dCompone n t ( i )
i f num i nRow > = 3 {
win
t rue
=
w i nLab e l . t e x t
w i n ? " W I NNER ! "
" " / / Обра т и т е в нима ние
// н а пробел в ка выч ках
ЗАМЕЧАНИЕ. Унарная инкрементация ( foo++) и декрементация ( foo - - ) в языке Swift З
объявлены устаревш и м и . Вместо них рекомендуется испол ьзовать операторы + = и -= .
Вставьте в код метода viewDidLoad ( ) код, приведенный в л истин ге 7. 1 3 .
Листинг 7 . 1 3 . Модификации мето да viewDidLoad ( )
для настройки изображений и метки
ove r r i d e f u n c v i e w D i dLoad ( )
s upe r . v i e w D i dLoad ( )
1 1 Дополни т е л ь на я н а с т р о й к а после з а г р у з ки предс т а в л е ни я .
ima g e s = [
U I Image ( n ame d : " s e ve n " ) ! ,
U I Image ( n amed : " b a r " ) ! ,
U I Image ( n amed : " c r owп " ) ! ,
U I Image ( n amed : " c h e r r y " ) ! ,
U I Image ( n ame d : " l emo n " ) ! ,
U I Image ( n amed : " a pp l e " ) !
w i n Lab e l . t e x t = " " / / / / Обр а т и т е внимание н а пробел в кавычках
a r c 4 r a ndom_ s t i r ( )
На:конец добавьте в код источн и ка данных и делегата в кон це объявления клас­
са перед закры вающей фигурной скобкой текст, приведе н н ы й в листинге 7 . 1 4.
Л истинг 7 . 1 4 . Методы источника дан ных и делегата
/ / MARK : / / MARK : P i c ke r D a t a S o u r c e M e t h o d s
f u n c n umb e r O fCompon e n t s ( i n p i c ke r V i e w : U I P i c k e r V i ew )
return 5
-
> Iпt {
286
ГЛАВА 7 а ПАНЕЛИ В КЛАДОК И С Е Л Е КТОРЫ
f u n c p i c ke rV i e w ( _ p i c ke r V i e w : U I P i c ke rV i e w ,
n umb e r O f Row s i n C omp o n e n t c omp o n e n t : I n t ) - > I n t {
r e t u r n imag e s . c o u n t
1
/ / MARK : / / MARK : P i c k e r De l e g a t e M e t hods
f u n c p i c ke r V i e w ( _ p i c ke rV i e w : U I P i c ke r V i e w ,
v i e w Fo r Row r o w : I n t ,
f o r Compon e n t c omp o n e n t : I n t ,
reu s i ng view : U I V i ew ? ) - > U I View
l e t ima g e = imag e s [ r ow ]
l e t ima g e V i e w = U I I m a g e V i e w ( image : ima g e )
r e t u r n ima g e V i e w
f u n c p i c ke r V i e w ( _ p i c ke r V i e w : U I P i c ke rV i e w ,
row H e i g h t Fo r Comp o n e n t comp o n e n t : I n t ) - > CG F l o a t {
return 64
Метод spin ()
Метод s p i n ( ) запускается, когда пользовател ь при касается к кнопке Spi n .
В н е м м ы сначала объя вляем несколь ко перемен н ы х, которые помогут отслежи­
вать в ы и грыш пол ьзователя . Мы испол ьзуем перемен ную w i n для того, чтобы
отследить, нет ли в ряду трех одинаковых изображе н и й . Переменная numi nRow
отслежи вает, скол ько оди наковых значений было в строке до сих пор, а значение
предыдущего ком понента хранится в l a s tVa l , чтобы мы могл и сравни вать те­
кущее значение с предыдущи м . Мы и н ициал изируем переменную l a s tVa l зна­
чением - 1, потому что знаем, что такого реал ьного значения не может быть.
var win = f a l s e
v a r numi nRow = - 1
v a r l a s tV a l = - 1
Далее следует цикл по всем пяти ком понентам , в котором каждый из н их
получает новую, случайн ы м образом выбран ную строку. Поскол ьку нам извест­
но, что размеры всех масси вов оди наковы, м ы испол ьзуем значение count из
масси ва c o l umn l .
for i in О . <5 {
l e t newVa l ue = I n t ( a r c 4 r a ndom_ u n i f o r m ( U i n t 3 2 ( imag e s . c o u n t ) ) )
.
С рав н и ваем новое значение с предыдущим и у вел и ч и ваем numinRow, есл и
они совпадают. Есл и же нет, то сбрасы ваем значение numi nRow в 1 . Присваи­
ваем новое значение переменной l a s tVa l , чтобы можно было сравнить его в
следующий раз.
i f newVa l u e == l a s t V a l {
n um i nRow + = l
else {
n um i n Row = 1
l a s t V a l = newVa l u e
ГЛАВА 7 lf! П А Н ЕЛ И В КЛАДОК И СЕЛ ЕКТО Р Ы
287
После этого устанавл и ваем новое значение для соответствующего ком понен­
та, запраш и ваем анимацию изменения и требуем от селектора перегрузки ука­
занного ком понента.
p i c ke r . s e l e c t Row ( n ewVa l u e , i n C omp on e n t : i , a n ima t e d : t r u e )
p i c ke r . r e l o adComp o n e n t ( i )
Последнее, что м ы делаем в каждой итерации цикла, - проверяем, не полу­
чилось ли три одинаковых сим вола в строке и, если получ илось, устанавл и ваем
для переменной w i n значение YE S .
i f numi nRow > = 3 {
win
true
=
Как тол ько м ы заканч и ваем работу с циклом, соответствующим образом ме­
няем текст метки .
w i n Lab e l . t e x t
=
w i n ? " W I NNER ! " : " "
/ / Обр а т и т е в нима ние на пробел между кавычками
Метод viewDid.Load ()
Первое, что надо сделать, - это загрузить шесть разл и ч н ых изображений,
которые мы добавил и в каталог Image s . xca s s e t s . М ы делаем это, используя
удобн ы й метод класса U I Image, который наз ы вается imageNamed ( ) .
ima g e s
[
U I Image ( name d :
U I Image ( name d :
U I Image ( n ame d :
U I Image ( named :
U I Image ( named :
U I Image ( named :
=
" s e ven " ) ! ,
" ba r " ) ! ,
" c r own " ) ! ,
" ch e r ry " ) ! ,
" l emo n " ) ! ,
" ap p l e " ) !
Последнее, что м ы делаем в этом методе, - задаем текст метки, состоящий
из одного пробела. М ы хоти м, чтобы метка была пустой, но не сжималась до
нуля. Задав пробел, мы обеспеч и м правильную высоту метки.
w i nLab e l . text
=
" " / / Обра т и т е вни м ание на пробел между кавычками
В заключение вы вызвал и метод a r c 4 random_ s t i r ( ) , задав начальное зна­
чение ,генератора случайных ч исел, чтобы избежать генерирован ия одинаковых
последовател ьностей чисел при каждом запуске приложения .
Но что же нам делать с шестью изображениями? Есл и вы просмотрите тол ь­
ко что введенный код, то увидите, что два метода источ н и ка дан н ы х в ы глядят
примерно так же, как и ранее, но есл и вы посмотрите далее, на методы де­
легата, то увидите, что для предоставления дан ных селектору мы испол ьзуем
совершенно другой м етод делегата. Тот, который м ы испол ьзовали до сих пор,
возвращал строку, а этот возвращает объект ти па U IVi ew.
288
ГЛАВА 7 :g: ПАНЕЛИ В КЛАДОК И С Е Л Е КТО Р Ы
Этот метод позволяет передавать селектору все, что можно изобразить, в
объекте класса U I V i ew . Конеч но, есть огран ичения на то, что будет работать
таким образом и в то же время хорошо в ы глядеть, учиты вая небол ьшой размер
селектора. Но этот метод дает гораздо бол ьше свободы в том, что мы вы водим,
хотя и требует несколько большей работы.
f u n c p i c ke rV i e w ( _ p i c ke r V i e w : U I P i c ke r V i e w ,
v i e w F o r Row r ow : I n t ,
f o r Comp o n e n t comp o n e n t : I n t ,
reus ing view : UIView ! ) - > UIView
l e t ima g e = imag e s [ r ow ]
l e t ima g e V i e w
U I I ma g e V i e w ( i ma g e : i m a g e )
r e t u r n ima g e V i e w
=
Этот м етод возвращает оди н объект класса U I IrnageVi ew, содержащи й одно
из изображений для с и м волов. Для этого мы сначала получаем изображение для
сим вола, а затем создаем и возвращаем графическое представление этого симво­
ла. Для более сложных представлений сначала целесообразно создать представ­
ление, нап ример методом v i e w D i dL o a d ( ) ,
а затем - заранее создан ное п редставление
Camer •
в селектор представлений по запросу. Однако
в нашем п ростом случае создание представ­
ления "на лету" работает впол не хорошо.
Все, что было первоначал ьно одн им боль­
ш и м куском кода, оказалось разложенным по
полочкам . Запустив приложение, вы увидите
• • •
экран, показан н ы й на рис. 7.24.
Последние штрихи
WI N N E R !
У нас получ илась неплохая и гра, особен­
но есл и подумать о том , как мало усил и й
потребовалось, чтобы е е создать. Сейчас мы
нем ного улучшим ее. Есть два замечан ия, ко­
торые можно высказать об игре.
Spi11
1
2
1+-
�
Рис . 7 . 2 4 . Н е с а м о е у вл е к а ­
тел ь н о е ,
н о в п ол н е п о з н а в а ­
тел ь н о е п р и л оже н и е , де м о н с ­
три рующее работу сел е ктора
'J;
Она сл и ш ком тихая . И гровые автоматы
так тихо не работают.
itl
Она сообщает о в ы и грыше еще до того,
как ш кала заканчи вает вращаться, что не
так уж важно, но тем не менее хотелось
бы этого избежать. Для того чтобы уви­
деть этот недостаток, снова запустите при­
ложение. Метка поя вляется нем ного ран ь­
ше завершения вращения, хотя это почти
не заметно.
ГЛАВА 7 1·1 ПАН ЕЛ И В КЛАДОК И СЕЛЕКТОРЫ
289
В папке 07
P i c ke r Sounds архива проектов и меются два зву ковых файла:
c runch . wav и w i n . wav. С копируйте эту папку в папку P i c ke r. Эти звуки мы
будем воспроизводить, когда пол ьзовател ь нажи мает кнопку Spin и когда он по­
беждает соответственно.
Для работы со звуками м ы должны иметь доступ к классам iOS Audio Тоо\Ьох.
Вставьте следующую строку в начало файла C u s t omP i c ke rVi ewCont ro l l e r .
swi f t :
-
imp o r t U I K i t
iшport AudioToolbox
Далее мы должны добавить выход, который будет указы вать на кнопку. Пока
колеса вращаются, м ы хотел и бы, чтобы кнопка была скрыта. М ы не хотим,
чтобы пол ьзователи могл и н ажимать ее в то время, когда колеса еще вращаются .
Добавьте следующий код в файл Cus t omPic ke rViewC ont ro l l e r . swi f t :
c l a s s C u s tomP i c ke r V i ewCo n t r o l l e r : U I V i ewCon t r o l l e r ,
U I P i c ke rV i e w De l eg a t e , U I P i c ke r V i e w Da t a S o u r c e
p r i v a t e va r ima g e s : [ U I I m a g e ] !
@ I BOu t l e t w e a k v a r p i c ke r : U I P i c k e rV i e w !
@ I BOu t l e t w e a k v a r w i n La b e l : U I La b e l !
@ IBOutlet weak var button : UIButton !
После того как введете текст в файл и сохран ите его, щелкните на файле Ma i n .
s t oryboa rd, чтобы редактировать графический пол ьзовател ьский и нтерфейс.
Откройте окно помощн и ка редактора и файл C u s t omP i c ke rVi ewCon t r o l l e r .
swi f t . Н ажм ите клавишу <Control> и перетащите указател ь с маленького кру­
жочка влево вниз - на выход, тол ько что добавлен н ы й к кнопке в раскадровке
(рис. 7.25).
Теперь необходимо выпол н ить нескол ь ко действи й по реализации нашего
класса контроллера. Во-первых, нам необходим ы переменн ые, в которых хра­
нились бы ссылки на загружаем ые звуковые файл ы . Откройте файл Cu s t om
P i c ke rViewContro l l e r . s w i f t и добавьте в него следующие новые свойства
(выделенные полужирным шрифтом):
c l a s s C u s t om P i c k e r V i ewCont r o l l e r : U I V i e wCon t r o l l e r ,
U I P i c ke r V i e w De l e g a t e , U I P i c ke r V i ew Da t a S o u r c e
p r i va t e va r imag e s : [ U I I m a g e ] !
@ I BOut l e t w e a k va r p i c ke r : U I P i c ke r V i ew !
@ I BOu t l e t w e a k va r w i n L a b e l : U I Lab e l !
@ I EO u t l e t w e a k va r b u t t o n : U I B u t t o n !
private var winSoundID : Sys teшSoundID = О
private var crunchSoundID : Sys teшSoundID = О
Во-вторых, необходимо добавить в класс контроллера пару методов. Добавьте
два метода, приведенные в листи нге 7 . 1 5 , в файл Cus tomPickerViewCont rol le r .
swi f t .
290
- ·
•
ГЛАВА 7 IJ\! ПАНЕЛИ В КЛ АДО К И СЕЛЕ КТОРЫ
...... ""' tlllt "':'- ""!!! -... t� � � �с.о-- � "
• " • f\-· · - "
<
,_ - . ..."....., _ · -" -· ·-· ·-··-· -·<>­
. -"
�--
· -­
· ----­
. � -..........
_ ........,. __
--
1::::--.:; :=�!=.=:=:"
... . .... . - - . "
" о-.,
·--
""" - - -
N-­
_,..__ _
· ·=-
•..
- ;:.� �
�
.
-- -·
-.
__
. ,., _
_ _ _ ,,,. "
.
...-. - Ot•• IOo • .'1 8
•
'
Q (J
---- -"
-..... - " . ,,. _ "
,__
_ _ ... __
1--• ::::.:.:.
:::- � _ ..."".
Рис . 7 25
.
.
С в я з ы ва н и е в ыхода к н о п к и с кноп кой на канве раскадровки
Л истинг 7 . 1 5 . Сокрытие кнопки Spin и воспроизведение
звуков и грального автомата
f u n c s h owBu t t o n ( ) {
b u t t o n . i s H i dd e n
=
fa l s e
f u n c p l a yW i n S ound ( ) {
i f wi nSound I D
О {
l e t s o u ndURL � Bund l e . ma i n . u r l F o r Re s o u r c e (
" w i n " , wi t h E x t e n s i on : " wa v " ) ! a s C FURL
Audi o S e r vi c e s C r e a t e S ys t e m S o u nd I D ( s o undURL , & w i n S ou nd I D )
==
Audi o S e rv i c e s P l a y S y s t emS o u n d ( w i n S o u nd I D )
w i n La b e l . t e x t = " W I NNER ! "
D i s p a t chQueue . ma i n . a f t e r ( w h e n : . n ow ( ) + 1 . 5 )
s e l f . s h owBu t t o n ( )
Первый метод используется для того, чтобы показать кнопку. М ы собираемся
скрывать кнопку после того, как пол ьзовател ь нажал ее, потому что, если колеса
уже вращаются, нет никакого смысла вращать их далее, пока они не остановятся.
Второй метод будет вызван, когда пол ьзовател ь в ы и грает. С начала м ы про­
веряем, загружен ли звук победы . С войства w i n S ou nd I D и c runchS ound I D
и н и циал изируются нулями, а идентификаторы для загруженных звуков - нет.
Следовател ьно, для того чтобы проверить, загружен ли звук, достаточно срав­
н ить идентифи катор с нулем . Для загрузки зву ка сначала запраши ваем пакет,
ГЛАВА 7 �• ПАНЕЛИ В КЛАДОК И СЕЛ ЕКТОР Ы
29 1
содержащи й файл w i n . wav, аналогично тому, как м ы дел ал и при загрузке спис­
ка свойств для зависимого представления селектора. Следующие три строки
кода загружают звук и воспроизводят его. Затем метка получает текст WINNER !
и вызы вается метод s howBu t t o n ( ) , но этот вызов выполняется специал ьным
образом - с применением метода Di spatch_Queue ( when : ) . Это очень удоб­
ная функция . Она позволяет вызвать м етод через некоторое время в будущем,
в дан ном случае - через полторы секу нды, которые позволят колесам, прежде
чем резул ьтат будет сообщен пол ьзователю, докрутиться до конечного положе­
ния . Эта фун кция относится к гру п пе функций Gra11d Ce11tral D ispatch (GC D),
которую м ы рассмотрим в главе 1 5 .
ЗАМЕЧАН ИЕ. Возможно , вы заметили нечто странное в способе объя вления функции
Audi o S e r v i c e s S y s ternS oundI о ( ) . Первым параметром этой функции я вляется ад­
рес URL. Однако он должен быть не экземпл я ро м класса N S URL , а объектом класса
C FURL ( который ранее назы вался C FURLRe f ) , представл яющим собой указател ь на
структуру из каркаса Core Fou пdation , написанного на языке С. Указатель NSURL я в ­
ляется частью каркаса Foundation , написанного на языке Objective- C . К счастью , мно­
гие компоненты , написанные на языке С , имеют аналоги н а языке Objective-C в кар ­
касе Foundation , например структура C FURL функционально эквивалентна указателю
NS URL . Это означает, что некоторые категории объектов , созда н н ых на языке Switt
ил и Objective- C , можно использовать в интерфейсах прикладного п рограммирования ,
написанных на языке С , п росто приводя их к соответствующим типам в языке С , ис­
пол ьзуя ключевое слово a s .
Нам также необходимо внести некоторые изменения в метод s p i n ( ) . М ы
нап ишем код для воспроизведения звука п р и в ы и грыше игрока (листинг 7. 1 6).
Л исти нг 7 . 1 6 . Модифицированны й метод spin ( )
@ I BAct i o n f u n c s p i n ( s e n de r : AnyOb j e c t ) {
va r w i n = f a l s e
va r num i nRow = 1
va r l a s tV a l = - 1
-
for i in О . . <5 {
l e t newVa l u e
I n t ( a r c 4 r a n dom_ u n i f o rm ( U i n t 3 2 ( imag e s . c o u n t ) ) )
i f newVa l u e
l a s tVal {
n um i nRow + +
else {
num l nRow
1
==
=
'1
l a s tVal
=
newVa l ue
p i c k e r . s e l e c t Row ( newVa l u e , i n C omp o ne n t : i , a n i m a t e d : t r u e )
p i c ke r . r e l o a dComp o n e n t ( i )
i f num i nRow > = 3 {
win
t r ue
=
292
ГЛАВА 7 �1 ПА Н Е Л И В КЛАДОК И С ЕЛ ЕКТОРЫ
i f c r u n c h S o u nd I D == О {
l e t s o undURL = N S B u n d l e . m a i n B und l e ( ) . U R L F o r Re s o u r c e (
" c r u n c h " , w i t h E x t e n s i on : " w a v " ) ! a s C FURLRe f
Audi o S e r vi c e s C r e a t e S y s t em S o u n d I D ( s o undURL , & c r u n c h S o u nd I D )
Audi o S e r v i ce s P l a yS y s t e m S o u n d ( c r u n c h S o u nd I D )
if win {
D i s p a t c h Q u e u e . ma i n . a f t e r ( wh e n : . n ow ( O ) + 0 . 5 ) {
s e l f . p l a yw i n S o un d ( )
else
D i s p a t ch Q u e u e . ma i n . a f t e r ( wh e n : . now ( O ) + 0 . 5 ) {
s e l f . s h owBu t t o n ( )
b u t t o n . h i dden
w i n La b e l . t e x t
true
/ / Обра ти т е в нима ние н а пробел между ка в ыч ка ми
Сначала м ы загружаем скрипу ч и й з ву к, как это делалось ранее. Следую­
щая строка проигры вает уже загруженный звук, чтобы и грок сл ы шал, как кру­
тятся колеса. Затем, вместо метки W I N N E R ! при в ы и грыше пол ьзователя, м ы
идем на некоторые хитрости . М ы вызы ваем оди н из двух м етодов, которые
тол ько что создал и, но делаем это после задержки с испол ьзован ием метода
D i s p a t chQueue . ma i n . a f t e r ( whe n : ) . Есл и пол ьзовател ь выи грал, вызы ваем
метод p l a ye rW i n S ound ( ) через полсеку нды, что дает колесам время остано­
виться ; в противном случае ждем полсекунды и с нова вкл ючаем кнопку Spi n .
Ожидая резул ьтата, м ы скры ваем кнопку и стираем текст метки.
Нажм ите кнопку Run в среде Xcode и щел кн ите на последней метке. При за­
пуске кнопка Spin издает оди н звук, а в случае победы воспроизводится другой .
Р е зюм е
Теперь вы должны ком фортно чувствовать себя, работая с приложения м и с
панел я м и вкл адок и селекторам и . В дан ной главе м ы "с нуля" создал и пол но­
цен ное прил ожение с панел ью вкладок, содержащее пять различных представ­
лен и й содержимого. Вы узнали, как испол ьзовать селекторы разл и чных конфи­
гураци й, как создавать селекторы с нескол ьким и ком понентами и как сделать
значения в одном ком поненте зависящи м и от в ыбран ного значения в другом
компоненте. Вы также видел и , как заставить селектор вы водить изображения,
а не просто текст.
Кроме того, вы узнали о делегатах и источ н и ках данных селектора и уви­
дел и, как загруз ить изображения, звуки, а также создать словари на основе
сп исков свойств. Это была дл и н ная глава, так что мы поздравляем ч итателей,
добравшихся до ее конца. Теперь вы готовы к работе с табл и ч н ы м и представ­
ления м и .
ГЛА В А 8
• • •
В в еде н и е в та б л и ч н ы е
п р едс т а вл е н и я
В нескольких следующих главах м ы создадим иерархическое навигационное
приложен ие, похожее на приложение Mail, поставляемое с iОS-устройствами.
Приложения этого ти па, обыч но и менуемые master-detail, позволяют пол ьзо­
вателю переходить к вложе н н ы м спискам данных и редактировать эти данн ые.
Но прежде чем мы сможем написать такое приложение, вам необходимо освоить
концепцию табличных представлений, которые и я вляются цел ью дан ной главы.
Т а бл и ч н ы е п редставлен и я (tаЫе views) - наиболее распространен н ы й ме­
хан изм, испол ьзуем ы й для отображения списков дан ных. Эти объекты допус ка­
ют очень подробное конфигурирование и могут быть настроен ы и менно так, как
вы хотите . П риложение Mail испол ьзует табл и ч н ые п редставления для показа
списков учетных зап исей, папок и сообщений, но табл ич н ые представления не
ограничи ваются тол ько отображением текстовых дан ных. Табл ичные представ­
ления испол ьзуются также в приложениях Settings, M u sic и C l ock, несмотря на
то что эти приложения имеют соверше н но разн ы й внеш н и й вид (рис. 8 . 1 ).
Осн о вы т а б л и ч н ы х п ред ст а влени й
Табл и цы вы водят на экран с п иски дан н ых. Каждый элемент табл ичного
сп иска я вляется строко й . В системе iOS табл ицы могут иметь любое кол ичест­
во строк, огран ичен ное л и ш ь и меющейся доступной памятью. Однако табл и цы
iOS м о гут содержать тол ько оди н столбец.
Табличные представления и ячейки табличного представления
Табл ич ное п редставление я вляется объектом, которы й вы водит табл и ч н ые
дан н ые и представляет собой экземпляр класса U I T a Ь l eView. Каждая видимая
строка табл и цы реал изуется экземпляром класса U I T a Ь l eVi ewCe l l (рис. 8.2).
294
ГЛАВА 8 >I.: В В ЕД ЕН И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
••••• V...� LП
18-'Н
Setttn;a
а Alrplane Моdе
11 Wi-FI
11 Вluвtooth
Cellulat
Personal Hotspot
IJ Notlfications
m Controt Center
CJ Do Not DisturЬ
@) Genetal
11 Dtsplay & Srightneu
" . " R: ••
Off
Оп
)N
�!::��, l
••"• Y8r\a'Ol\ L,f
(j)
л
л
л
.J''J
_i'j
11:f7
" . :t IC) t
Q
'" "°
л
New York
·-�
-
Вruckf*. SymphorUea ID..c 7}
Вruckмc Sym- ID18c 8)
,,_
Chicago
.
о
...
.
о
""""""'" s""""°"'" IOO.C •J
� В.linef Philharmonitl.er S.r8'1b.
...
'\l:M
World Clock
Today. 3 houf• Ьtnina
Вnюt<..,, Symphonoes ID""' •1
"."
Edn
Cupenino
Вruckner: SymphonieJ (D1tc 2)
'
••••• \18rtlon LП
6ruckмr: Syn� No. з •
•
"...,.. ...."
. ... � �-,...... '"''-
-------
'
San Francisco
Tcxt.y, 3 hour:a Ьehlnd
."
'
'
.
Shoat.ekovich: Symphofly f7.
"LenlnQrad"
Nr.8 •v ,._,., �
TocNly, 1 tll'Juf" i>ehlnd
London
Тоdау, 5 !'louf-e atчмld
St . Louis
�-·-
- -
...
Todly, 1 hour bet11nd
.., • • •_,t
�-,
.
.
"С
+
• \, •
t
'
.
•
.
.
.
<
.
'
"\
,
'
' . .
"С
.
.
.
'
'
.
.
•
"
.
.
"\'
.
, ,
1
'
.
Рис. 8 . 1 . Несмотря на раз н ы й в н е ш н и й вид, приложе н и я Setti ngs, Music и C lock
испол ьзуют табл и ч н ы е п редста вл е н и я
Табл ичные представления не несут ответственности за хранение табл ич­
ных дан н ы х . Они хранят тол ь ко те дан н ые, которые необходи м ы для вы во­
да строк, види мых в текущий момент. Табл и ч н ы е представления получают
свои конфигурационные данные из объекта, который соответствует протоколу
U I TaЬleVi ewDe l e g a t e, и строчные данные из объекта, соответствующего про­
токолу U I TaЬleViewDa t a S ource. Вы увидите, как все это работает, в при мерах
наш их програм м, описанных в главе.
Как уже упом и налось, все табл ицы реал изованы в виде одного столбца. Одна­
ко приложение C l ock, показанное на рис. 8 . 1 , справа, выглядит как имеющее два
столбца, но в действител ьности это не так
каждая строка в табл и це представ­
лена единственным объектом класса U I T a Ь l eVi ewCe l l . По умолчанию объект
класса U I TaЬleVi ewCe l l может быть настроен для вы вода изображения, неко­
торого текста и необязател ьной вспомогател ьной п и ктограмм ы в правой части
( м ы подробно рассмотри м вспомогательные п и ктограм м ы в главе 9).
По мере необходимости можно поместить в ячейку еще бол ьше данных, до­
бави в в объект класса U I Ta Ь l eViewC e l l дочерние представления, испол ьзуя
оди н из двух основных методов : 1 ) путем добавления дочерних представлен ий
програм мно при создани и ячейки ил и 2 ) с помощью загрузки из раскадровки
ил и n iЬ-файла. В ы можете макетировать ячейку табл ицы так, как вам нравится, и
вкл юч ить в нее л юбое требуемое кол ичество дочерн их представлен и й . Поэтому
-
ГЛАВА 8 �. В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
295
ограничение табличных представлен и й одни м столбцом на деле оказы вается не
таким страшн ы м , как это, вероятно, выглядит на первый взгл яд. Далее мы по­
кажем, как испол ьзовать оба эти метода.
Ячейка табл и ч н о го п редста влен ия
(UITa ЫeViewCell)
Табл и ч ное п редста вление
(UITa ЫeView)
Q
Q
Вruckner: Symphoolea (Disc 2]
Вruckner: Symphonles (Disc 2]
l1м.нt! Б.�t-N, ' 1 '1 Bl#t1"\ P11Hri1:1·rnQ1'11t; Or,11
л
л
Вruckner: Symphooles (Disc 6]
{i,., ·lo,I 6>t;'ll •lx• "l t:I•
P'"tl!MirriQn•
r;
0.J'\ifoi 8af1."Ьo•tt f\1411!
а
N
о
р
о
."· в".", 1... '111 ""...., i "lfln;i tюn· t -·
Вruckner. Symphooles (Disc 8)
0,tt'I- ! Siv�•\Qo"' f:\•I
Bruckner: Symphonles (Dlsc 9]
l !:iWl"<I. ... R�
",, ' " .>IЧ
'
U•t-t
Bruckner. Symphooles (Disc 7]
JJI
t1<'1'll>•Jf'� (J
L
"
N
о
р
Q
R
•
т
u
•
w
х
�
Вruckner: Sym phonles (Dlsc 9]
O..n1•J W1"лЬ011n BtrП.11 Pml!'\11m10.:tlf;' Or"-n.
\).1NOI �niIOfln. 8�111n P,11\l'ISf'nolt+C Orc11
J
l•м h.Jl'mo" •
f)l)"11•\ 8Ar,..l'lbt"1�' ('1-• , �..,�h:'!•F.•>f'· ".,, Ф-
Вruckner: Symphonles (Disc 8]
Вruckner: Symphooy No. З 8ef1iner PhUharmoniker - Barenb . . .
о
•
F
G
Вruckner: Symphooies (Disc 6]
•·.
Bruckner: Sym p hooi es (Disc 7]
[l,1t>•1'1 н,}/1!'<1\)111"1'1 t:l�н1•1 l'l'll!noc'Т\Ol'h< )1: !1
1
•
в
C...i>l•I Вar«�P'I В.-тlт l"ttiilhи1rnи с 01rt1
•••
Вruckner: Symphony No. З •
Ber1iner Phllharmoniker - Barenb . . .
у
f)1.•н"l 8.1.'tt !
Shostakovlch: Symphony И7,
' Lenlngrad'
<1•1
8
" i'tt1U"1r
<
�C't'I
Shostakovlch: Symphooy 17,
'Lenlngrad'
{}l'f\;I''• У,)!°)\ '""'<.) Н•JС."щ1 Р� 11'.\lff\0'�· (lf
•
{.)n1o1tr( Y11Qlt>i1•ky � .....,"al!' f'h•'l'l·••fl'lon•c {)r
Nr.3 lv. Flnaio. Allogro
� �. Вtf\ln Phi!Мrrnot'.: Orcмs:" - 8'�
Jj
Q
....
.....
".
@
Рис . 8 . 2 . Каждое табл и ч н о е представл е н и е п р едставляет собой
экзе м п л я р класса U I TaЫ eView, а каждая в ид и м ая строка - эк­
земпляр U I TaЬleVi ewCe l l
Сгруп пированные и простые табли цы
Табличные представления бы вают двух основных стилей.
��
С гру п п и рова н н ые (grouped). С груп пированное табл ичное представление
содержит один ил и нескол ько разделов из строк. В каждом разделе все
' строки тесно связан ы в одну небол ьшую гру п пу; между разделами и ме­
ются ясно види мые промежутки, как показано на рис. 8 . 3 , слева. Заметим ,
что сгруппирован ная табл и ца может состоять из одной группы.
�:.;
П ростые (plain). Это стил ь, заданн ы й по умолчанию. При дан ном стиле
раздел ы рас полагаются нем ного ближе друг к другу, а заголовок каждо­
го раздела может (необязател ьно) выделяться вне ш н и м видом . При ис­
пол ьзован и и и ндекса этот стиль также именуется и ндекс и рова н н ы м
(с м . рис. 8 . 3 , справа).
296
ГЛАВА 8 & В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
C.r•-.i •
Azar1a
Azul
Вailee
Bailey
Вolley
Ваrьаr1
вarrett
8ayiee
Вeatrice
Веоu
8eckett
Вelen
Вelinda
. " ...
-
""""' .
А
6 :о4 , М
-
Aylin
с.,,• •
м
М.СI
8
Мackenzie
Вailee
Вoiley
ВiiМзу
-·
Вarnзtt
8ayifJI
8eatrice
Веоu
Вecl<ett
Вelen
-
Масеу
Az8'\a
AzUI
t.otPМ
масlо
Масу
М.d•lyn
мad1)Vnn
Мadden
мaddl1on
мaddox
Madelelne
Мade4ine
мadelyn
мadelyon
Рис . 8 . 3 . Одно и то же табл и ч н о е п редставл е н и е в виде сгруп п и рован ной таб ­
л и цы ( сл е ва ) , п ростой табл и цы без и ндекса ( п осреди н е ) и п ростой табл и цы с
и ндексом , ил и и ндекс и ро в а н н о й табл и цы ( с п рава )
Есл и источ н и к дан ных предоставляет необходимую и нформацию, табл и чное
представление позволяет пол ьзовател ю перемещаться по сп иску с испол ьзова­
нием и ндекса, которы й отображается вн изу справа.
Табл ицы состоят из разделов (section). В сгру п пированной табл ице каждый
раздел визуал ьно представляет собой гру п пу. В и ндексированной табли це раз­
делом я вляется каждая и ндексирован ная группа данных. Напри мер, в и ндекси­
рованной табл ице, показанной на рис. 8 . 3 , все имена, нач и нающиеся с буквы А,
образуют оди н раздел, нач и нающиеся с буквы В - другой и т.д.
ПРЕДУПРЕЖДЕНИЕ. Хотя технически возможно создать с груп п и рованную табл ицу с ин­
дексом , вы не должны этого делать. В справоч нике iPhone Нитап lnterface Guidelines
подчеркивается , что с г рупп и рова н н ы е табл и цы не должны п редоставлять индекс ы .
Р е али з ация п ростой табли цы
Расс мотри м простейш и й при мер табл и ч ного представления, чтобы понять,
как оно работает. В дан ном примере мы просто вы ведем сп исок текстовых зна­
чен и й .
ГЛАВА 8 � В В ЕД Е Н И Е В ТАБ Л И Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
297
Создайте н о в ы й nроект в среде Xcode. В дан ной главе м ы вернемся к
шаблону S i n g l e View Appl ication, nоэтому выбираем его. Назовите ваш nроект
S imp l e Т а Ы е , выберите nункт Swift в сnиске Lang uage и nу н кт U n iversa l в
списке Devices , а затем убедитесь, что флажок U se Core Data сброшен .
Проектирование представления
Зайдите в нави гатор nроекта и раскройте nроект верхнего уровня S imp l e
ТаЫ е и nan кy S imp l e Т аЫ е . Наше nрил ожение настоль ко nростое, что нам не
требуются н и выходы, ни действия, так что в ыберите файл Ma i n . s t oryboard
для редактирования раскадровки. Если окно View не отображается, щел кн ите
на его пиктограм ме в окне Docu ment Outline, чтобы открыть его. Затем найдите
в библ иотеке объектов элемент ТаЫе View (рис. 8.4) и перетащите его в окно
View .
....... 1.... ....,, 1 ,-. . 10 11 .щ
& Q;i 1 . 1.1 t;J (]
"
• � ..,.. ia. • ..._ "
-1.�
"'· '
�
1.ЩО:.'..:
w;, IJ
�" �.���· .
1 -�,
""" ...... ,...
..,... ,...,. , � а """"-д .,.. а -.с-.. � � vi.. � ' � . '--..,..,..
u Ф 11 � о rэ
r:t il <> & e • ." " •11<
·-. , ... ,...
т а и.. � --- - -- �-! ·" . --�
IJ
._ .,.... _
....... Clllo
4:
---1
�
---
. .,,... _
·-­
. ."
. ......,... ...,. ....
1
1
!
1
1
--1:
1
TaЬle Vlew
L - ---- -- -
.
.
•
._..__ Dltalt
в
..._ ...,. �
.
i-... м.••� °"""'ll' tailirt8
- - -
= -
- -
8
, --
...., __
0 __ 1-tl� .......
. ._ ..,.,.. ...,._..
...... . ...... �
--
-
1
---- - _....J
-
.
-. а -а-1 :
·"
i) о ф 11
, ,
' rw� "....... . .,_., .... . . ...
. � _j ·��· ....-:
...
tn & /ot}l �· м e-
о
Рис . 8 . 4 . П е ретас к и в а н и е табл и ч н о го п р едставл е н и я из б и бл и отеки на гла в ­
н о е п редставл е н и е
Перетащите табл и ч ное п редставление в окно View и распол ожите его по
центру родител ьского представлен и я . Добавьте ограничения Auto Layout, что­
бы убедиться, что табл и ч ное представление корректно расположено и и меет
правил ьный размер, независимо от раз мера э крана. Выберите табл и цу в окне
Docu ment Outline, а затем щелкните на п и ктограмме P i n в п равом н ижнем углу
редактора (рис. 8 . 5 ) .
298
ГЛАВА 8 � В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
q
[о_
•
-; нон о
I
-=з
10
:i
Spacing to nearest nelghЬOr
г
1
О Constraln to margins
О 1!J Wldth
о (iiJ Нelght
r
580
,- lil Equгl 1dths
• 1 t tq
J
600
---.J
�
ht:s
о 11 Aspect Rat\o
-0 !
n
Lea<f ng Edges
Update Frames ( None
(
Add 4 Constralme
m в
:)
��:=J
�af ��� J =вв ��
Рис . 8 . 5 . Закрепл е н и е табл и ч ного п р едста в ­
л е н и я таки м об разо м , чтоб ы о н о запол н ял о
э кран
В верхней части вспл ы вающего окна сбросьте флажок Constra i n to marg i ns,
щелкните на всех четырех пунктирных л иниях и установите все расстоя ния во
всех четырех полях ввода рав н ы м и нулю. Это прикреп ит все стороны табл ич­
ного представления к сторонам родител ьского представлен ия . Для того чтобы
применить эти ограничения, замен ите значение поля U pdate F rames на I t ems
of New Con s t r a i nt s и щелкните на кнопке Add 4 Constra i nts . Табл ица должна
изменить размеры и заполн ить все представление.
Вновь выберите табл и ч ное представление в окне и нспектора документов и
нажм ите комбинацию клавиш <Option+X+6>, чтобы вызвать инспектор связей.
Вы увидите, что первые две доступные связи для табл ичного представления та­
кие же, как и для представления селектора в предыдущей главе: da t a S ource и
d e l egate. Перетащите указатель из кружка, расположен ного рядом с каждой из
связей, к пиктограм ме View Controller в окне Docu ment Outl ine ил и в точку, рас­
положенную выше представления контроллера в редакторе раскадровки. Посту­
пая так, мы делаем наш класс контроллера источ н и ком данных и делегатом для
этой таблицы.
ГЛАВА В � В В ЕДЕН И Е В ТАБЛ ИЧ Н Ы Е П Р ЕДСТАВЛ Е Н И Я
"'*"�- � ��...tt1. a�
" • ....., т...
•
..... r"
· -­
--
.
--
• ai v... � i­
· J� �
......
'
�---1
·- � o...,r.,
.
._,
-
...:;.;,J
""
,;.;.:
....,. ,... • � · • ....,...- .,., �1 . 8 ..,,.,,. ecм..• lk- ' Q..,... a.-. � r Vltw
--­
" ·.:.::
·-
·-­
. ...
....... ......у ...,.
�!
а •-::.•
1
--
"� l;J о
& �
о Ф • о а G
-'=-=·""li.1' - -�
�
Q
=--_.......,.. _
о
j ...... .... �
-..-..... ... о
11
Table View
Pн.rtut)I� C�i.wd.
11
1
1
J
[] V.W •1,; � h l*C ••I
•
-·;;,..... .,,..., !
299
- .
о о \& о
." .,... � . 1.
'* -· - - · - ···
.... " �
· --
====--.....
,..... ....., , "--' ..... . ....
",.... .,... " ...... _
о
Рис. 8 . 6 . Свя з ы в а н и е выходов da t a S o u r c e и de l e g a t e дл я табл и ч ного п ред­
ста вл е н и я
Теперь м ы присту п и м к п рограм м и рован ию табл и ч ного представления на
языке Swift.
Р еализация контроллера
После прочтения предыдущей главы м ногие терм и н ы ч итателя м уже долж­
ны быть понятны м и, и допол н ител ьные разъяснения не требуются . Тем не ме­
нее для ч итателей, пропусти вших предыдущую главу, мы постараемся сохра­
нить связь с терм и нологией, в веденной в первых главах. Щел кн ите на файле
ViewCont ro l l e r . s w i f t и добавьте в объя вление класса код, приведенный в
листинге 8 . 1 .
Л истинr 8 . 1 . Добавление кода в начало объявления класса для создания массива
c l a s s V i ewCo n t r o l l e r : U I V i e w C o n t r o l l e r ,
UI TaЬleViewDataSource , UI TaЬleViewDelegate
pri va te let dwarves
[
" S leepy " , " Sneezy " , " Bashful " , " Нарру " ,
"Doc " , " Grwnpy " , "Dopey " ,
" Thorin " , " Dorin " , " Nori " , " Ori " ,
" Balin " , " Dwalin " , " Fi l i " , " Ki l i " ,
" Oin " , " Gloin " , " Bifur " , " Bofur " ,
" BomЬur "
=
let s impleTaЬleidenti fier
=
" SimpleTaЬleidentifier "
300
ГЛАВА 8 i1 В В ЕДЕ Н И Е В ТАБЛ ИЧ Н Ы Е П Р ЕДСТАВЛ Е Н И Я
В л истин ге 8. 1 м ы обеспечиваем соответствие нашего класса двум протоко­
лам, которые необходимы для того, чтобы он действовал в качестве делегата и
источника данных для табли чного представления, а затем объя вляем массив, ко­
торый будет содержать дан ные для отображения в табл ице, и идентификатор, ко­
торый нам вскоре понадобится . В реальном приложении дан ные посrупали бы из
другого источника, такого как текстовый файл, список свойств или веб-служба.
Затем добавьте над закры вающей фигурной с кобкой в конце файла код, пред­
ставлен н ы й в л исти н ге 8 . 2 .
Л истинг 8 . 2 . Методы источн и ков данных для табличного представления
// МАRК : / / МАRК : Т а Ы е V i e w D a t a S o u r c e M e t h o d s
f u n c t a Ы eV i e w ( t a Ы e V i ew : U I T a Ь l e V i e w ,
numb e r O f Row s i n S e c t i on s e c t i on : I n t ) - > I n t {
r e t u r n dw a rve s . c o u n t
f u n c t a Ы e V i e w ( t a Ы e V i ew : U I T a Ь l eVi e w ,
c el l Fo r RowAt i n de x P a t h : I ndex P a t h ) - > U I T a Ь l e V i ewCe l l
va r ce l l = t a Ы e V i e w . d e q u e u e Re u s a Ь l e Ce l l ( w i t h i de n t i f i e r :
s imp l e T aЬ l e i de n t i f i e r )
i f ( ce l l
nil ) {
ce l l = U I T a Ь l eV i ew C e l l (
s t y l e : U I T a Ы e V i e w C e l l S t y l e . de f a u l t ,
r e u s e i de n t i f i e r : s imp l e T aЬ l e i de n t i f i e r )
= =
ce l l ? . t e x t Lab e l ? . t e x t
return cell !
=
dwa rve s [ i ndex P a t h . row ]
Эти методы я вляются частью протокола U I Ta Ь l eViewDa t a S ource. Первый
из них, t a Ы eVi ew ( t a Ь l eView : U I T a Ь l eV i e w , numbe rOfRow s i n S e c t ion
s e c t i on : I nt ) - > I nt, испол ьзуется табл и цей для запроса о кол ичестве строк
в кон кретном разделе. Как можно ожидать, по умолчан и ю кол ичество разде­
лов равно еди н и це, и этот м етод будет вызы ваться для получения кол и чества
строк в этом одном разделе, составл яющем сп исок. Мы просто возвращаем ко­
личество элементов в нашем массиве.
Следующий метод, видимо, потребует определенного пояснения, так что рас­
смотрим его более внимател ьно:
func taЫeView ( _ taЫeView : U I TaЫeVi ew ,
ce l l Fo r RowAt i nde x P a t h : N S i ndex P a t h ) - > U I T a Ь l eVi ewCe l l {
Этот метод вызы вается табл и ч н ы м п редставлением, когда ему необходимо
в ы вести одну из с воих строк. Обратите в н и ман ие: вторы м аргументом этого
метода я вляется экземпляр класса N S i ndex Path. Это струкrура, которую таб­
лич ное представление испол ьзует для того, чтобы поместить раздел и и ндексы
строк в еди н ы й объект. Дл я того чтобы получ ить и ндекс строки ил и и ндекс
ГЛАВА 8 � В В ЕД Е Н И Е В ТА БЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
301
раздела из объекта класса N S i ndex P a t h, вы вызываете л ибо его свойство row,
либо свойство s e c t i on, и оба они возвращают целочисленное значение.
Перв ы й параметр, t a Ы eVi ew, я вляется ссыл кой на создаваемую табл и цу.
Это позволяет нам создавать классы, которые действуют в качестве источ н и ка
дан ных для нескол ьких табл иц.
Табл ичное п редставление может вы водить тол ь ко нескол ько строк за один
раз, но сама табл и ца может хран ить их знач ител ьно бол ьше. Пом н ите, что
каждая строка в табл ице представлена экзем пл яром класса U I TaЬleViewC e l l ,
которы й является подкл ассом класса U IVi ew, что означает, что каждая строка
может содержать дочерние представления . В случае больших табл и ц хранен ие
для каждой строки экземпляра ячейки табл и ч ного представления, независимо от
того, вы водится л и строка в настоящий момент, может при водить к огром н ы м
накладн ы м расходам . К счастью, таблицы работают нескол ько и наче.
Вместо этого, когда ячейки табл и чного представления исчезают с экрана, они
помещаются в очередь ячеек, доступных для повторного испол ьзован и я . Если
в системе оказы вается мало памяти, табл и ца будет избавляться от я чеек в этой
очереди . Однако пока система и меет некоторы й запас досту п но й памяти для
этих я чеек, она будет хран ить их на тот случай, если вы захотите использовать
их вновь.
Каждый раз, когда ячейка табл и ч ного представления исчезает с экрана, су­
ществует довол ьно бол ьшая вероятность, что другая ячейка поступает на экран
с другой стороны. Есл и эта новая строка может повторно использовать одну из
ячеек, которые уже исчезл и с экрана, то с истема с может избежать накладных
расходов, связан ных с постоя н н ы м созданием и освобождением этих представ­
лен и й . Дf1я того чтобы воспол ьзоваться преимуществами этого механизма, м ы
запраши вае м у табл и ч ного представления одну из освободи вшихся я чеек оп­
ределенного типа с испол ьзованием объявлен ного ранее идентификатора клас­
са N S S t r i n g. По сути, мы зап раш и ваем повторно испол ьзуемую ячейку типа
S irnp leTaЬ l e i dent i f i e r .
va r ce l l
t a Ы e V i e w . d e q u e u e Re u s a Ы e Ce l l ( w i t h i de n t i f i e r :
s i mp l e T a Ь l e i de n t i f i e r )
=
В этом примере табл ица испол ьзует только оди н тип я чеек, но в более слож­
ной таблице может потребоваться форматирование различных типов я чеек в за­
висимости от их содержания или позиции, и в этом случае придется испол ьзовать
отде.Jlьный идентифи катор я чеек табл ицы для каждого отдел ьного типа я чеек.
Впол не возможно, что табл ица не будет и м еть н и каких запасных ячеек ( на­
пример, когда они изначал ьно запол нены), поэтому после вызова м ы проверяем
значение переменной ce l l на равенство n i l . Есл и это так, то м ы вруч ную со­
здаем новую ячейку табличного представления с помощью той же самой строки
идентифи катора. В какой-то момент неизбежно повторное испол ьзование созда­
ваемой здесь я чейки, поэтому мы должн ы убедиться, что м ы создаем ее с по­
мощью s irnp leTaЬ l e ident i f i e r .
302
ГЛАВА 8 lfl В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П РЕДСТА В Л Е Н И Я
i f ( c e l l == n i l ) {
ce l l = U I T a Ь l e V i ewC e l l (
s t y l e : U I T a Ы e V i ewC e l l S t y l e . De f a u l t ,
r e u s e i de n t i f i e r : s imp l e T aЫ e i de n t i f i e r )
Вас заинтересовал юшсс U I TaЬ l eVi ewCe l l S t y l e . defaul t? Потерп ите не­
м ного - мы доберемся до него, когда будем рассматривать стил и ячеек табл ич­
ного представлени я .
Теперь у нас есть ячейка табл ичного представления, которую мы можем вер­
нуть табли це для испол ьзовани я . Таки м образом, достаточ но просто поместить
в нее и нформацию, которая должна отображаться в этой ячейке. Отображение
текста в строке табл ицы - очень распространенная задача, поэтому ячейки таб­
личного представления предоставл яют свойство класса U I Labe l под названием
t e x t Labe l , которое мы можем установить для отображения строк. Для этого
нам надо получить корректную строку из нашего массива dwa rve s и испол ьзо­
вать его для установки значения t e x t Labe l ячейки.
Однако, чтобы получить корректное значение, мы должны знать, какая стро­
ка табл ицы запрошена. М ы получаем эту и н формацию из с войства строки
i nd e x P a t h . Мы испол ьзуем номер строки табл и цы, чтобы получить соответ­
ствующую строку из массива, присвоить ее свойству t e xtLabe l . text ячейки,
а затем вернуть ее.
ce l l ? . t e x t Lab e l ? . t e x t = dw a rve s [ i n d e x P a t h . r ow ]
r e t u r n ce l l !
С ком пилируйте и запустите прил ожен ие, и у видите, как значения масси ва
отображаются в виде табли цы (рис. 8.7, слева).
У ч итателей может возни кнуть вопрос, зачем нужен оператор ? в этом коде.
ce l l ? . t e x t Labe l ? . t e x t = dwa r ve s [ i n d e x P a t h . r ow ]
Каждый случай испол ьзования оператора ? п редставляет собой при мер оп­
ционально й последовательности (optional chaining), позволяющей писать ком­
пактн ы й код, даже есл и вы вызываете метод или обращаетесь к свойствам ссыл­
ки на объект, которая может быть равной n i l . Перв ы й оператор ? требуется,
потому что ячейка может содержать значение n i l . Мы получ и м это значение,
вызвав метод dequeueRe u s a Ь l e C e l lWi t h i de n t i f i e r ( ) , возвращающий зна­
чение типа U ITa ЬleVi ewCe l l ? . Разумеется, ком п илятор не уч иты вает тот факт,
что м ы явно п роверяем, не равно л и возвращаемое значение ni l, и создает но­
вый объект класса U I TaЬleVi ewCe l l , гарантируя, что ячейка никогда не будет
содержать значение n i l , когда м ы достигнем этой строки кода. Обратитесь к
документации кл асса U I TaЬleVi ewCe l l , вы увидите, что свойство textLabe l
имеет тип U I Labe l ? , поэтому оно тоже может быть равным n i l . На самом деле
этого тоже н и когда не произойдет, потому что м ы по умолчанию испол ьзуем
экзем пляр U I T aЬ l eV i e w C e l l , который всегда вкл ючает метку. Естественно,
ГЛАВА 8 111 В В ЕДЕН И Е В ТАБЛ И Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
303
компилятор об этом не знает, поэтому мы испол ьзуем оператор ? при разыменова­
нии этого свойства. Эта ситуация часто встречается в програм мах на языке Swift.
Carrlef •
Sleepy
11 :ОО АМ
-
Sneezy
Bashful
Нарру
Doc
Grumpy
Dopey
Thorin
Dorin
Nori
Ori
Вalin
Dwalin
Fili
Kili
Рис. 8 . 7 . П р иложе н и е S i m p l e ТаЫ е ,
де м о н ст р и рующее масс и в
Добавл ение изобра ж ения
Было бы неплохо, есл и бы м ы могл и добав ить в каждую строку изобра­
же ние. Можно предположить, что дл я этого м ы должны создать подкл асс
U I TaЬleVi ewCe l l ил и добавить дочерние представлени я . На самом деле, есл и
вы согласны на то, чтобы изображен ие находилось на левой стороне каждой
строки, ничего делать не нужно. Ячейки табл ичного представления по умолча­
нию впол не могут обработать эту ситуацию. Давайте убедимся в этом.
Пе R етащите файл ы s t a r . png и s tar2 . png из папки 08 - S t a r Image архива
исходных кодов в папку As s e t s . x c a s s e t s проекта, как показано на рис. 8 . 8 .
М ы планируем разместить эти п и ктограммы в каждой строке табл и ч ного
представлен ия. Для этого достаточно создать объект класса U I Image для каж­
дой из них и вы полнить присваивание объекту класса U I TaЬ l eVi ewCe l l, когда
табличное представление запросит источн и к данных для ячейки в каждой стро­
ке. Для этого в файле ViewContro l l e r . swi ft модифициру йте метод taЬleVi
ew ( : ce l l Fo rRowAt i ndexPath : ) , как показано в листин ге 8.3 .
304
...
ГЛАВА 8 fli В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТА В Л Е Н И Я
. ,.. ...... ,.... · �"
ei п et. & G • -o •
" . ..... t....
1.1 <
· --
. ..,
•
· �·--
.
· ­
-
11'"
......,
°'"'-
-----
..,,,.,. " °'-
•
-"
-- ---__.._....,.
"""""....,._
..... ,..... 1"
о
--
-
--
'
, -­
• .._ ...,. ,R/11
{) о 0 (J
1 ' '!;�• · · ·
Ц н�t�с•i
--
�·
•
.. . . . . . . . . . . .... . . . . . . . . . . . . . ... . . . . .
1
,... " � A ­
- - • MI - - - �
_ _ ... _ _
" .. . .. . . . "" . . ... . . . . . . . ..
Рис . 8 . 8 . Добавл е н и е изоб раже н и й в п а п ку As s e t s . xca s s e t s
Листинг 8 . 3 . Модификация метода для добавления изображения в каждую ячейку
f u n c t a Ь l e V i e w ( t a Ь l e V i e w : U I T a Ь l eV i e w ,
ce l l Fo r RowAt i ndex P a t h : I ndex P a t h ) - > U I T a Ь l e V i e w C e l l
va r ce l l = t a Ы e V i e w . d e q u e u e Re u s a Ь l e C e l l ( w i t h l de n t i f i e r :
s i mp l e T a Ь l e i de n t i f i e r )
i f ( ce l l
nil ) {
c e l l = U I T a Ы e V i ewc e l l (
s t y l e : U I T a Ь l eV i e w C e l l S t yl e . de f a u l t ,
r e u s e l de n t i f i e r : s i mp l e T a Ь l e i de n t i f i e r )
==
l e t i m a g e = U I I ma g e ( n amed : " s t a r " )
c e l l ? . imageVi e w ? . i m a g e = i m a g e
l e t h i g h l i gh t e d i ma g e = U I I m a g e ( n amed : " s t a r 2 " )
c e l l ? . imageV i ew ? . h i gh l i gh t e d i m a g e = h i g h l i g h t e d i ma g e
c e l l ? . t e x t Lab e l ? . t e x t = dwa r ve s [ i n d e x P a t h . r o w )
return cell !
Это все. Каждая ячейка и м еет с войство imageView типа U I Image, которое,
в свою очередь, имеет свойство image, а также свойство highl i ghted lmage.
Изображение, задаваемое свойством image, поя вляется слева от текста ячейки и,
когда ячейка выбрана, заменяется на highl i ghtedlmage, есл и таковое имеется .
Вы просто присваи ваете с войствам ячейки ima geVi ew . ima ge и imageVi ew .
h i gh l i ghtedimage изображения, которые хотите отобразить.
ГЛАВА 8 ,�1 В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
305
Есл и сейчас вы ском пилируете и запустите приложение, то должн ы получить
сп исок с м ножеством красивых маленьких голубых звездочек слева от каждой
строки (рис. 8 .9). Есл и вы в ыберете л юбую строку, то звездочки в ней станут
зелен ы м и . Конечно, мы могл и бы в кл юч ить различные изображения для каждой
строки в табл и це ил и, немного потрудивш ись, ис11ользовать разные пиктограм­
м ы для разных категорий персонажей произведений Диснея и Тол киена.
Carri.r �
•
Sleepy
•
Sneezy
•
Вashful
•
Нарру
•
•
Grumpy
Dopey
•
Thorin
•
Dorin
•
Nori
•
Ori
•
Balin
•
"
Doc
•
•
11:23 АМ
Dwalin
Fili
Kili
Рис . 8 . 9 . М ы и с п ол ьзуем с в о й ство я ч е й к и
ima g e V i e w дл я добавл е н и я и з о б раже н и я в
каждую я ч е й ку табл и ч н ого п р едставл е н и я
ЗАМЕЧАНИЕ. Класс U I Image использует механизм кеш ирования на основе имен фай ­
лов , поэтому он не будет загружать н о вое свойство изображе н и я каждый раз при
вы;юве u I Image ( name d : ) . Вместо этого будет испол ьзоваться уже ке ш и рованная
верс и я .
Использование стилей ячеек табличных представлений
Д о сих пор, работая с табл и ч н ы м п редставл е н и е м , м ы и с 11 ол ьзовал и
стил ь ячейки п о умолчанию (см. рис. 8.9), представленн ы й константой стил я
U I T a Ь l eViewCe l l S t y l e . de faul t . Однако класс U I TaЬleViewC e l l вкл юча­
ет нескол ько других предопределенных стилей ячеек, что позвол ит вам легко
306
ГЛАВА 8 !;\\ В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
добавить нем ного больше разнообразия в табличные представления. Эти стил и
используют три элемента ячеек.
11
И зо б раже н и е . Есл и изображение я вляется частью указанного стиля, оно
отображается слева от текста ячейки .
11
Те кстовая метка. Это основной текст ячейки. В испол ьзован ном ранее
стиле U I T aЬ l eVi ewCe l l S t y l e . d e f a u l t текстовая метка предста вляет
собой единственный текст, отображаем ы й в ячейке.
m
П одр о б ная текстовая метка .
Это вспомогател ь н ы й текст я ч ей ки, как
правило, испол ьзуем ы й в качестве пояснения.
Для того чтоб ы у видеть, на что похожи эти новые допол нения, добавьте
следующий код в метод t a Ы eV i e w ( _ : c e l l For RowAt i nde x P a t h : ) в файле
ViewContro l l e r . swi f t :
i f i n de x P a t h . r ow < 7 {
ce l l ? . de t a i l T e x t Labe l ? . t e x t
else {
ce l l ? . de t a i l T e x t Labe l ? . t e x t
=
"Mr Disney"
=
"Mr Tolkien"
Поместите этот код в текст метода непосредственно перед строкой ce l l ? .
textLabe l ? . text dwa rve s [ i ndex Path . row ] .
Итак, м ы задали подробный текст ячейки. М ы испол ьзуем строку "Mr . Di sney"
для первых семи строк и "Mr . T o l k i e n " для остал ь н ых. Когда вы запустите
этот код, каждая ячейка будет выглядеть так же, как и ран ьше (рис. 8 . 1 О). Это
связано с тем, что м ы испол ьзуем стил ь U I TaЬleVi ewCe l l S t y l e . de faul t, ко­
торый не испол ьзует подробн ы й текст.
=
1
•
Sneezy
Рис . 8. 1 О. Стил ь ячеек по умол ч а н и ю в ы в одит изоб ­
раже н и е и те кст в одн у строку
Теперь замените стил ь U I T a Ь l eVi ewCe l l S t y l e . d e f a u l t стилем U I TaЬle
Vi ewCe l l S t y l e . s ubt i t l e
i f ( ce l l
nil ) {
cell
U I T a Ь l eVi ewCe l l (
s t y l e : U I T aЬ l eV i ewC e l l S t y l e . s u b t i t l e ,
r e u s e i de n t i f i e r : s imp l e T aЫ e i de n t i f i e r )
= =
=
С нова запустите приложение. В этом случае в ы увидите оба текстовых эле­
мента, оди н под другим (рис. 8 . 1 1 )
.
ГЛАВА 8 Z11 В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
Caггlltf ?
•
•
•
•
•
•
•
•
•
•
•
•
•
•
Sleepy
307
-
Mr Dlst18y
Sneezy
Мr Olsney
8ashful
Мг Olsney
Нарру
Mr Disnty
Doc
Mr Disney
Grumpy
Мг Dlsnay
Dopey
Мг Di1nev
Thorin
Мr Tolkten
Dorin
Мf Tolklon
Nori
Mr Tolklen
Ori
Мг Tolkien
Вalin
Mr Tolkien
Dwalin
Mr Tolklen
Fili
Мt Tolkten
Kili
Рис . 8 . 1 1 . Стил ь подзагол о в ка в ы в о ­
дит подроб н ы й текст бол ее м е л к и м
с е р ы м ш р и фтом п од текстом метки
Замен ите стил ь U I T aЬ l eVi ewCe l l S t y l e . s uЬt i t l e стилем U I T aЬ l eView
Ce l l S t y l e . va lue l и вновь перестройте и запустите приложение. В этом слу­
чае вы увидите оба текстовых элемента в одной строке, но в разных частях
ячейки (рис. 8 . 1 2).
Наконец замен ите стил ь U I T a Ь l eVi ewCe l l S t y l e . va l ue l стилем U I T a Ь l e
Vi ewCe l l S t y l e . va l ue 2 . Этот формат часто испол ьзуется для отображения ин­
формаци и вместе с описател ьной меткой. При этом п и ктограмма не вы водится,
а подробный текст помещается слева от текста метки (рис. 8. 1 3 ) . В этом случае
подробн ы й текст выступает в качестве метки, описы вающей тип дан ных, хра­
нящихся в текстовой метке.
После того как вы ознаком ил ись с досту п н ы м и стил я м и я чеек, вернемся к
стилю U I T a Ь l eVi ewCe l l S t y l e . d e f a u l t, прежде чем продолжить работу. Да­
лее в главе вы узнаете, как настроить внеш н и й в ид табл ицы . Однако, прежде
чем вы реш ите сделать это, убедитесь, что ни один из доступных стилей я чейки
не позволяет сделать то, что вы хотите получить.
308
ГЛАВА 8 "' В В ЕД Е Н И Е В ТАБ Л И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
�
Carrier ?
•
1 1 : 5 О АМ
Sleepy
Мг D1sney
•
Sneezy
•
Bashful
Мг D1sney
•
Нарру
•
Мг D1sney
Doc
Мг D1s11ey
•
Gгumpy
Мг l)isney
•
Dopey
•
Мг D1s11ey
Thorin
Мг Tolk1en
•
Dorin
Mr Tolkie11
•
•
Nori
Огi
• Balin
•
Dwalin
•
Fili
Kili
-
М г D1s11ey
М г Tolkien
М г Tolk1e11
Mr To lk1e11
Мг To lk1e11
Мг Tolk1en
М г Tolkien
Carrier .,,.
1 1 : 5 3 АМ
Sleepy M r Oi1ney
-
Snne1y Mr Dl1ney
B •shtul M r Dlsney
1-<1рру Mr Dlsney
Оос M r Dlsney
Grumpy M r Dlsney
Dop•y Mr Dlsney
rt)orsn M r Tolklen
Donn Mr Totklen
No1 t Mr Tolkien
Or M r Tolkien
BaJ1n M r Tolkien
OwAlln M r Tolkien
Fil• Mr Tolkien
Kil1 M r Tolklen
Рис . 8 . 1 2 . Стил ь va l u e l в ы в о ­
Рис . 8 . 1 3 . Сти л ь v a l u e 2 не в ы ­
д и т п одроб н ы й те кст голуб ы м и
водит п и ктогра м м у и в ы в одит
буква м и , в ы р о в н е н н ы м п о п р а ­
подроб н ы й те кст голуб ы м и бук ­
в о й гра н и це я ч е й к и
вам и слева от те ксто вой м етки
Вы могл и заметить, что мы сделал и наш контроллер как источ ником дан ных,
так и делегатом для этого табл и чного представления, но до сих пор м ы факти­
чески не реал изовал и ни оди н из методов протокола U I T a Ь l eVi ewDe l e g a t e .
В отл и ч ие от представлен и й селектора, более простые табличные представления
не требуют использования делегатов для своего фун кцион ирован ия. Источник
данн ы х предоставля ет все необходимое для вы вода табл ицы. Цель делегата настрой ка внешнего в ида табл ич ного представления и обработка определенного
взаимодействия с пол ьзователем . Давайте взгля нем на некоторые из настроек
конфигураци и . Остал ьные настройки рассмотри м в следующей главе.
Н астройка уровня отступа
Делегат может быть испол ьзован для указания того, что некоторые строки
должн ы иметь отсту п . В файле V i e wC o n t ro l l e r . s w i f t добавьте к вашему
коду следующий метод:
ГЛАВА 8 !t В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТА В Л Е Н И Я
309
1 1 MARK : 1 1 MARK : Т а Ы е V i e w de l e g a t e M e t h o d s
func taЫeView ( taЬleView : U I TaЬleView ,
_
i n de n t a t i o n L e v e l Fo r RowAt i nd e x P a t h : I nde x Pa t h )
r e t u r n i n dex P a t h . r ow % 4
-
> Int {
Этот метод задает у рове н ь отсту п а для каждой строки на основе ее н оме­
ра, так что строка О будет иметь нулевой уровень отступа, первая строка будет
иметь урове н ь отступа 1 и т.д. Нал ичие оператора % при водит к тому, что от­
ступ для четвертой строки становится нулевым и цикл повторяется. Уровен ь
отступа - это просто целое число, которое говорит табличному представлению
о необходи мости сместить строку нем ного вправо. Чем бол ьше это ч исло, тем
дал ьше вправо будет смещена строка. Вы можете испол ьзовать эту методи ку,
например, чтобы у казать, что одна строка подч инена другой строке, - точ но
так же, как приложение Mai l показы вает вложенные папки.
При повторном запуске прил ожения вы можете у видеть, как каждая строка в
блоке из четырех строк оказы вается немного правее предыдущей (рис. 8 . 1 4 ) .
Carrler •
•
Sleepy
•
Sneezy
•
Bashful
•
Doc
•
Grumpy
•
Dopey
Thorin
•
Dorin
•
Nori
•
-
Н а рру
•
•
11:69 At.4
Огi
Вalin
•
•
Dwalin
•
Fill
Kili
Рис . 8. 1 4 . Стр о к и табл и цы с отступа м и
310
ГЛАВА 8 !11 В В ЕД ЕН И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
Обработка выбора строки
Делегат табл и цы может испол ьзовать два метода для обработки выбора
пол ьзователем некоторой строки. Оди н из методов вызы вается перед выбором
строки и может испол ьзоваться для предотвращения выбора строки и даже для
изменения этого в ыбора. Реал изуем этот метод и укажем, что первая строка
не может быть выбрана. Добавьте при веде н н ы й далее метод в конец ф айла
ViewContro l l e r . swi f t .
f u n c t a Ь l eV i e w ( _ t a Ь l e V i e w : U I T a Ы e V i e w ,
w i l l S e l e c t RowAt i ndex P a t h : I nd e x P a t h ) - > I n dex P a t h ? {
r e t u r n i n d e x P a t h . row
О ? n i l : i ndex P a t h
==
Этот метод получает объект indexPath, соответствующий элементу, который
будет выбран. Наш код проверяет, какая строка была выбрана. Есл и это первая
строка с нулевым и ндексом, то метод возвращает значение n i l, указы вающее,
что строка не должна быть выбрана. В проти в ном случае возвращается не мо­
дифицированное значение indexPath
так м ы у каз ы ваем, что процесс выбора
можно продолжить.
Перед тем как ском п ил и ровать и запустить приложение, реализуем также ме­
тод делегата, который вызы вается после того, как строка была выбрана, и кото­
рый, как правило, и представляет собой обработч и к выбора. Здесь вы можете
предприн имать л юбые действия, связан ные с выбором строки пол ьзователем.
В следующей главе м ы будем испол ьзовать этот метод для обработки представ­
лений с подробн ы м отображением, а в этой главе просто вы ведем сообщение
о выбранной строке. Добавьте в конец файла Vi ewC o n t ro l l e r . swi ft метод,
приведенны й в л истин ге 8.4.
-
Л истинг 8 . 4 . Вы вод сообщения, когда пользователь касается строки
f u n c t a Ы e V i e w ( t a Ь l e V i e w : U I T a Ь l e V i e w , d i d S e l e c t RowAt i ndex P a t h :
I ndex P a t h ) {
l e t rowVa l u e
dwa rve s [ i nde x Pa t h . r ow ]
l e t me s s a g e
" Y o u s e l e c t e d \ ( rowVa l u e ) "
=
=
l e t c on t r o l l e r
U I A l e r t C o n t r o l l e r ( t i t l e : " Row S e l e c t e d " ,
me s s a g e : me s s a g e , p r e f e r r edS t y l e : . a l e r t )
let action
U I A l e rtAc t i o n ( t i t l e : " Y e s I D i d " ,
s t y l e : . de fa u l t , h a n d l e r : n i l )
c o n t r o l l e r . addAc t i on ( a c t i o n )
p r e s e n t ( co n t r o l l e r , a n i m a t e d : t r ue , comp l e t i o n : n i l )
=
=
Добавив этот метод, ском пилиру йте и запустите приложение. Проверьте,
сможете ли вы выбрать первую строку (это у вас не должно получ иться), а
затем в ыберите одну из остальных строк. Выбранная строка должна стать под­
свеченной, а на экране поя вится сообщение о том, какая строка была выбрана
(рис. 8 . 1 5 ) .
ГЛАВА 8 к В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТА ВЛ Е Н И Я
31 1
Рис . 8 . 1 5 . В этом п р и м е ре п е р вую строку
вы б рать н е возможн о , а при в ы боре л юбой
другой строки в ы водится сооб ще н и е
Вы можете измен ить значение объекта i ndexPath, прежде чем передать его
обратно, что приведет к выбору другой строки и/ил и раздела. Вряд л и вы бу­
дете прибегать к такому методу часто, так как для этого нужны веские осно­
вания. В подавляющем большинстве случаев, испол ьзуя метод taЬleView ( _ : w
i l l S e l e c t RowAt i ndex Pa t h : ) , вы л ибо возвращаете переменную i ndexPath
неизмененной, чтобы позволить выбор, л ибо возвращаете значение n i l, что­
бы запретить его. Есл и вы действител ьно хотите изменить выбран ную строку
и/ил и раздел, испол ьзуйте метод N S i ndex Path ( forRow : , i n S e c t i o n : ) , чтобы
создать новы й объект класса N S i nde x Path и вернуть его. Н апример, код, при­
веденный в листин ге 8 . 5 , гарантирует, что есл и в ы попытаетесь выбрать четную
строку, то на самом деле выберете строку, которая следует за ней.
Л исти нг 8 . 5 . Возвращение следующей строки
func taЬleView ( taЬleView : U I TaЬl eView ,
w i l l S e l e c t RowAt l nde x Pa t h i n dex Pa t h : N S i ndex P a t h )
- > N S i ndex P a t h ? {
i f i n dex P a t h . r ow = = О {
return n i l
0) {
} e l s e i f ( i nde x P a t h . row % 2
31 2
ГЛАВА 8 ii;( В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
r e t u r n N S i ndex P a t h ( r ow : i nde x Pa t h . r ow + 1 ,
s e c t i o n : i n d e x P a t h . s e c t i on )
else {
return indexPath
Изменение размера шрифта и в ысоты строки
Предположи м , мы хоти м изм е н ить размер шрифта, испол ьзуемого в таб­
л и чном представлении. В больши нстве случаев вы не должны переопределять
шрифт, заданн ы й по умолчан ию, так как это именно тот шрифт, которы й ожи­
дают увидеть пол Ь1овател и . Однако иногда бы вают веские причины, чтобы из­
менить этот шрифт. Добавьте следующую строку кода в метод taЫeView ( _ : с
e l l ForRowAt i ndexPath : ) :
f u n c t a Ь l e V i ew ( t a Ь l e V i e w : U I T a Ь l e V i e w ,
ce l l F o rRowAt i ndex P a t h : I ndex Pa t h ) - > U I T a Ь l e V i e wC e l l
va r c e l l
t a Ы e V i e w . d e qu e u e Re u s a Ь l e C e l l ( w i t h l de n t i f i e r :
s i mp l e T aЬ l e i de n t i f i e r )
i f ( ce l l
nil ) {
cell
U I T a Ы e V i ewCe l l (
s t y l e : U I T aЬ l e V i ewCe l l S t y l e . de f a u l t ,
r e u s e l de n t i f i e r : s imp l e T a Ь l e i de n t i f i e r )
=
= =
=
l e t image
U I I m a g e ( n amed : " s t a r " )
c e l l ? . ima g e V i ew ? . ima g e
ima g e
l e t h i g h l i gh t e d l m a g e
U I I m a g e ( n ame d : " s t a r 2 " )
c e l l ? . ima g e V i ew ? . h i g h l i g h t e d i ma ge = h i g h l i g h t e d lmage
=
=
=
i f i n de x P a t h . row < 7 {
c e l l ? . de t a i 1 T e x t Labe 1 ? . t e x t
else {
c e l l ? . de t a i l T e x t La b e 1 ? . t e x t
=
=
"Mr Di s ne y "
"Mr To1kien"
c e l l ? . textLabel ? . text
=
dwa rve s [ i ndex P a t h . r ow ]
cel l ? . textLaЬel ? . font
=
U I Font . boldSys temFont ( o f S i ze : 5 0 )
1 1 Добавьте спедующую строку
r e t u r n ce l l !
Теперь, когда вы запустите приложение, значения в списке будут вы водиться
шрифтом большого размера, но не будут помещаться в строке (рис. 8 . 1 6).
Существуют два способа исправления ситуации . Для начала м ы можем ука­
зать табл и це, что все строки должн ы и меть заданную ф и ксированную высоту.
Для этого устанавл и ваем ее свойство rowH e i ght :
t a Ы e V i e w . r owHe i g h t
=
70
Есл и же требуется, чтобы разные строки и м ел и разную высоту, мож­
но реализовать метод t a Ь l eVi ew ( _ : he i ght For RowAt i ndex P a t h : ) делегата
U I TaЬleViewDe legate. Добавьте приведенный ниже метод в класс контроллера.
ГЛАВА 8 м В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П РЕДСТАВ Л Е Н И Я
313
f u n c t a Ь l e V i e w ( _ t aЬ l eVi e w : U I T a Ь l eV i e w ,
h e i g h t Fo r RowAt i nd e x P a t h : I n dex P a t h ) - > C G F l o a t
r e t u r n i n dex P a t h . row
==
О ? 120
: 70
М ы тол ько что указал и табл ич ному представлению, что строки должны быть
высотой 70 п и кселей, за исключен ием немного бол ьшей первой строки. С компи­
лируйте и запустите приложение, и в ы увидите, что строки стали существен но
выше (рис. 8 . 1 7).
Sl eepv
Sn e e z v
"
Bashful
"
Нарру
• Doc
• G rumpv
•
Dopev
•
Thorin
• Dorin
• Nori
"
Ori
•
Balin
" Dwalin
• Fil i
Рис . 8 . 1 б . И з м е н е н и е ш р и фта ,
испол ьзуе м ого дл я вы вода я ч е ­
е к табл и ч н ого п редставл е н и я
-
Camer •
•
Sl ee py
•
Sneezy
•
Bashful
Нарру
• Doc
• G rumpy
•
•
•
Dopey
Thorin
Рис. 8 . 1 7 . И з м е н е н и е в ы соты
стро к табл и ч н ого п редставл е н и я
с п о м о щью дел е гата . О б ратите
в н и м а н и е н а н е с колько бол ьш и й
раз м е р п е рвой строки
Есть и дру гие задач и, которые может реш ить делегат, но бол ь шинство из
них возникают, когда вы начинаете работать с иерархически м и дан н ы м и , а об
этом мы поговорим в следующей главе. Для того чтобы получить допол нител ь­
ную и нформацию, испол ьзуйте браузер документации для изучен и я протокола
UITaЬleVi ewDe l e g a t e и посмотрите, какие еще методы досту п н ы .
314
ГЛАВА 8 :9i В В ЕДЕН И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВ Л Е Н И Я
Н а стр ой ка я ч ее к табл и ч ного п редставления
Можно оче н ь м ногое сделать с табл и ч н ы м и представлен и я м и без внесе­
ния измене н и й, но часто требуется форматировать дан ные дл я каждой стро­
ки таки м нетривиал ьн ы м образом, что он п росто не поддержи вается классом
U I TaЬleVi ewCe l l непосредственно. В таких случаях есть три основных г�одхо­
да: оди н из н их предусматривает програм м ное добавление дочерних представле­
н и й в класс U I TaЬleVi ewCe l l при создани и ячейки, второй вкл ючает загрузку
м ножества дочерних представлен и й из n i Ь-файла, а третий загружает я чейки
из раскадровки. В этой главе м ы рассмотри м две первые технологии, а пример
создания ячейки из раскадровки будет приведен в главе 9.
Д обавление дочерних представлений
к ячейкам табличного представления
Дл я того чтобы показать, как использовать пол ьзовател ьские я чейки, мы
собираемся создать новое приложение с другим табл и ч н ы м представлением .
В каждой строке будем вы водить две строки информаци и (рис. 8 . 1 8). Наше
приложение будет отображать название и цвет ряда потен циал ьно знаком ых
ком п ьютерных моделей, и м ы будем в ыводить обе части и нформации в одной
ячейке табл и цы, добавляя дочерние представления в ячей ку табл ичного пред­
ставления .
Р е ал и з ац ия приложен ия с пол ь з ова те льски ми
табл и ч н ы ми п редставления ми
Создайте новый проект в среде Xcode с испол ьзованием шаблона S i ngle View
Application . Назовите проект Т а Ы е Ce l l s . Испол ьзуйте настройки предыдущего
проекта. Щелкн ите на пункте Ma in . s t o r yboa rd, чтобы отредактировать граф и­
ческий интерфейс в програм ме I nterface B u i lder.
Добавьте в главное представление таблич ное представление и измените его
так, чтобы оно зан и мало все представлен ие, за искл ючением того, что верхняя
часть табл ицы должна быть в ы ровнена по н ижней части строки состоя ния, а
не по верхней части представлен и я . Испол ьзуйте инспектор связей для задания
источн и ка данн ы х для контроллера представления, как м ы это делали для прос­
той табл ицы приложения. Затем испол ьзуйте кнопку Pin в н ижней части окна
для создания огран ичений между края м и табл и цы п редставления и края ми его
родител ьского элемента и строкой состоя н и я . В ы можете испол ьзовать те же
настрой ки, что и показанные на рис. 8 . 5 , так как значения, которые вы укажете
в полях в вода в верхней части вспл ы вающего окна, по умол чанию я вляются
расстоя н и я м и между табл и ч н ы м представлен ием и ее бл ижай ш и м соседом во
всех четырех направлениях. В закл ючение сохраните раскадровку.
ГЛАВА 8 • В В ЕДЕН И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
С.1._, 9'
_,
a:•I Pt.4
МэсВооk Alr
....,., Silver
31 5
-
н.�м:
масВооk Pro
....,, Silver
н.,,.., 1Мас
cotot Silver
Н•те' Мзс Mini
eoto,. Silver
,..,,,.. Мае Pro
с_, Вlack
Рис . 8 . 1 8 . Доба вл е н и е доч е р н е го предста в ­
л е н и я в я ч е й ку табл и ч н о го п редста вл е н и я
позвол я ет получ ить м н огостроч н ы е я ч е й ки
Создание под кл асса U ITaЫeViewCell
До сих пор все детал и макета я чеек автоматически определял ись стандарт­
ным табличным представлением . В нашем коде контроллера не было запутанных
деталей, регламентирующих, где должны размещаться метки и изображения, что
позволяло просто передавать значен и я в ячей ки, не заботясь об их внешнем
виде. Таким образом, проблемы презентации был и в ынесены за предел ы конт­
роллера, что представляло собой несом ненное пре и мущество. В нашем проекте
мы создадим подкласс класса U I T aЬ l eV i e wC e l l для новой ячейки, которы й
будеl' самостоятельно определять детал и макета, чтобы наш контроллер был как
можно более просты м .
Добавление новых ячеек
Выберите пап ку ТаЫе Ce l l s в окне навигатора проекта и нажм ите комби­
нацию клавиш <X+N>, чтобы создать новый файл . В откры в шемся окне по­
мощн ика выберите пиктограм му Сосоа Touch C lass из раздела IOS и щелкните
на кнопке N ext. На следующем экране введите строку NameAndC o l o rC e l l в
316
ГЛАВА 8 т! В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
качестве и м е н и класса, в ыберите пункт U I TaЫeViewCe l l в о вспл ы вающем списке
S u bclass of, снова щел кните н а кнопке N ext и на последнем экране щел кн ите на
кнопке C reate .
Выберите файл NameAndC o l o rCe l l . s w i ft в окне навигатора проекга и до­
бавьте в него следующий код:
c l a s s NameAndC o l o r C e l l : U I T a Ь l eV i ewCe l l
var name : String = " "
var color : String = " "
var nameLaЬel : UI LaЬel !
var colorLaЬel : UI LaЬel !
Здесь м ы определили два свойства (name и c o l or) и нтерфейса я чейки, кото­
рые наш контроллер будет испол ьзовать для передачи значени й каждой ячейке.
Мы также добавил и пару свойств, которые будем испол ьзовать для обращения к
некоторым дочерним представлениям, которые будут добавлены к нашей ячейке.
Она будет содержать четыре дочерних представления, два из которых - метки
с ф и ксирован н ы м содержим ы м , а два других - с содерж и м ы м , которое будет
изменяться для каждой строки.
Это все свойства, которые требовалось добавить, так что перейдем к коду.
М ы дол ж н ы перекрыть и н и ци ал и затор я ч е й ки табл и ч ного п редставления
i n i t ( s t y l e : reu s e i dent i f i e r : ) и добавить код для создания представлений,
которые нам надо будет выводить (листин г 8.6).
Л и стинг 8 . 6 . Метод i n i t ( ) ячейки табличного представления
ove r r i de i n i t ( s t y l e : U I T aЫ e V i ewC e l l S t y l e , r e u s e i de n t i f i e r : S t r i n g ? )
s up e r . i n i t ( s t y l e : s t y l e , re u s e i de n t i f i e r : r e u s e l d e n t i f i e r )
l e t name L ab e l Re c t
CGRect ( x : О , у : 5 , w i d t h : 7 0 , h e i g h t : 1 5 )
l e t nameMa r k e r
U I Labe l ( f rame : n ame L a b e l R e c t )
n ameMa r ke r . t e x tAl i g nme n t = N S T e x tAl i g nme n t . r i g h t
n ameMa r ke r . t e x t
" N ame : "
n ameMa r ke r . f o n t
U I Font . b o l d S y s temFont ( o f S i z e : 1 2 )
c o n t e n t V i e w . a ddS ubvi ew ( n ameMa r ke r )
=
=
=
=
l e t c o l o r L a b e l Re c t
CGRe c t ( x : О , у : 2 6 , w i dt h : 7 0 , h e i gh t : 1 5 )
l e t c o l o rMa r ke r = U I Labe l ( f r ame : c o l o r L a b e l Re c t )
c o l o rMa r ke r . t e x tAl i g nme n t
N S T e x tAl i g nme n t . r i g h t
c o l o rMa r ke r . t e x t = " Co l o r : "
c o l o rMa r ke r . f o n t = U I Font . b o l d S y s temFont ( o f S i z e : 1 2 )
c o n t e n t V i e w . addS ubvi e w ( c o l o rMa r ke r )
=
=
l e t n ameVa l u e R e c t = C G Re c t ( x : В О , у : 5 , w i d t h : 2 0 0 , h e i g h t : 1 5 )
n ame Lab e l
U I L a b e l ( f r ame : nameVa l u e Re c t )
c o n t e n tV i ew . addS ubvi ew ( n ame L a b e l )
=
l e t c o l o rV a l u e R e c t
CGRect ( x : В О , у : 2 5 , w i d t h : 2 0 0 , h e i g h t : 1 5 )
c o l o rLabe l = U I L a b e l ( f r ame : c o l o rV a l u e R e c t )
c o n t e n t V i e w . addS ubvi ew ( c o l o r L a b e l )
=
ГЛАВА 8 � В В ЕД Е Н И Е В ТА БЛ И Ч Н Ы Е П Р ЕДСТАВ Л Е Н И Я
317
Это довольно просто. М ы создал и четыре метки т и п а U I Labe l и добави­
л и их в ячейку табл и ч ного п редставления . Ячейка табл и ч ного п редставления
уже содержит дочернее представлен ие класса UIView с именем contentVi ew,
которое испол ьзуется для гру п пи рован ия всех дочерних представлений. В ре­
зультате нам удалось избежать добавления меток как дочерних п редставлений
непосредственно в ячейку табл ичного представлен и я . Мы просто добавили их
в объект contentView.
Две из этих меток содержат статически й текст. Метка nameMa r ke r содержит
текст Name : , метка c o l o rMa r ke r - текст C o l o r : . Это метки, которые мы не
будем изменять, но обе они содержат текст, выровнен н ы й по правому краю с
помощью атрибута NSTextAl i gnment . r i g h t .
Оставшиеся две метки испол ьзуются для вывода дан ных, зависящих от стро­
ки. Напом н и м , что позже нам потребуется с пособ оп ределения содержи мого
этих полей, поэтому сохраняем ссыл ки на н и х в свойствах, которые объявил и
ранее .
Поскол ьку м ы переоп редел ил и назначен н ы й и н ициал изатор кл асса ячейки
табличного представления, ком п илятор языка Swift требует от нас п редоставить
также реал изаци ю и н и циал изатора i n i t ( code r : ) . Этот и н и циал изатор н и когда
не будет вызы ваться в нашем примере приложения, так что просто добави м три
следующие строки кода:
requ i r e d i n i t ? ( c ode r a De c ode r : NS Code r ) {
f a t a l E r r o r ( " i n i t ( c o d e r : ) h a s n o t b e e n i mp l eme n t e d " )
В главе 1 3 м ы подробно рассмотрим этот и н ициализатор.
Теперь внесем в кл асс NameAndC o l o rCe l l последние изменения - добави м
логику установки свойств name и c o l o r . Измени м объявления этих свойств сле­
дующим образом :
var name : S t r i n g = " " {
d i dS e t {
i f ( n ame ! = o l dVa l u e )
name Lab e l . t e x t = n ame
var c o l o r : S t r i n g = " " {
didSet {
1 f ( c o l o r ! = o l dVa l u e )
c o l o r Lab e l . t e x t = c o l o r
Здесь м ы добавляем код, чтобы убедиться, что при измене н и и значения
свойства name ил и c o l o r свойству t e x t соответствующей метки в той же ячей­
ке табл ицы присваи вается это же значение.
318
ГЛАВА 8 111 В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТА В Л Е Н И Я
Реализация кода контроллера
Нап ишем п ростой контроллер, отображающ и й дан н ые в новых ячейках,
внеш н и й вид которых мы оп редел ил и самостоятел ьно. Откройте файл View
Cont ro l l e r . swi ft и добавьте в него код из л исти н га 8.7.
Листи н г 8 . 7 . В ывод значений в пользовательской ячейке
c l a s s V i ewCont r o l l e r : U I V i ew C o n t r o l l e r , UI TaЬleViewDataSource
l e t c e l l T aЬ l e i de n t i f i e r = " Ce l l T aЬ l e i de n t i f i e r "
@ I BO u t l e t v a r t a Ь l eVi ew : U I T a Ь l e V i e w !
l e t comp u t e r s = [
" M a cBoo k A i r " , " C o l o r " : " S i lve r " ] ,
[ " Name "
[ " Name "
" Ma c Bo o k P r o " , " C o l o r " : " S i l ve r " ] ,
[ " Name "
" i M a c " , " Co l o r " : " S i lve r " ] ,
[ " Name "
" М а е M i n i " , " Co l o r " : " S i l ve r " ] ,
[ " N ame "
"Мае P ro " , " C o l o r " : " Bl a c k " ]
ove r r i de f u n c v i e w D i dLoad ( )
supe r . view DidLoad ( )
1 1 Дополни т ел ь н а я н а строй ка предс т а влени я п о сле за грузки
t a Ь l e V i e w . r e g i s t e r ( N ameAndCo l o r C e l l . s e l f ,
f o r C e l l Re u s e i de n t i f i e r : c e l l T aЬ l e i de n t i f i e r )
М ы сделал и наш контроллер соответствующим п ротоколу U I T a Ь l eV i e w
D a t a S ource, а также добавил и и м я идентификатора ячейки и массив словарей .
Каждый словарь содержит имя и и нформацию о цвете для одной строки в таб­
л и це. Название для этой строки хранится в словаре с кл ючом Name, а цвет - в
словаре с кл ючом C o l o r . М ы собираем все словари в один массив, который и
я вляется наш и м и дан н ы м и для таблицы. М ы также добавили выход для таблич­
ного представления, так что нам надо подключ ить его к раскадровке. Выберите
файл Ma i n . s t o ryboa rd в окне Document Outli ne, нажм ите клавишу <Control> и
перетащите указател ь от п и ктограм м ы View Controller к п и ктограмме ТаЫе View .
Отпустите кно п ку м ы ш и и выберите t a Ь l eV i e w из вспл ы вающего окна для
связи табли ч ного п редставления с выходом .
Теперь добавьте в конец файла Vi ewCont r o l l e r . swi ft код из листинга 8.8.
Листинг 8 . 8 . Методы источн и ка данных для табл ичного представления
/ / МАRК : / / МАRК : ТаЫе View Data Source Мethods
func taЫeView ( taЫeView : UI TaЬleView ,
num'Ь erOfRowsinSection section : I nt) -> Int {
return coшputers . count
func taЬleView ( taЬleView : UI TaЬleView ,
cel lForRowAt indexPath : I ndexPath ) -> UI TaЫeViewCell {
ГЛАВА 8 i1 В В ЕДЕН И Е В ТАБЛ И Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
319
let cell
taЬleView . dequeueReusaЬleCell (
withidentifier : cellTaЬleidenti fier , for : indexPath )
as ! NameAndColorCell
=
let rowData
computers [ indexPath . row ]
cell . name
rowData [ " Name " ] !
cel l . color
rowData [ " Color " ] !
=
=
=
return cell
Вы уже видел и эти методы в предыдущем примере - они принадлежат про­
токолу U I TaЫ eVi ewDa t a S o u r c e . Обратите в н и мание на метод taЬleView
(_ taЫeView : Ui taЬleView , ce l l ForRowAt IndexPath : IndexPath ) ,
поскол ьку здесь м ы испол ьзуем и нтересную возможность: табл и ч ное представ­
ление может испол ьзовать разновидность реестра для создан ия при необходи­
мости новой ячейки. Это означает, что, когда мы зарегистри руем все повторно
испол ьзуемые идентифи каторы, которые собираемся испол ьзовать для таблич­
ного представления, м ы всегда сможем получить доступ к свободны м ячейкам.
В предыдущем при мере м ы испол ьзовал и метод dequeue, которы й также ис­
пол ьзует реестр, но возвращает n i l , есл и идентификатор, который мы передаем
ему, не зарегистрирован . Возвращаемое значение n i l испол ьзуется как сигнал ,
что нам нужно создать и запол н ить нов ы й объект класса U I T a Ь l eVi ewCe l l .
Метод, которы й м ы испол ьзуем здесь, н и когда не возвращает значение n i l :
dequeueR e u s a Ь l e Ce l l ( w i t h i de n t i f i e r : c e l l T aЬ l e i de n t i f i e r , f o r : i n d e x P a t h )
Как же он получает объект ячейки табл и цы? Для этого он использует иден­
тифи катор, который м ы передаем ему как кл юч в реестре и добавляем запись в
реестр, которая отображается на идентификатор ячейки нашей табл ицы в методе
vi ewDidLoad().
t a Ь l e V i e w . r e g i s t e r ( NameAndC o l o r Ce l l . s e l f ,
f o r C e l l Re u s e i de n t i f i e r : ce l l T aЬ l e i de n t i f i e r )
Что произойдет, есл и м ы передадим незарегистрированн ы й идентифи катор?
В этом случае метод dequeueRe u s aЬ l eCe l l завершится аварийно. Это плохо
звучит, но в дан ном случае это было бы результатом ошибки, которую можно
обнаружить в процессе разработки . Таким образом, нам не нужно включать код,
проверяющи й возвращаемое значение n i l , так как этого никогда не произойдет.
За ко н ч и в создан и е новой я ч е й к и , м ы м оже м и сп ол ьзовать аргумент
i n dex Pa th, оп ределяющий строку табл ицы, в которой находится требуемая
ячейка, а затем испол ьзовать эту переменную строки для определения правиль­
ного словаря для требуемой строки. Вспом ните, что словарь содержит две пары
"кл юч-значение": одну - для name, другую - для c o l o r .
l e t rowDa t a
=
compu t e r s [ i ndex P a t h . r ow ]
320
ГЛАВА 8 $t В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТА В Л Е Н И Я
Теперь осталось тол ько запол н ить ячейки дан н ы м и из выбран ной строки, ис­
пол ьзуя свойства, определен ные в нашем подклассе .
ce l l . name
ce l l . c o l o r
=
=
r o w D a t a [ " Name " ] !
r ow Da t a [ " C o l o r " J !
Как вы видел и ранее, установка этих свойств при водит к копировани10 зна­
чен и й в метки имени и цвета в я чейке табл ич ного представления.
С ком п ил и руйте и запустите приложение. В ы должны увидеть табл ицу строк,
каждая из которых, в свою очередь, состоит из двух строк дан ных (рис. 8. 1 9).
C�rrier '9
IPhonft 6а - IOS 10.О (14A5297cJ
9:32 АМ
МасВооk Air
Color: Silver
Name: МасВооk Pro
co1or: Silver
Name: iMac
eotor: Sllver
Namo: Мае Mini
Name:
-
Color: Silver
Name:
co1or:
Мае Pro
Black
Рис. 8 . 1 9 . П ол ьзовател ьские я ч е й к и
табл и ч н о го п редста вл е н и я , созда н ­
н ы е п рограм м н о
Возможность добавления представлен и й в табл и чные представления обеспе­
ч ивает бол ьше гибкости, чем испол ьзование одной стандартной ячейки табл ич­
ного п редставления, но п рограмм ное создание, позиционирование и добавление
всех дочерн их представлен и й может о казаться достаточ но утом ительным. Было
бы неплохо, есл и бы мы могл и конструировать ячейки табл ичного представле­
ния графически, испол ьзуя инструменты редактирования графического и нтер­
фейса пол ьзователя в Xcode. К счастью, как уже у пом и н алось ранее, можно
ГЛАВА 8 ''' В В ЕДЕ Н И Е В ТАБ Л И Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
32 1
испол ьзовать програм му lnterface Bui lder для разработки ячеек табли ч ного пред­
ставления, а затем при создан и и новой ячейки просто загрузить представления
из раскадровки ил и Х I В-файла.
Загрузка об ъ екта кл асса UITaЫeViewCell из ХI В - файла
М ы собираемся воссоздать тот же двустроч н ы й и нтерфейс, который тол ько
что создал и в коде, но на этот раз испол ьзуя визуальные возможности, которые
среда Xcode предоставляет в программе l nterface B u i lder. Для этого создадим
новый Х I В-файл, который будет содержать ячейку табличного представления,
и настрои м вид ее представления с помощью програм м ы l nterface B u i lder. За­
тем, когда нам будет нужна ячейка табли чного представления для представле­
ния строки, вместо создания стандартной ячейки табл ичного представления м ы
просто загрузи м Х I В-файл, содержащий ячейку табл и ч ного представления и
ее дочерние представлен ия, и испол ьзуем выход, подключенный к я чейке, что­
бы найти метки и задать имя и цвет. Пом имо применения програм м ы l nterface
Bui lder, м ы упростим некоторые фрагменты кода. Прежде чем продолжить, и ме­
ет см ысл сделать коп и ю проекта ТаЫе Ce l l s , в которую можно будет вносить
описываемые далее изменения. Для этого в ыйдите из среды Xcode и заархиви­
руйте папку проекта под узнавае м ы м и менем, например, ТаЫе C e l l s O r i g .
z ip, что означает "исходный проект ТаЫе Cells'' (рис. 8 .20).
r!J
ch08
о
Simple ТаЫе
... ТаЫе Cells Orig.zip
Та Ые Cells
о "
о "
;;,
Рис . 8 . 20 . П а п ку п роекта можно заархи ­
в и р о вать, чтоб ы создать базо вую верси ю ,
в кото рой м ожно будет вернуться
Сначала внесем нескол ько измене н и й в класс N ameAndC o l orCe l l в файле
NameAndCo l o rCe l l . s w i f t . На первом этапе помечаем свойства nameLabe l и
1
c olo rLabe l как выходы , так что можем испол ьзовать их в програм ме I nterface
Bui lder:
@ IBOutlet va r nameLabe l : U I La b e l !
@ IBOutlet va r c o l o r Lab e l : U I Lab e l !
Теперь вспом н и м о настрой ках, которые м ы делали в методе i n i t ( s t y l e :
U I TaЬleCe l l S t y l e , reu s e i de nt i f i e r : S t r i n g ? ) , в котором создавал и наш и
метки. Все это теперь не нужно. Фактически м ы должн ы просто удал ить весь
322
ГЛАВА В i\!i: В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П РЕДСТАВ Л Е Н И Я
метод, так как в с ю эту настрой ку в ы п ол няет програм ма l nterface Builder. По­
скол ьку мы больше не переопределяем н и какие и н и циал изаторы базового клас­
са, можем удалить и i n i t ( code r : ) .
После всех этих изменен и й класс я чейки стал еще меньше и проще. Это
единственная фун кция, работающая с дан н ы м и для меток. Теперь м ы должны
заново создать я чейки и их метки в програм ме l nterface Bui lder.
П роектирование ячейки табличного представления
с помощью программы l nterface Builder
Щел кн ите п равой кно п кой м ы ш и на пап ке ТаЫе C e l l s в среде Xcode и
вы пол н ите команду New File . . . из вспл ы вающего меню. На левой панел и помощ­
н и ка, предназ наченного для создания новых файлов, щел кн ите на кнопке U ser
l nterface ( выбрав ее в разделе IOS, а не в watchOS , tvOS ил и macO S ) . На правой
верхней панел и вы пол н ите команды U ser l nterface и E m pty, а затем щел кн ите
на кнопке N ext (рис. 8.2 1 ) . На следующей стран и це экрана выберите имя фай­
ла NameAndC o l o r Ce l l . x i b . Убедитесь, что главн ы й каталог проекта выбран
в браузере файлов и что группа ТаЫе Cells выбрана в раскры вающемся списке
G ro u p . Щел кн ите на кнопке C reate для создания нового Х I В-файла.
Chooee а template for уоuг new file:
10-;-------Source
t.Jser lnterfece
Core Oata
Apple Watch
Resource
StoryЬoard
,-
Vlew
-
Launch Screen
Other
watchOS
Source
User lnterface
Core Oata
Resource
Other
tvO S
Source
Empty
User lnter1ace
А1' empty lnterface 8uik1er document for an iOS lntertaco.
Рис . 8 . 2 1 . Созда н и е пустого файла п ол ьзо вател ьского и нтерфе й са ,
кото р ы й ста н ет ХI В -файлом н а ш е й я ч е й к и
Выберите файл NameAndC o l o r Ce l l . x i b в окне навигатора проекта, чтобы
открыть этот файл для редактирован и я . До сих пор м ы вы пол нял и все редак­
тирован ие графического интерфейса в раскадровке, а теперь испол ьзуем вместо
ГЛАВА 8 �� В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
323
этого niЬ-файл . Больши нство действи й похожи и будут вам очень знакомы, но
есть и нескол ько разл и ч и й . Одни м из главных отл и ч и й я вляется то, что, хотя
файл раскадровки и фокусируется на сценах, которые связывают контроллер
представления и само представление, в niЬ-файле нет н и какого принудительного
связы вания. В действительности niЬ-файл часто не содержит объект реал ьного
контроллера вообще, а тол ько прокси, который называется F i le's Owner. Есл и вы
откроете окно Document Outline, то увидите его там над элементом First Responder.
Найдите в библ иотеке элемент ТаЫе View Cell (рис. 8 .22) и перетащите его в
область макетирован ия графического и нтерфейса .
• • ,.... e.ilt
.
-­
·· �·""'
(.......
" ,..,
......
· --
°' --
- · -­
·--
-
---
---, ......_.. .... �
...,. ..._.. �r.-w
с
о
о
о
с
с
о
flllllit
� - ... . ""'
" _ __!'( " .,..._. _
......
о
Рис . 8.22. П е ретаскиваем эл е м е н т ТаЫе Vtew Cell и з б и бл и отек и н а кан ву
Нажм ите комбинаци ю клавиш <Option+X +4>, чтобы перейти в окно инспек­
тора атрибутов (рис. 8 . 2 3 ) . Первое поле, которое вы здесь увидите, - l d enti­
fier. Это повторно испол ьзуемый идентификатор, который мы уже при меняли в
нашем коде. Есл и это н и чего вам не напом н ило, верн итесь назад и найдите
в глав� упом и нание класса Cel lTaЬl e i dent i f i e r. Установите атрибут l dentifier
равным CellTaЫel dentifier.
Идея закл ючается в том, что, когда мы получаем ячейку для повторного ис­
пользования ( н апри мер, из-за прокрутки новой я чейки в представлен и и), м ы
хотим убедиться, что получ и м правил ь н ы й т и п я чейки. П ри создани и объекта
этой конкретной ячейки из niЬ-файла вы можете вызвать запол нение повторно
испол ьзуемого идентифи катора переменной экземпляра и менем, в веде н н ы м в
поле ldentifier, - в данном случае и м я вляется CellTaЫeldentifier.
324
ГЛАВА 8 f,1 В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
,______ __ ___
Т1Ые Vlew Cell
Style
-- ---
Custom
ldentlfler CellTaЫeldentifier
seiectlon � D efa u l t _ __ _ _____
Accessory
None
Edlting Асс.
None
F ocus Style
Default
lnnP.ntяtlnn
в
S
в
в
в
Рис . 8 . 2 3 . И н с п е кто р атрибутов я ч е й к и
табл и ч н о го п редста вл е н и я
П редставьте себе сценарий, в котором в ы создал и табл ицу с заголовком, а
затем ряд средн их я чеек. Есл и при прокрутке средняя ячейка входит в пред­
ставление, важно, чтобы вы получил и для повторного испол ьзован ия средн юю
ячейку, а не ячейку заголовка. Поле ldentifier позволяет соответствующи м обра­
зом помечать ячейки.
Наш следующий шаг закл ючается в редактирован ии представления содержи­
мого ячейки таблицы. Сначала выберите ячейку табл ицы в области редактирова­
ния и перетащите ее н ижний край, чтобы сделать ячейку нем ного выше. Добей­
тесь высоты, равной 6 5 . Перейдите к библ иотеке, перетащите четыре элемента
управления Label из библ и отеки и поместите их в п редставление содержимого,
испол ьзуя рис. 8.24 в качестве ориентира. Обратите внимание на то, что метки
будут находиться сл и ш ком бл изко к верхней и н ижней направл я ющим, чтобы
они могл и оказать существен ную помощь, но левая направляющая и направля­
ющие вырав н и ван ия должн ы корректно служить своей цел и . Замети м, что вы
можете перетащить одну метку, а затем перетаски вать ее с нажатой клавишей
<Option>, чтобы создавать копии, есл и такой подход дл я вас проще.
or
. 1 Label Label
: j Label Label
1
1·
1
'-- -�������������������--
=.
Рис . 8 . 24 . П редста вл е н и е соде ржи м ого я ч е й к и таб ­
л и ч н о го п р едставл е н и я с четы р ь м я м етка м и
Дважды щел кн ите на верхней левой метке и измен ите ее текст на Name: , а
текст н ижней левой метки - на Color: .
ГЛАВА 8 ,t< В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
325
Выберите обе эти метки и щел кн ите на маленькой кно п ке с буквой Т в поле
Field инспектора атрибутов . В результате откроется маленькая панел ь, содержа­
щая выпадающий сп исок Font. Щел кн ите на ней и выберите пункт System Bol d .
Есл и необходи мо, выберите два остал ьных поля меток с права, перетащите их
вправо, чтобы освободить немного места, и измените размер двух других меток
так, чтобы видеть тол ько что введе н н ы й текст. Наконец измените размер двух
правых меток так, чтобы они оказались растя нутым и до п равой направляющей.
Рис. 8.25 должен дать вам представление о том , как в ы глядит око н чател ьное
представление содержимого ячейки.
�abel
Color: �abel
Name:
Q
в
Q
Q
Q
8 :
Q
Q
• '--���� .
. .
Рис. 8 . 2 5 . П редста вл е н и е с оде ржи м о го я ч е й к и таб ­
л и ч ного п редста вл е н и я с и з м е н е н н ы м и н а з ва н и я м и и
ш р и фтом л е в ы х м еток и с пе редви нуты м и с и з м е н е н и ­
е м раз м е ров п р а в ы м и м етка м и
Как обычно при создании нового макета, м ы должны добавить огран ичения
Auto Layout. Общая идея закл ючается в том, чтобы прикреп ить метки левой
сторон ы макета к левой стороне я чейки, а метки правой стороны - к правой.
Мы также должны раздел ить метки верхней и нижней частей я че й ки по вер­
тикал и . Мы свяжем кажду ю метку левой сторон ы с соответствующей меткой
справа. Ниже оп исано, как это сделать.
1 . Щел кните на метке N a me : , нажм ите клавишу <Sh ift>, а затем щел кн ите
на метке Color: . Щелкните на п и ктограмме P i n , расположенной под окном
редактора n iЬ-файла, установите флажок Equal Width и щелкните на кнопке
Add 1 Constra i n t . При этом в ы увидите предупреждение механ изма Auto
Layout (не беспокойтесь - м ы исправим ситуацию, когда добавим допол­
н ительные огран ичения).
2. Оставив две метки выбран н ы м и, откройте окно и нспектора размеров и най­
:дите раздел Content H u g g i n g P riority. Есл и вы его не видите, отмените выбор
меток и вновь выберите их, Значения в этих полях определя ют, наскол ько
метки сопротивляются расширению в допол нител ьное пространство. М ы
н е хотим, чтобы метки расш ирялись по горизонтали вообще, поэтому из­
мените значение в поле H o rizontal с 2 5 1 на 5 0 0 . Любое значение, бол ьшее
25 1 , подходит - надо л и ш ь, чтобы оно было больше, чем значение Content
H ug g i n g Priority для двух правы х меток, т.е. чтобы л юбое допол н ительное
горизонтальное пространство в ыделялось именно и м .
326
ГЛАВА 8 t> В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
3 . Нажмите клавишу <Contro\> и перетащите указател ь от метки Color: к мет­
ке Name:, выполните команду Vertical Spacing во всплы вающем меню и
нажмите клавишу <Retum>.
4. Нажмите клавишу <Control> и перетаскивайте указатель вверх и влево от
метки Name: по направлени ю к верхнему левому углу ячейки до тех пор,
пока фон ячейки не станет полностью голубы м . Нажав клавишу <Sh ift>, во
всплывающем меню выполн ите команды Leading Space to Container Margin
и Тор Space to Container Margin, а затем нажм ите клавишу <Return>.
5. Нажмите клавишу <Control> и перетаскивайте указатель от метки вниз и вле­
во от метки Color: по направлению к нижнему левому углу ячейки до тех пор,
пока фон ячейки не станет полностью голубым. Нажмите клавишу <Shift> и
во всплывающем меню выполните команды Leading Space to Container Mar­
gin и Bottom Space to Container Margin, а затем нажмите клавишу <Retum>.
6. Нажм ите клавишу <Control> и перетащите указател ь от метки Name: к
метке, расположенной справа. Во всплы вающем меню при нажатой кла­
више <Shift> в ыпол ните команды Horizontal Spacing и Baseline, а затем на­
жмите клавишу <Return>. Нажм ите клав и шу <Control> и перетаскивайте
указатель от верхней метки вправо по направлени ю к правому краю ячей­
ки, пока фон ячейки не станет голубы м . Во вспл ы вающем меню выберите
Trailing Space to Container Marg i n .
7 . Аналогично нажм ите клавишу <Control> и перетащите указатель от метки
Color: к метке, расположенной справа от нее. Во всплы вающем меню при
н ажато й клавише <Shift> выпол ните команды Horizontal Spacing и Baseline
и нажмите клавишу <Return>. Нажм ите клавишу <Control> и перетаскивай­
те указатель от н ижней метки вправо по направлению к правому краю ячей­
ки, пока фон ячейки не станет голубы м . Во вспл ывающем меню выполните
команду Trailing Space to Contai ner Margin и нажмите клавишу <Return>.
8. Выберите п икrограм му Content View в окне Document Outl ine, а затем вы­
полн ите команду Editorc> Resolve Auto Layout lssuesc:> U pdate Frames, если
она досrупна. Четыре метки переместятся в свои окончател ьные местополо­
жен ия, как показано на рис. 8.26. Если вы увидите что-то иное, удалите все
ограничения в окне Document Outline и попробуйте выполнить все заново.
ог
1 Name : Label
� Color: Label
·--- --- --
Рис. 8 . 2 6 . О кончател ьная позиция м етки в н утри я ч е й к и
Теперь мы должны сообщить п рограмме l nterface B u i lder, что ячейка таб­
л и чного п редставления я вляется не стандартной ячейкой, а особ ы м подклас­
сом . В противном случае мы не сможем связать выходы с соответствующи м и
327
ГЛАВА 8 "' В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
ячейкам и . Выберите ячейку табл и ч ного представления щел ч ком на элементе
CellTaЫeldentifier в окне Document Outline, откройте и нспектор идентичности, на­
жав комби нацию клавиш <Option+:tf:+З>, и выберите пункт NameAndC o l orCe l l
в списке C lass (рис. 8 .27).
Затем перейдите в окно инспектора с вязей, нажав комби нацию кл авиш
<Option+X +6>, где вы увидите выходы c o l orLabe l и nameLab e l (рис. 8.28).
Outleta
Cuatom Claaa
о
о
о
о
о
о
accessoryV1ew
Class
backgroundVlew
colorLabel
Module
edltlngAccessoryVlew
nameLaЬel
selectedBackgroundVlew
ldentlty
Restoratlon ID
Outlet Collectlona
Рис . 8 . 2 8 . В ыходы c o l o r L a b e l и
Рис. 8.27. Н астрой ка н а ш е го класса
nameLab e l
Нажм ите клавишу <Control> и перетащите указател ь от выхода nameLabe l
к верхней метке справа в ячейке табл ицы и от выхода c o l o rLabe l к нижней
метке справа, как показано на рис. 8.29.
. , ,.... °'*'
.
-­
· --
·
"' <
• тlllll8 c.tt
0-
......,
,.... t.- 1 t111c1 т_... t:..., .._...__ t..iw м t;:it №
,._с.а.
- � ··
"
• �·• t c.inИJ1i8Ь8111�•
1
[] 0 1.]
С\ Ф • & а е
· -·
-
1 ::=""--
�� /
(.
- �-.н._
�
---­
- -. - -
/
-
Name: L.abel
Color: , LaЬel
(\ {) <i) о
Рис. 8 . 29 . Связ ы в а н и е в ыходов с и м е н е м и м еткой цвета
о
о
()
о
о
328
ГЛАВА 8 ш В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
Использование новой ячейки табличного представления
Для того чтобы испол ьзовать · спроектиро ван ную я ч е й ку, следует в нести
некоторые довол ьно простые измене н и я в метод v i e w D i d L o a d ( ) в файле
ViewCont ro l l e r . s w i f t (л истин г 8 .9).
Л истинг 8 . 9 . Модификация метода vi ewDidLoad ( )
для использования новой ячейки
ove r r ide func vi e w D i dLoad ( ) !
s up e r . v i e w D i d L o a d ( )
1 1 До п ол н и тел ь н а я на стройка п р е д с т а в л е н и я п о сл е з а грузки , обыч н о и з
n i Ь - файла
t a Ы e V i ew . r e g i s t e r ( NameAndC o l o r Ce l l . s e l f ,
f o r C e l l Re u s e i de n t i f i e r : c e l l T aЫ e i de n t i f i e r )
let xib
U I N i b ( n i bName : " N ameAndCo l o r Ce l l " , b u n d l e : n i l )
taЫeView . re g i s t e r ( x i b ,
f o r Ce l l Re u s e i de n t i f i e r : c e l l T aЬ l e i d e n t i f i e r )
t a Ы e V i e w . rowHe i g h t
65
=
=
Так же, как класс может быть с вязан с повторно испол ьзуе м ы м идентифика­
тором (как в ы видел и в предыдущем примере), таблич ное представление может
отслежи вать, какие n iЬ-файл ы должны быть связан ы с кон кретным повторно
испол ьзуе м ы м идентифи катором . Это позволяет регистрировать я чейки для каж­
дого вида строк, исflользуемых в приложении с помощью классов ил и niЬ-фай­
ла, а метод dequeReusaЬleCe l l ( _ : for i ndex Path : ) всегда будет возвращать
готовую к испол ьзованию ячейку.
Вот и все. В ы пол н ите сборку и запус к. Теперь ваш и двухстроч ные я чейки
табл ичного представления пол ностью зависят лишь от вашего умения работать
с програм мой I nterface Bui lder (рис. 8 . 3 0).
Гр у п п и рова н ные и и ндекс и рован ные ра здел ы
Наш следующий проект посвя щен изучению еще одного основополагающе­
го аспекта табл и ц. Мы по-прежнему будем испол ьзовать одно табличное пред­
ставление - без иерархий, - но раздел и м дан н ые на раздел ы . В новь создайте
новый проект в среде Xcode с испол ьзован ием шаблона S i n g l e View Appl ication
и назовите его Sections. Как обы ч но, выберите пункт Swift в списке La ng uage и
пун кт U n iversal в с п иске Devices.
Создание представления
Откройте пап ку Sect i on s и дважды щел кн ите на файле Ma i n . s t oryboard
для его редактирования . П еретащите табл и ч ное представление в окно View, как
мы делал и это раньше. Измените верх табл ичного представления так, чтобы он
был н иже строки состоя ни я, и добавьте те же о граничения A uto Layout, что и
в при мере Т а Ы е C e l l s . Затем нажм ите комби наци ю клавиш <Option+X +б>
и соеди н ите flодкл ючение dataSou rce с п и ктограммой View Control ler.
ГЛАВА В м В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
'""e 6s - юs 10.0 (14А62.97с)
lюn
. IP"'"
....,.__..
Carrier •
10:64 АМ
Name: MacBook Air
329
__,,....,'"-.
-
Co\or: Silver
Name: MacBook Рго
Co\or: Silver
Name: iMac
Color: Silver
Name: Мае Mini
Co\or: Silver
Name: Мае Pro
Color: Black
Рис . 8 . 30 . Резул ьтаты н астро й к и я ч е й ки
Убедитес ь, что табл и ца выбрана, и нажм ите комбинацию клавиш <Option+
+Х+4>, чтобы вызвать инс пектор атрибутов. Измените значение Style табли чно­
го представления с Plain на G rou ped (рис. 8.3 1 ). Сохраните раскадровку.
Импортирование данных
Этот проект требует для работы изрядного кол ичества данных. Для того что­
бы избежать дл ител ьного набора текста, м ы предоставляем еще оди н с писок
свойств, упрощающих работу. Найдите файл s o r t e dname s . p l i s t из вложен­
ной папки 0 8 - S e c t i on s Data архива исходных текстов примеров и перета­
щите его в папку Sections.
После того как файл s o r t e dname s . p l i s t будет успешно добавлен в ваш
проект, щел кн ите на нем, чтобы получ ить представление о том, как он в ы глядит
(рис. 8.32). Это список свойств, который содержит словарь, в котором имеется
по одной записи для каждой буквы алфавита. Под каждой буквой располагается
список имен, которые нач и наются на эту букву.
М ы будем испол ьзовать данные из этого списка свойств для запол нения таб­
личного представления, создавая разделы для каждой буквы .
330
ГЛАВА 8 � В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
"1ew Controller Sceno )
18111 . stO<yt>oam (В.И) )
•
1!1
-
View Controller )
••
"1ew ) 1" Т•Ы• "1ew
т1ы. v-.
Content
Dyn1mlc Prototypes
n
В
-
f
Р18111
1 Group&fi
$et>tt8tor O.f1utt
в\
В
S�� Slngle Selectlon
8
f.dltlng No Sei.ctlon Durlng Editlng В
Sel)ll'1tor mиt
= De/8\J!t
Oefault
tиtion h\Ot1t
о :
D1oollY Llmlt
в
в
в
Text = o.fautt
+ B8CJ(ground = Deleun
Ttaekfng = Olf1ult
TaЫe View
ktod Vlew
в
Style 0.fault
Prototype Cont�nt
Sc<oll lndicet- а SltoWI HorltOl)(el lndlcetor
D Showe Vortlcel lndlcetor
Suotllno D 9crotllng Enebled
P1glng En1bl8CI
OIJ'OC!lon Lock Enebled
........ а 11ounco1
Вounce H«l:iont.ity
fJ Вounce VtrtlCl"Y
Рис. 8 . 3 1 . И н с п е ктор атри буто в дл я табл и ч н о го п редставл е н и я с в ы ­
бран н ы м з н ач е н и е м G rouped в ы п ада юще го м е н ю Style
S.C 1l",'° ...... 1
"
e:i 11 о. 6 0 !11 "' "
· • hcti..
.
-
# �-""""
· -·-
11 <
r...,. м t1'(17 Ш
.,_ .,.._ ,,. .......,,
·-
-
-
11·�-·
...,
."
,.,_,
•.
"
""
•."
·*-'
-
-
•.
"
"
•J
-·
-·
-·
00
....
....
-
-·
....
_,
-
-·
-
-·
_"
""
{it>
---
-
-
"�
о ф
r
с о
... "-�
,.,.. DllWl · "'-тtl l.М •lll. 8
�
•."
..
"
"
"
-
� "' ....
--
,,. _ _
,.,.,,..
., ,_,..,.,,
...,....�!/
......_
.
"
-....
1--­
. ,.., "_
_"
_"
....
.....
-
_"
_"
....
....
-
". "
_"
_"
_"
-
-
....
-
....
....
-
-
-
(\ (1 0 о
.....
....
....
....
Рис . 8.32. С п и с о к с в о й ств s o r t e dnarne s . p l i s t . Здесь раскрыт с п и с о к и м е н
на букву ':.J "
ГЛАВА В l7f В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
33 1
Реализация контроллера
Щел кните на файле ViewC o n t r o l l e r . swi f t . Сделайте класс отвечающим
протоколу U I T a Ь l eV i e w D a t a S ou r c e , добавьте имя иденти фи катора ячейки
таблицы и создайте пару свойств путем добавления в файл Vi ewCont r o l l e r .
swi ft кода, выделен ного н иже полужир н ы м шрифтом .
c l a s s Vi ewCont ro l l e r : U I V i e w C o n t r o l l e r , U I T a Ы e V i e w Da t a S o u r c e
let sectionsTaЬleidenti fier
" Sections TaЬleindentifier "
var name s : [ String : [ S tring ] ] !
var keys : [ S tring ] !
=
С нова откройте файл Ma i n . s t o rybo a rd и откройте окно помощни ка редак­
тора. Если файл в окне не откры вается, воспол ьзуйтесь панел ью быстрых пере­
ходов для выбора файла Vi ewCont r o l l e r . s w i f t . Нажмите клавишу <Control>
и перетащите указател ь от таблич ного представления в окно помощн и ка редак­
тора для создания выхода для табл и цы непосредственно под определением кл ю­
чевых свойств.
@ IBOutlet weak var taЬleView : UI TaЬleView !
Теперь измените метод viewDi dLoad ( ) так, как показано в л истин ге 8 . 1 О.
Л истинг 8. 1 0 . Модификация метода vi ewDidLoad ( )
для использования новой ячейки
ove r r ide func v i e w D i d L o a d ( ) {
s upe r . v i e w D i d L o a d ( )
/ / Дополнител ь н а я н а с тройка представлени я п о сле з а грузки ,
1 1 обыч но и з n i Ь - файла
taЫeView . re g i s t e r ( U I TaЬl eViewCel l . s e l f ,
f o r Ce l l Re u s e i de n t i f i e r : s e c t i on s T a Ь l e i de n t i f i e r )
l e t p a t h = Bund l e . ma i n . p a t h ( f o r Re s o u r ce :
" s o r t e dn ame s " , o f T yp e : " p l i s t " )
l e t name s D i c t
N S D i c t i o n a r y ( c o n t e n t s O f fi l e : p a t h ! )
name s
name s D i c t a s ! [ S t r i n g : [ S t r i n g ] ]
keys
( n ame s D i c t ! . a l l Ke y s a s ! [ S t r i n g ] ) . s o r t e d ( )
=
=
=
Бол ьшая часть этого кода не сл и ш ком отл ичается от того, что в ы видел и
раньше. Прежде м ы добавляли объявления свойств и для словаря, и для массива.
Словfiрь будет хран ить все наши дан н ые, в то время как масси в будет хранить
раздел ы, отсортированные в алфавитном порядке. В методе v i e w D i dLoad ( )
м ы сначал а зарегистри ровал и класс я ч е й ки табл и ч ного п редставл е н и я по
умолчанию, который должен в ы водиться для каждой строки, с помощью на­
шего объя влен ного идентифи катора. П осле этого м ы создал и э кзем пляр клас­
са N S D i ct i on a r y из добавленного в проект списка с войств и присвоил и его
свойству name s , при ведя его к подходящему ти пу словаря Swift. После этого
м ы получили все ключи из этого словаря и отсортировал и их, чтобы получ ить
332
ГЛАВА 8 � В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВ Л Е Н И Я
упорядочен н ы й масси в с о значения м и кл ючей из словаря в алфавитном поряд­
ке. Помните, что наши дан ные испол ьзуют в качестве ключей буквы алфавита,
так что этот масси в будет содержать 26 букв в порядке от А до Z и мы будем
испол ьзовать этот масси в для отслежи вания разделов.
Далее добавьте в конец файла код, при веде н н ы й в л истинге 8 . 1 1 .
Л и стинг 8 . 1 1 . Методы источника дан н ых для табличного представления
11 МАRК : ТаЫе View D a t a Source Methods
f u n c n umbe r O f S e c t i on s ( i n t a Ь l e V i ew : U I T a Ь l e V i e w )
return keys . count
f u n c t a Ы e V i e w ( _ t a Ь l e V i e w : U I T a Ь l e Vi ew ,
numb e rO fRow s i n S e c t i o n s e c t i o n : I n t )
l e t key = keys [ s ect ion )
l e t name S e c t i o n
name s [ ke y ) !
r e t u r n name S e c t i o n . c o u n t
-
-
> I nt {
> Int {
=
f u n c t a Ы e V i e w ( t a Ь l e V i e w : O I T a Ь l eVi e w ,
t i t l e Fo r H e a de r i n S e c t i o n s e c t i on : I n t ) - > S t r i n g ?
r e t u rn k e y s [ s e c t i o n ]
f u n c t a Ь l e V i e w ( t a Ы e V i ew : U I T a Ь l e V i ew ,
c e l l Fo r RowAt i ndex P a t h : I n d e x Pa t h ) - > O I T a Ы eVi ewCe l l {
l e t ce l l
t a Ь l e V i e w . d e q u e u e Re u s aЫ e C e l l (
w i t h i d e n t i f i e r : s e c t i on s T a Ь l e i de n t i f i e r , f o r : i ndex P a t h )
a s U I TaЬl eViewCe l l
l e t ke y = k e y s [ i nd e x P a t h . s e c t i on ]
l e t name S e c t i o n
n ame s [ ke y ] !
c e l l . t e x t Lab e l ? . t e x t = name S e c t i o n [ i nde x P a t h . r ow ]
=
=
r e t u r n ce l l
Все это методы источ н и ка дан н ы х табл и цы . Перв ы й добавлен н ы й в наш
класс метод у казы вает кол и чество раздело в . М ы не реал изовал и этот метод
в п редыду щ и х п р и м ерах, п отому что н ас в п ол не устраи вало знач е н и е по
умол чанию, равное еди н и це . Н о н а этот раз мы говори м табл и ч ному пред­
ставлению, что у н ас и меется по одному разделу для каждого кл юча нашего
словаря .
f u n c n umbe r O f S e c t i o n s i n T a Ы e V i e w ( t aЫ e V i e w : U I T a Ь l e V i e w ) - > I n t {
return keys . count
Следующий метод вычисляет количество строк в конкретном разделе. В преды­
дущем примере у нас был только один раздел, так что мы просто возвращали коли­
чество строк в массиве. На этот раз нам необходимо разбить его по разделам . М ы
ГЛАВА 8 ;�1 В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВ Л Е Н И Я
333
можем сделать это путем получения массива, соответствующего и нтересующему
нас разделу, и возвращения количества элементов в этом массиве.
func t a Ь l e V i e w ( t a Ы e V i e w : U I T aЬ l e V i e w ,
n umb e r O fRow s i n S e c t i o n s e c t i o n : I n t ) - > I n t {
l e t k e y = k e y s [ s e c t i on ]
l e t n ame S e c t i o n = n ame s [ ke y ] !
r e t u r n n ame S e c t i o n . c o u n t
Метод t a Ы eVi ew ( : ti t l e ForHeade r i n S e c t i on : ) позволяет указать не­
обязател ьное значение заголовка для каждого раздела, и в нем м ы просто воз­
вращаем букву соответствующей гру п п ы .
f u n c t a Ь l eV i e w ( t a Ы e V i e w : U I T a Ь l eV i e w ,
t i t l e Fo r H e a de r i n S e c t i o n s e c t i o n : I n t ) - > S t r i ng ? {
r e t u r n keys [ s e c t i o n ]
В методе taЬ leView ( : ce l l ForRowAt i ndex P a t h : ) м ы должн ы извлечь из
пути индекса раздел и строку, а затем испол ьзовать их для определения интере­
сующего нас значен и я . Номер раздела говорит нам о том, какой массив следует
получ ить из словаря имен, а затем на основани и значения строки получ ить необходи мое значение из указанного масси ва.
Все остал ьное в этом методе в основном ос­
12:05
Carrier •
талось тем же, что и в приложе н и и простой
Aydin
табл и цы , которое м ы создал и ранее в этой
главе.
Ayla
С ком п ил и ру йте и запустите прое кт, и
Aylin
можете гордиться собствен н о й крутизной .
Помн ите, что м ы изменил и значение Style
Azaria
табл и цы на Grouped и в резул ьтате получили
Azul
сгру п п и рован ную табл и цу с 26 разделам и ,
которая должна в ы глядеть так, как показано
8
на рис. 8 . 3 3 .
8ailee
Для контраста вернем нашему табл и ч но­
8ailey
му п редставлению простой стил ь и посмот­
рим, на что похожа п ростая табл и ца с не­
8ailey
сколькими разделам и . Выберите файл Ma i n .
8arbara
s t o ryboa rd, чтобы отредактировать его в
програм ме l nterface B u i lder. В ы берите таб­
вarrett
лич ное представление и восп ол ьзуйтесь ин­
8aylee
спектором атрибутов, чтобы изме н ить стил ь
Beatrice
таблич ного представления на Pla i n . Сохран и­
те проект, а затем соберите и запустите его.
Beau
Как в идите, дан н ы е - те же, но внеш н и й
вид совсем другой (рис. 8.34).
Рис. 8.33. Сгруппи рован ная таб _
_ _ __
РМ
л и ца с нескол ьки м и разделам и
334
ГЛАВА 8 11 В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
Добавление индекса
Одной из проблем, связан н ы х с нашей текущей табл и цей, я вляется само
кол и чество строк. В сп иске 2000 имен. Пока вы доберетесь до Zachariah или
Zayne, не говоря уж о Zoie, ваш палец ужасно устанет.
Одн и м из решений этой п роблемы я вляется добавление и ндекса в правой
части табл и цы . Теперь, когда мы вновь установил и стил ь нашего табличного
представления в Plain, это относител ьно легко сделать, как показано на рис. 8.3 5 .
Добавьте следующий метод в конец файла Vi ewContro l l e r . swi f t :
f u n c s e c t i o n i n dex T i t l e s ( f o r t a Ь l e V i e w : U I T a Ь l eV i e w ) - > [ S t r i n g ] ?
return keys
Carrier •
А
12:08 РМ
-
Carricr <:?'
L
Ayla
Lacey
Aylin
Laci
Azaria
Laila
Azul
Lainey
в
Взilее
Lamar
1 2 : 1 2 РМ
-
'
G
Lamont
Bailey
Lana
Bailey
Lance
ВзrЬаrа
Landen
Взrrett
Landin
Взу lее
Landon
L
м
N
о
р
о
•
s
v
w
х
Beatrice
Landyn
Beau
Lane
Beckett
Laney
Рис . 8 . 34 . П ростая табл и ца с
Рис . 8.35. Добавл е н ие и нде к ­
раздел а м и и без и ндексов
са в табл и ч ное п редставл е н и е
Реализация строки поиска
И ндекс полезен, но несмотря на это у нас все еще сл и ш ком м ного имен.
Если, например, м ы хотим узнать, имеется л и в сп иске имя Arabel la, то должны
будем выпол н ить некоторую п рокрутку даже при применении индекса. Было бы
неплохо, есл и бы мы могл и дать пол ьзовател ю возможность уменьшить список,
ГЛАВА 8 11 В В ЕДЕН И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
335
введя поисковый запрос . Это требует небол ьшой допол н ител ьной работы, но
резул ьтат того стоит. Мы собираемся реал изовать стандартную строку поиска
iOS, показанную на рис. 8 . 3 6, слева, с испол ьзованием контроллера поиска.
Claudla
Aaron
Diamond
Abagall
Diana
дЬЬеу
lnd1a
дЬЫе
'
м
дЬЬу
Abigail
Nadia
Yurldia
AЬdullah
дЬеl
Lydia
u
v
w
q
w
е
г
t
у
u
о
р
дbigale
AЫgayle
Abraham
Рис . 8 . 36 . П риложе н и е с добавл е н н о й строкой поиска
По мере ввода пол ьзователем информаци и в строку поиска список имен со­
кращается, и в нем остаются тол ько те из н их, которые содержат введе н н ы й
текст в качестве подстроки . В качестве бонуса строка поиска также позволяет
вам определ ить кно п ки области в иди мости, которые в ы можете испол ьзовать
для уточ нения поиска тем ил и и н ы м образом . М ы добави м три такие кнопки в
нашу строку поиска: Short, которая позволит ограни ч ивать поиск и менами менее
шести сим волов дл иной; Long - для имен дл иной не менее шести сим волов;
Al l
'для поиска по всем и менам . Эти кнопки появляются тол ько тогда, когда
пользовател ь вводит что-то в строку поиска (см . рис. 8 . 3 6, справа).
Добавление фун кции поиска выпол няется достаточно просто. Для этого нуж­
ны три вещи.
-
'Р�
Данные, среди которых выполняется поиск. В нашем случае это список имен.
!$
Контроллер представления для вы вода резул ьтатов . Временно заменяет
контроллер, предоставляющий данные. Результаты для отображения могут
336
ГЛАВА 8 �'' В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТА В Л Е Н И Я
выбираться л юб ы м способом , но обы ч но исходные дан ные представле­
ны в таблице, и контроллер использует другую табл и цу, которая выглядит
очень похоже на основную, создавая тем сам ы м впечатление, будто поиск
просто фильтрует исходную табл и цу. Однако, как в ы увидите, это не сов­
сем то, что происходит на самом деле.
' t»
Класс U I Sea rchCont ro l l e r, п редоставляющий строку поиска и управля­
ющий в ыводом результатов поиска в контроллере резул ьтирующего пред­
ставлен и я .
Нач нем с создания скелета нашего контроллера п редставления . М ы будем
отображать результаты поиска в табли це, так что наш контроллер представле­
ния резул ьтатов должен содержать табл и цу. М ы можем перетащить контрол­
лер представления на раскадровку и добавить к нему табл и ч ное представле­
н ие, как мы делал и в более ран них примерах в этой главе, но в этот раз м ы
пойдем другим путе м . М ы будем испол ьзовать класс U I T a Ь l eVi ewCont r o l l e r,
который представляет собой контроллер п редставления со встроенн ы м объек­
том класса U I T a Ь l eVi ew, настроен н ы м и как источ н и к дан н ы х, и как деле­
гат для своего табл и ч ного представлени я . В окне нави гатора проекта щел кни­
те п равой к но п кой м ы ш и на группе Sections и вы пол н ите команду New File
из всплывающего меню. В области в ы бора шаблона выберите п и ктограмму
Сосоа Touch C lass из гру п п ы IOS S o u rce и щел кн ите на кнопке N ext. Назови­
те ваш нов ы й класс S e a r chRe s u l t s C o n t ro l l e r и сделайте его подкл ассом
U I T a Ы eVi ewCont ro l l e r . Щелкн ите на кнопке N ext, выберите местоположе­
ние для нового файла и позвол ьте программе Xcode создать его.
В ы берите в окне навигатора проекта файл S e a r c hRe s u l t s C o n t ro l l e r .
swi f t и внесите в него следующие изменения :
. . .
c l a s s S e a r ch Re s u l t s Co n t r o l l e r : U I T aЬ l e V i ewCo n t r o l l e r ,
UI SearchResultsUpdating {
М ы собираемся реал изовать логику поиска в этом контроллере представления.
поэтому делаем его соответствующим протоколу U I S e a rchRe s u l t s Upda t i ng,
котор ы й позволяет нам назнач ить его в качестве делегата кл асса U I S e a r ch
Cont ro l l e r . Как вы увидите позже, еди нствен н ы й метод, определенн ы й эти м
протоколом, вызы вается для обновления результатов поиска по мере ввода поль­
зователем дан ных в строку поиска.
Поскол ьку этот контроллер будет реал изовы вать операции поиска, классу
S e a rchRe s u l t s C o n t r o l l e r необходим доступ к с п иску и мен, которые отоб­
ражает основной контроллер, так что мы должны дать ему свойства, которые
сможем испол ьзовать для передачи словаря имен и списка кл ючей, испол ьзу­
емых для в ы вода в основном контроллере п редставления. Добав и м эти свой­
ства в файл S e a rchRe s u l t s C o n t ro l l e r . s w i f t . Вы, наверное, заметил и, что
этот файл уже содержит некоторый незакончен н ы й код, которы й обеспечи вает
ГЛАВА 8 � В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
337
части ч ную реал изацию протокола U I T a Ь l eV i e w D a t a S o u r c e , и некоторые
блоки заком ментированного кода других методов, которые подклассам класса
U I Ta Ь l eViewCont ro l l e r часто необходимо реал изовать. В дан ном при мере
м ы не собираемся испол ьзовать бол ьш и нство из н и х, так что не стесня йтесь
удалить весь закомментированный код, а затем добавить следующий код в верх­
ней части файла:
c l a s s S e a r c h Re s u l t s C o n t r o l l e r : U I T aЬ l e V i e w C o n t r o l l e r ,
U I S e a r c h Re s u l t s Upda t i n g {
l e t s e c t i o n s T a Ь l e i de n t i f i e r
" S e c t i o n s T a Ь l e i de n t i f i e r "
va r name s : [ S t r i n g : [ S t r i n g ] ] = [ S t r i ng : [ S t r i n g ] ] ( )
va r k e y s : [ S t r i n g ]
[]
va r f i l t e r e dName s : [ S t r i n g ]
[]
=
=
=
М ы добавил и перемен ную s e c t i on s TaЬ l e i dent i f i e r для хранения иден­
тификатора я чеек табл ицы в этом контроллере представления и испол ьзуем тот
же идентификатор, что и в контроллере главного представления, хотя мы могл и
бы испол ьзовать л юбое и м я . М ы также добавил и два свойства, которые будут
хранить имена словаря и списка кл ючей, которые м ы будем испол ьзовать при
поиске, и еще одно для ссылки на масси в, в котором будут храниться резул ьтаты
поиска.
Далее добавим в метод viewDidLoad ( ) строку кода для регистрации иден­
тификатора я чейки табл и цы с резул ьтатам и встроен ного в контроллер табл ич­
ного представления:
ove r r i d e f u n c v i e w D i dLoad ( )
s u p e r . v i e w D i d Load ( )
t a Ь l e V i e w . r e g i s t e r ( U I T a Ь l eV i ewCe l l . s e l f ,
f o r Ce l l Re u s e i de n t i f i e r : s e c t i o n s T aЬ l e l de n t i f i e r )
Это все, что нам пока что нужно было сделать в контроллере представления
резул ьтатов, так что давайте ненадол го вернемся к нашему контроллеру главно­
го представления и добавим в него строку поиска. Выберите Vi ewContro l l e r .
swi f t в окне навигатора п роекта и добавьте в верхней части файла свойство
для хранения ссылки на экзем пляр U I S e a rchCont rol l e r, который будет делать
за нас бол ьшую часть тяжелой работы .
c l a s s V i ewCont r o l l e r : U I V i e w C o n t r o l l e r , U I T a Ь l e V i e w Da t a S o u r c e
l e t s e c t i o n s T aЬ l e i de n t i f i e r
" Se c t i o nsTaЬ l e i ndent i f i e r "
va r name s : [ S t r i ng : [ S t r i n g ] ] !
va r k e y s : [ S t r i n g ] !
@ I BOut l e t w e a k va r t a Ь l e V i e w : U I T aЬ l e V i e w !
=
1 1 Добавьте следуJСЦую строку
var searchControl ler : UI SearchController !
Теперь добав и м код, котор ы й создает контроллер поиска, в метод v i e w
DidLoad ( ) , как показано в л истин ге 8 . 1 2 .
338
ГЛАВА 8 11 В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
Л и стинг 8 . 1 2 . Добавление контроллера поиска в метод
vi ewDidLoad в файле ViewCont r o l l e r . swi f t
ove r r i de f u n c v i ew D i dLoad ( ) {
s u pe r . v i e w D i d L o a d ( )
1 1 Допол нител ь н а я на с т р о й к а п о с л е з а гру з ки пред с т а влени я ,
1 1 о быч н о и з n i Ь - фа йл а .
t a Ы e V i e w . r e g i s t e r ( U I T a Ь l e V i ewCe l l . s e l f ,
f o r Ce l l Re u s e i de n t i f i e r : s e c t i o n s T aЬ l e i de n t i f i e r )
l e t p a t h = B u n d l e . ma i n . p a t h Fo r R e s o u r c e (
" s o r t edname s " , o f T yp e : " p l i s t " )
l e t name s Di c t = N S D i c t i on a r y ( c o n t e n t s O f F i l e : p a t h ! )
n ame s = n ame s D i c t a s ! [ S t r i n g : [ S t r i ng ] ]
keys
( n ame s D i c t ! . a l l Ke y s a s ! [ S t r i n g ] ) . s o r t e d ( )
=
l e t r e s u l t s Co n t r o l l e r = S e a r c h Re s u l t s C o n t r o l l e r ( )
r e s u l t s Co n t r o l l e r . name s = name s
r e s u l t s Co n t r o l l e r . k e y s = k e y s
s e a r ch C o n t r o l l e r =
U I S e a r c h C on t r o l l e r ( s e a r c h Re s u l t s C o n t r o l l e r : r e s u l t s C o n t r o l l e r )
l e t s e a r c h B a r = s e a r c h C on t r o l l e r . s e a r ch B a r
s e a r c h B a r . s co p e B u t t o n T i t l e s = [ " Al l " , " S h o r t " , " L o ng " ]
s e a r ch Ba r . p l a c e h o l d e r
" E n t e r а s e a r c h t e rm "
sea rchBar . s i zeToFit ( )
t a Ы e V i ew . t a Ы e H e a d e r V i e w = s e a r c h B a r
s e a r c h C on t r o l l e r . s e a r c h Re s u l t s Up da t e r
r e s u l t s Co n t r o l l e r
=
Нач нем с создания контроллера п редставления результатов и установим его
свойства name s и ke y s . Затем создадим объект класса U I S e a rchCont r o l l e r
и передадим е м у ссылку н а контроллер результатов - именно этот объект бу­
дет играть роль контроллера представления результатов во время демонстраци и .
l e t r e s u l t s Co n t r o l l e r
S e a r c h Re s u l t s C o n t r o l l e r ( )
r e s u l t s Co n t r o l l e r . n ame s
n ame s
r e s u l t sControl l e r . keys = keys
s e a rchCont r o l l e r =
U I S e a r ch C o n t r o l l e r ( s e a r c h Re s u l t s Co n t r o l l e r : r e s u l t s C o n t r o l l e r )
=
=
Следующие три строк и кода п олучают и н астраи вают объе кт класса
U I S e a rchB a r, который создается контроллером кл асса U I S e a r chCont r o l l e r
и которы й м ы получаем и з его свойства s e a r chBa r :
l e t s e a r c h B a r = s e a r c h C on t r o l l e r . s e a r c h B a r
s e a r c h B a r . s co p e Bu t t o nT i t l e s = l " A l l " , " S h o r t " , " Lo ng " ]
s e a r c h B a r . p l a c e h o l d e r = " E n t e r а s e a r ch t e rm "
С войство строки поиска s copeBu t t onT i t l e s содержит имена, назначаемые
кнопкам области видимости. По умолчанию этих кнопок нет, но здесь м ы уста­
навливаем и мена трех кнопок, о которых говорили ранее в этом разделе. М ы так­
же устанавли ваем некоторый замещающий текст, чтобы дать пользователю понять,
для чего эта строка поиска. Вы можете увидеть этот текст на рис. 8 . 3 6, слева.
ГЛАВА 8 .� В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П РЕДСТАВ Л Е Н И Я
339
Пока что мы создал и класс U I S e a rchCont ro l l e r, но не подключ ил и его к
своему пол ьзовател ьскому и нтерфейсу. Для того чтобы это сделать, м ы получа­
ем строку поиска и устанавл и ваем ее как представление заголовка таблицы в
нашем контроллере основного представления.
sea rchBar . s i zeToFit ( )
t a Ь l eVi ew . t a Ы e H e ade r V i e w
=
searchBar
Представление заголовка табл и цы автоматически у правляется табл и ч н ы м
представлением . Заголовок всегда располагается перед первой строкой первого
раздела таблицы. Обратите внимание: чтобы задать размер полосы поиска, под­
ходя щий для его содержи мого, м ы испол ьзуе м метод s i z e T o F i t ( ) . В результа­
те получается верная высота заголовка - шири на, задаваемая этим методом, не
важна, поскол ьку табл ичное представление гарантирует, что оно растя ги вается
на всю ширину табл и цы и будет автоматически изменять размер при изменени и
размера табл ицы (об ы ч но из-за вращения устройства).
Последнее изменение в методе viewDidLoad ( ) присваи вает значен ие с вой­
ству s e a rchRe s u l t s Upda t e r контроллера класса U I S e a rchCont ro l l e r, кото­
рое имеет тип U I S e a rchRe s u l t s Upda t i ng :
s e a r c h C o n t r o l l e r . s e a r c h Re s u l t s Upd a t e r
=
r e s u l t s Co n t r o l l e r
Каждый раз, когда пол ьзователь в водит что-то в строке поиска, объект класса
U I S e a rchCont ro l l e r для обновления резул ьтатов поиска испол ьзует объект,
хранящи йся в свойстве s e a rchRe s u l t s Upda t e r . Как уже упом и налось, поиск
будет выполняться в классе S e a rchRe s u l t sContro l l e r, а потому нам необхо­
димо, чтобы он соответствовал протоколу U I S e a rchRe s u l t s Upda t i ng .
Это все, что нам нужно сделать в нашем главном контроллере для добавления
строки поиска и вы вода резул ьтатов поиска. Далее м ы должн ы вернуться к фай­
лу SearchRe s u l t s Control l e r . swi ft и завершить в нем вы полнение двух за­
дач - добавить код, реал изующий поиск, и методы класса U I TaЬ l e Da t a S ource
для встраи ваемого табл и чного представлени я .
Нач нем с кода для поиска. П о м ере в вода пользователя в строке поиска
объект класса U I S e a rchCont ro l l e r вызы вает метод upda t e S e a rchRe s u l t s
F o r S e a r c hC o n t ro l l e r ( ) дл я обновления результатов с помощью объекта
S e a rchRe s u l t s Cont r o l l e r . В этом методе нам нужно получить текст поис­
ка из строки поиска и испол ьзовать его для создания отфильтрованного списка
имен в массиве f i l t e redName s . М ы также будем использовать кнопки области
видимости для ограничения и мен, включаемых в поиск. Добавьте следующие оп­
ределения констант в верхней части файла SearchRe s u l t sCont rol l e r . swi f t :
c l a s s S e a r c h Re s u l t s C o n t r o l l e r : U I T a Ь l e V i ewCont r o l l e r ,
U I S e a r c h Re s u l t s Up da t i n g (
private s tatic let lonqNameS i ze = 6
private s tatic let shortNamesButtonindex = 1
private s tatic let longName sButtoni ndex = 2
340
ГЛАВА 8 1J11 В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
Добавьте в конец файла код, приведен н ы й в л истин ге 8 . 1 3 .
Л истинг 8 . 1 З . Код для вы вода результатов поиска
1 1 MARK : U I S e a r ch Re s u l t s Up da t i n g C o n f o rm a n c e
f u n c upda t e S e a r c h Re s u l t s ( fo r s e a r c h C o n t r o l l e r : U I S e a r c h C o n t r o l l e r ) {
i f l e t s e a r ch S t r i n g = s e a r c h C on t r o l l e r . s e a r c h Ba r . t e x t {
l e t b u t t o n i ndex = s e a r chCon t r o l l e r . s e a r c h Ba r . s e l e ct edScopeBu t t o n i ndex
f i l t e r e dName s . r emoveAl l ( keep i ng C a p a c i t y : t r u e )
i f ! s e a r ch S t r i ng . i s Emp t y {
l e t f i l t e r : ( S t r i n g ) - > B o o l = { n ame i n
1 1 Фил ь т р а ци я дли н ных или кор о т ких име н в з а в и симо с т и о т кн о п ки
l e t name L e n g t h = n ame . ch a r a c t e r s . c o u n t
i f ( b u t t o n i ndex == S e a r ch Re s u l t s Co n t r o l l e r . s ho r tName s Bu t t o n i ndex
& & name L e n g t h > = S e a r ch Re s u l t s C o n t r o l l e r . l o ngNameS i z e )
1 1 ( bu t t o n i ndex == S e a r chRe s u l t s Co n t r o l l e r . l ongName s Bu t t o n i ndex
& & name L e n g t h < S e a r c h Re s u l t s Co n t r o l l e r . l o ngN ame S i z e ) {
return fal se
l e t r a n g e = name . r a n g e ( o f : s e a r c h S t r i n g , o p t i o n s : N S S t r i ng .
C ompa r e Op t i on s . ca s e i n s e n s i t i ve , r a n g e : n i l , l o ca l e : n i l )
1 1 l e t r a n g e = n ame . r a n g e O f S t r i n g ( s e a r c h S t r i n g ,
1 1 opt i on s : N S S t r i n g .
C omp a r eOpt i o n s . C a s e i n s e n s i t i ve S e a r c h )
return range ! = n i l
f o r key in keys {
l e t n a me s F o r K e y = name s [ ke y ] !
l e t ma t c h e s = n ame s F o r K e y . f i l t e r ( f i l t e r )
f i l t e r e dName s + = ma t c h e s
taЫeView . re l oadData ( )
П ройдемся по этому коду и посмотрим, что он делает. С начала м ы получаем
строку поиска из панел и поиска и и ндекс выбран ной кнопки области видимос­
ти, а затем очищаем сп исок отфил ьтрованных имен :
i f l e t s e a r c h S t r i n g = s e a r chCont r o l l e r . s e a rchBa r . text {
l e t b u t t o n i ndex = s e a r c h C on t r o l l e r . s e a r c h B a r . s e l e c t e d S c o p e Bu t t o n i ndex
f i l t e r e dName s . r e moveAl l ( keep i ng C a pa c i t y : t r u e )
Затем м ы проверяем, что строка поиска не пустая, - м ы не выводим ника­
кие результаты для пустой строк и поиска:
i f ! s e a r ch S t r i n g . i s Emp t y {
Далее определяем замы кание для и мен, соответствующих строке поиска. Замы­
кание будет вызываться для каждого имени в каталоге и мен, давать имя (в виде
строки) и возвращать значение t rue, есл и значение имени соответствует строке
ГЛАВА 8 � В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
341
поиска, и f a l s e, есл и нет. Но сначала проверяем, соответствует ли длина име­
ни выбранной кнопке области видимости, и возвращаем f a l se, если это не так:
let f i l ter : ( S t r i n g ) - > Bool
{ n ame i n
1 1 Фил ь тр а ци я дли н ных или корот ких имен в з а в и симо сти о т к н о п ки
l e t name L e n g t h = n ame . ch a r a c t e r s . c o u n t
i f ( b u t t o n l ndex = = S e a r c h Re s u l t s C o n t r o l l e r . s h o r tName s B u t t o n i ndex
&& name L e n g t h > = S e a r c h Re s u l t s Co n t r o l l e r . l o n gName S i z e )
S e a r c h Re s u l t s Co п t r o l l e r . l o n gN ame s B u t t o n i ndex
1 1 ( b u t t o n i ndex
&& name L e n g t h < S e a r c h Re s u l t s C o n t r o l l e r . l o ngName S i z e ) {
return fa l s e
=
==
Есл и и м я проходит эту проверку, м ы и щем строку поиска как подстроку в
имени. Есл и находи м ее, у нас имеется соответствие:
let r a n g e = name . r a n g e ( o f : s e a r c h S t r i n g , o p t i on s :
N S S t r i ng . Compa r e Op t i o n s . c a s e i n s e n s i t i ve ,
range : ni l , local e : n i l )
return range ! = n i l
Далее переб ираем все кл юч и в словаре и мен, каждый и з которых соответ­
ствует масси ву имен (кл юч А отображается на и м ен а, которые нач и наются с
буквы А, и т.д.). Для каждого кл юча м ы получаем его масси в имен и фильтруем
его с помощью нашего зам ы кан и я . Это дает нам ( возможно, пустой) отфиль­
трован н ы й масси в и мен, которые соответствуют строке поиска и который мы
добавляем в массив f i l te redNarne s :
for key i n keys {
l e t name s Fo r K e y = n ame s [ ke y ] !
l e t ma t c h e s = name s Fo r K e y . f i l t e r ( f i l t e r )
f i l t e redName s + = ma t c h e s
В этом коде объект n arne s ForKey и меет тип [ S t r i ng ] и содержит и мена,
которые соответствуют обрабатываемому значению кл юча. М ы испол ьзуем ме­
тод f i l t e r ( ) ти па A r r a y для применения нашего зам ы кания к каждому из
элементов narne s T o Ke y . В резул ьтате получается другой массив, содержащий
тол ько те элементы, которые соответствуют фил ьтру, т.е. тол ько те имена, ко­
торые соответствуют тексту поиска и кноп ке выбранной области в идимости .
Затем м ы добавляем эти имена в масси в f i l t e redNarne s .
После того как будут обработан ы все м асс и в ы и м е н , у нас в м асс иве
f i l t e redNarne s будет пол н ы й набор имен, соответствующих строке поиска.
Теперь все, что нам нужно сделать, - это организовать их для отображения в
табли це в классе S e a rchRe s u l t s C o n t ro l l e r . Начнем с того, что у кажем таб­
лице на необходимость отобразить ее содержимое:
t a Ь l e V i e w . r e l o a d Da t a ( )
342
ГЛАВА 8 IJ В В ЕД ЕН И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
Н а м нужно, чтобы табл и чное п редставление отображало п о одному имени
из масси ва f i l t e redName s в каждой строке. Для этого м ы реализуем мето­
ды протокола U I TaЬl eViewDa t a S ource в классе S e a rchRe s u l t s Control l e r .
Напом н и м , что класс S e a r c h Re s u l t s C o n t r o l l e r я вляется п одкл ассом
U I Ta Ь l eVi ewCont ro l l e r, поэтому он автоматически действует в качестве ис­
точн и ка дан н ы х его табл и ц ы . Добавьте в файл S e a r chRe s u l t s C o n t r o l l e r .
swi ft код, приведенный в л истин ге 8 . 1 4.
Листинг 8 . 1 4 . Методы источника данных нашего табличного представления
11 МАRК : ТаЫе View Da t a S o u r ce Me t h o d s
ove r r i de f u n c t a Ь l eV i e w ( _ t a Ь l eV i e w : U I T a Ь l eVi ew ,
numb e r O fRow s i n S e c t i o n s e c t i o n : I n t ) - > I n t {
r e t u r n f i l t e redName s . c o u n t
ove r r i de f u n c t a Ь l e V i e w ( _ t a Ь l e V i e w : U I T a Ь l eV i e w ,
ce l l Fo r RowAt i ndex P a t h : I ndex Pa t h ) - >
U I T a Ь l eVi ewCe l l {
l e t ce l l = t a Ы e V i e w . deque u e Re u s a Ь l e C e l l { w i t h i de n t i f i e r :
s e c t i o n s T aЬ l e i de n t i f i e r )
c e l l ! . t e x t Labe l ? . t e x t = f i l t e r e dName s [ i nde x P a t h . r ow ]
r e t u rn ce l l !
Теперь можете запустить приложение и попробовать отфил ьтровать сп исок
и мен, как показано на рис. 8.37.
Alonzo
Enzo
Lorenzo
Vincenzo
Zoe
Zoey
Zo1e
Рис . 8 . 37 . П ри л оже н и е с доба в ­
л е н н о й к табл и це строкой п о и ска
ГЛАВА 8 1!'< В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
343
Отла д ка п редс т авле н ия
Класс U I S e archControl l e r так хорошо выполняет работу по переключению
между двумя табл и цами в нашем последнем при мере, что вы могл и бы просто
не поверить, что такое переключение вы пол няется вообще ! Пом имо того, что
вы видел и весь код, есть также несколь ко визуал ьных подсказок, свидетел ьству­
ющих о переключении, - табл ица поиска я вляется п ростой однородной табл и­
цей, поэтому имена в ней не сгруппированы так же, как в главной табл ице, и у
нее нет раздела и ндекса. Есл и вы хотите еще бол ьше доказател ьств, то можете
получить их с помощью новой возможности Xcode, которая назы вается отлад­
кой представления (View Debugging) и позволяет делать снимки иерархии пред­
ставлений запущенного приложения и изучать и х в области редактора Xcode.
Эта возможность работает как на симуляторе, так и в реал ьных устройствах,
и вы, вероятно, 1юл ностью сможете оцен ить ее, когда поп ытаетесь выяснить,
почему одно из ваш их представлен и й кажется отсутствующим ил и поя вляется
не там, где вы ожидаете его видеть.
Начнем с того, что посмотрим, что сделает фун кция View Debugging из наше­
го приложения, когда оно показы вает пол н ы й список имен. Запустите приложе­
ние и в строке меню Xcode вы пол ните команду Debugc:>View Debuggingc:> Capture
View H ierarchy . Програм ма Xcode получает иерархи ю представлений из симуля­
тора ил и устройства и вы водит ее так, как показано на рис. 8.38 .
. ,,..,
·-
Ci....
·.
,", ....
А
.....
· -
.
.
'
.
АЫg1!1
- --
m • ... J:-
1
1
- � +
е
e в 'li
о > 4
......_ , . ,,..... , ) D o 41o\11\J1181.ь-.
D () @ D
т..- .,... °""'*" �
-- - ...... · - -
'
;
· ,,.... � . � ..... " ....
j " .... ....... " .,_ _
РВ е -
Рис. 8 . 38 . И е рархия п редставл е н и й п риложе н и я Secti ons
•
344
ГЛАВА 8 w. В В ЕД Е Н И Е В ТАБЛ И Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
Вероятно, это выглядит не очень полезно - м ы не видим ничеm большего,
чем могл и бы видеть в симуляторе. Для тоm чтобы выявить иерархию представ­
лений, необходимо повернуть изображение приложения так, чтобы вы могли по­
смотреть на неm "со стороны''. Для этого нажм ите кнопку мыши в области редак­
тора, где-то слева от изображения, и перетащите указател ь вправо. Когда вы это
сделаете, наслоение представлений в приложении станет види м ы м . Есл и вы по­
вернете представления на уmл около 45°, то увидите что-то наподобие рис. 8.39.
88 (
)
Sections )
UIWindow
-
.......
"...
-
B B !ii!i
ЕВ
- = +
Рис . 8.39. Изуч е н и е и е ра рх и и п р едста вл е н и й п р иложе н и я
Щел кнув на разл ичных п редставлениях в стеке, вы увидите, что панел ь пе­
реходов в верхней части измен ится и покажет и м я класса п редставления, на
ГЛАВА 8 �1 В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
345
котором был сделан щел чок, и и мена классов всех родительских nредставлен и й .
Щел кните на каждом из nредставлений с последнего д о первого, чтобы ознако­
миться с тем , как строится табл и ца. Вы сможете найти главное nредставление
контроллера nредставления, табл и ч н ые nредставления, некоторые nредставле­
ния ячеек, панел ь nоиска, nанель и ндекса и разл и ч н ые nредставления, которые
являются частью реал изаци и табл и цы .
Теперь nосмотрим, как в ы глядит иерархия nредставлений в о время поиска.
Програм ма Xcode nриостанавл и вает работу nриложения, nозволяя изучить сни­
мок представлений, nоэтому сначала возобновим вы nол нен ие, выбрав коман­
ду Debug c:::> Continue. Н ач н ите ввод в строке nоиска и вновь вы пол н ите команду
Debug qView Debugg ing c:::> Capture View H ierarchy. Когда nоя вится иерархия пред­
ставлений, nоверн ите ее немного, и вы увидите что-то наподобие рис. 8.40.
-
-
-
-
...
.
-
-
-
-
В В l!З
ЕЕ
- == +
Рис . 8 .40. И е рархия п редста вл е н и й п ри и с п ол ьзова н и и строки п о и ска "Zoe"
Сейчас совершенно очевидно, что действител ьно испол ьзуются две табл и­
цы . В ы можете увидеть исходную табл и цу при мерно на nол пути через стек
представлений, а выше (т.е. справа) - табл и ч ное представление, которое п ри­
надлежит контроллеру nредставления резул ьтатов поиска. С разу за ним есть
nолуnрозрачное серое представление, покры вающее исходную табли цу, - это
nредставление затемняет исходную табли цу в начале ввода в строке поиска.
346
ГЛАВА 8 1.111 В В ЕДЕ Н И Е В ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
Немного поэкспериментируйте с кноп ками в нижней части области редакто­
ра - их можно испол ьзовать для вкл ючения и откл ючения отображения огра­
ничений механизма Auto Layout, сброса представления вниз иерархии, а также
увеличения и уменьшения масштаба. Можно также измен ить расстоя н ие между
представлен и я м и с помощью ползунка в левой части и испол ьзовать ползунок
справа для удаления слоев в верхней или н ижней части иерархии, так что вы
сможете у видеть, что находится за н и м и . View Debuggiпg - очен ь мощн ы й
инструмент.
Р е з ю ме
Это была сол идная глава, и вы изуч или массу новинок. Теперь вы должны
очень ясно понимать, как работают табл ицы, знать, как настроить табл и цы и
я чейки табл и ч н ы х представлений, и конфигурировать табл и ч н ые представле­
н и я . Вы также узнал и, как реал изовать панел ь поиска, которая я вляется жиз­
ненно важным и нструментом в любых ЮS-приложен иях, которые представля­
ют пол ьзователя м большие объемы дан ных. Наконец вы познакомились с View
Debugging - новы м исключ ител ьно полезн ы м инструментом среды Xcode .
Убедитесь, что хорошо понимаете все, что м ы делали в этой главе, потому что
дальнейший материал будет опираться на эту главу.
М ы продолжим работу с табл и ч н ы м и представлен и я м и в следующей главе.
Н апри мер, вы узнаете, как испол ьзовать их для представления иерархических
дан н ых; увидите, как создать представления, которые позволяют пол ьзовате­
лю редактировать дан н ые, выбран ные в табл ич ном представлении, а также как
представлять в табли цах переч ни, вставлять элементы управления в строки таб­
лиц строк и удалять строки.
ГЛ АВА 9
• •
К о н тр о лл еры н а в и г ац и и
и т абл и ч н ые п редст а в л е н и я
В предыдущей главе мы сосредоточились на основах рабСУГы с табличны м и пред­
ставлениями, а в этой м ы сделаем акцент на изучении контроллеров навигации.
Контроллеры нав и гации и табл и ч н ые представления дополняют друг друга,
но, строго говоря, контроллер нав и гации для в ыпол нения своих фун кций может
обойтись без таблич ного представления . Однако на п рактике при реал изации
контроллера навигации почти всегда используется хотя б ы одна табл и ца, по­
скол ьку мощь контроллера навигации как раз и состоит в простоте, с которой он
обрабаты вает сложные иерархические данные. На небольшом экране устройства
i Phone иерархические дан ные лучше всего представля ются именно с помощью
последовател ьности табличных представлен и й .
В этой главе м ы шаг з а шагом создадим новое приложен ие, подобно тому,
как сделал и приложен ие Pickers в главе 7 . М ы создадим корневой контроллер
навигаци и и, как тол ько он заработает, будем добавлять другие контроллеры и
наращи вать уровни иерархи и . Каждый создаваем ы й нам и контроллер нави гации
будет усил ивать тот ил и иной аспект испол ьзован ия табл и цы или конфигурации,
в резул ьтате чего вы получ ите ответы на следующие вопросы :
.r'
'�i
ifi
как перейти от табл и ч н ы х п редставлений к дочерним табл и ч н ы м пред­
ставлениям;
как перейти от табличных представлен и й к представлениям содержан ия,
которые позволят не тол ько отобразить детал изиро ван ные дан н ые, но и
отредактировать их;
как испол ьзовать нескол ько разделов в табличном представлен ии;
'" как испол ьзовать режим редактирования, чтобы из табл ичного представ­
ления можно было удалять строки;
>;;>
как испол ьзовать режим редактирован ия, чтобы пол ьзовател ь мог пере­
упорядоч и вать файл ы в табл и ч ном представлен и и .
348
ГЛАВА 9 �' КОНТРОЛ Л Е Р Ы НАВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П Р ЕДСТА ВЛ Е Н И Я
О сновы контролл еров нави гаци и
Основ н ы м инструментом , которы й м ы будем испол ьзовать для написания ие­
рархических приложений, я вляется класс U I Navi g a t i onCont r o l ler, который
похож на класс U I TabBa rCont ro l l e r в том, как он управляет представления м и
содержимого, загружает и в ы гружает и х . Основное разл ичие между эти м и �ас­
сам и состоит в том, что класс U I Navi g a t i onCon t r o l l e r реал изован как стек,
что делает его весьма подходя щим для работы с иерархия м и .
Есл и у вас есть знан ия в этой области, вы м ожете просто перел истать эту
главу. Есл и же терм и н стек вам незнаком, продолжайте ч итать. К счастью, по­
нять, что такое стек, не так уж трудно.
Стеки
С тек (stack) - это часто используемая структура данн ых, которая работает по
принципу "последни м вошел - первым вы шел". П рекрас н ы й при мер стека механическая игрушка-дозатор Pez (рис. 9. 1 ) . Вам когда-л ибо доводилось заправ­
лять его конфетам и? В соответствии с небол ьшой и нструкцией, которая прила­
гается к каждой такой игрушке, вам необходимо вы пол н ить нескол ько простых
действий. Во-первых, раз верните упаковку конфет. Во-вторых, откройте дозатор,
опрокинув его верхуш ку н азад. В-третьих, возьм ите конфеты, крепко удерживая
их между указател ьным и большим пальцами, и вставьте в открыты й дозатор.
Рис . 9 . 1 . Меха н и че с кая и груш ка-до­
зато р Pez
-
п росто й п р и м е р сте ка
Помните, м ы сказали о стеке "последни м вошел - первы м вышел"? Вот имен­
но так у нас и получается с этим дозатором . Первую конфету, которую вы опус­
тите в дозатор, вы сможете достать из него тол ько в последнюю очередь. В то же
время последняя конфета, которую вы затолкнули в дозатор, останется верхней, а
значит, ее вы достанете первой. Компьютерный стек работает по тем же правилам .
!Н
Добавляя объект в стек, м ы говорим, что затал ки ваем (push) его в стек.
':';' Первы й объект, который в ы поместил и в стек, назы вается основа н и ем
стека (base ).
ГЛАВА 9 '"' КОНТРОЛ Л Е Р Ы Н А В И ГА Ц И И И ТАБ Л И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
tiЗ
349
Последн и й объекr, который вы поместил и в стек, н азы вается верш и н о й
стека (top) (он остается тако в ы м до тех пор, пока в ы не замен ите его
следующим объекrом, которы й поместите в стек).
"' Удаляя объекr из стека, м ы говорим, что выталк и ваем (рор) его из стека.
Удаляем ы м из стека объекrом всегда оказы вается объект, который был по­
мещен туда последним. И наоборот, первый объекr, который был помещен
в стек, всегда извлекается из него последни м .
Стек контроллеров
Контроллер навигации обслужи вает стек контроллеров представления. П ри
разработке контроллера навигации вам необходимо у казать первое представле­
ние, которое увидит пол ьзовател ь. Как упом иналось в предыдущих главах, та­
кое представление назы вается ко нтроллером корневого п р едставления (root
v iew control ler) ил и просто корневым контроллером (root contro l ler) и служит
основан ием стека контроллеров представления в контроллере нав и гаци и . П р и
выборе пользователем следующего представления для отображения новы й кон­
троллер представления помещается в стек, в резул ьтате чего и на экране появ­
ляется соответствующее представление. Мы наз ываем эти новые контроллеры
представлен и й под ко н т роллера м и (subcontro l ler). Как будет показано н иже,
приложение Fonts, которое мы создадим в этой главе, будет состоять из конт­
роллера навигации и нескол ьких подконтроллеров.
Посмотрите на рис. 9.2. Обратите в н имание на заголовок посредине нави­
гационной панел и и на кнопку возврата в левой ч асти этой панел и . Заголовок
нави гационной панел и запол нен свойством Ti t l e контроллера представления,
находящегося на верш и не стека, а наз ван ие кнопки навигации запол нено свой­
ством Т i t 1 е предыдущего контроллера представления. Эта кнопка похожа на
кнопку возврата в окне веб-браузера. Есл и пол ьзовател ь нажмет эту кнопку,
контроллер текущего представления будет извлечен из стека и текущим станет
предыдущее представление.
Нам нравится этот шаблон проекrирования, так как он позволяет итеративно
создавать сложные иерархические приложения. Для того чтобы система посто­
янно находилась в состоян и и готовности к работе, нам необязател ьно знать всю
иерархию. Каждый контроллер должен знать тол ько о существовани и своих до­
черних контроллеров, чтобы, когда пользователь делает выбор, контроллер мог
поместить в стек соответствующий объекr нового контроллера. Таким спосо­
бом можно нап исать бол ьшое приложение из нескольких маленьких составля ю­
щих - и менно этим м ы и зай мемся в данной главе.
Контроллер навигации можно н азвать ядром м ногих i Рhоnе-приложений, но
в приложениях для устройства i Pad контроллер навигаци и и грает менее значи­
тел ьную рол ь. В качестве тип и ч ного примера можно привести i Рhоnе- приложе­
ние Mail, содержащее иерархический контроллер навигации, которы й позволя­
ет пол ьзовател ю легко перемещаться между почтовыми серверам и, папкам и и
350
ГЛАВА 9 t\' КОНТРОЛЛ Е Р Ы НАВ И ГА Ц И И И ТАБ Л И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
сообщениями. В i Раd-версии приложения Mai l контроллер навигаци и никогда не
запол няет экран, но отображается в виде л ибо врезки, л ибо временного представ­
ления, закрывающего часть основного окна. М ы разберемся с этим в главе 1 1 .
К ноп к а
во з вр ата
Vibrate on Rlno
ViЬrtte on Sllent
··�
Ch•noe wlth Button•
C[_i
Jht � of the 1tn!f�• ....1 titwte: c;nn Ь. adlim,...:;i
\....,tf lt'ot \'C>i-.Mft' Ь...11<.,11
Темt TOf\8
New VolcemaM
New Ma!I
Sent Мail
'·l·.i�
rr - t(')f":
()!ng
Swo�h
Рис. 9 . 2 . П риложе н и е Setti n g s и с п ол ьзует ко нтролл ер
н а в и га ци и . В л е в о м ве рхн е м угл у н аходится к н о п ка
в о з в рата , кото рая и спол ьзуется дл я и з вл е ч е н и я ко н ­
троллера текущего п р едста вл е н и я и з сте ка . Н ажатие
этой кнопки возвращает вас н а п р едыдущи й уровен ь
и е ра рхи и . С п рава отображается загол овок контролл е ­
р а те кущего представл е н и я соде ржи м о го
Font
-
п ростой бра у з ер шрифтов
На примере приложения, к нап и сан и ю которого м ы присrуnаем, будет пока­
зано, как можно справиться с больши нством распространенных задач, связан ных
с отображением иерархи и дан н ы х . При запуске этого приложения вы увидите
сп исок всех семейств ш рифтов, и м еющихся в iOS, как показано на рис. 9.3 .
Семейство шрифтов представляет собой группу тесно связан ных шрифтов, ил и
шрифтов, я вл я ющихся стил истически м и вариаци я м и дру г друга. Например,
шрифты Helvetica, Helvetica-Bold, Helvetic-OЬ\ ique и п рочие вариации входят в
семейство шрифтов Helvetica.
ГЛАВА 9 i: КОНТРОЛ Л Е Р Ы Н А В И ГА Ц И И И ТАБЛ И Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
cмri.r •
3:1t PM
Fonts
All Font Familles
351
-
AI Nlle
Aш.rl•llЛ '1',уреwмtм
Arмric.8t\ TyJМwrlter
App l e
Co l o r
Appl< Cokн Emol'
Emoj l
Applt SO Gothlc Neo
t.pp \41 SO Gothk: Neo
Arial
Arlal Нebrew
Arlвl Rounded МТ Bold
Avenir
.......
Awnlr Ntllt Condtnstd
Alt.,Ur Nht COfIOfn1ed
Bangla Sangam MN
8Jn;/I SanQl)ln MN
Рис . 9 . 3 . В н а ш е м п р о е кте контрол л е р к о р н е в о го
представле н и я п р иложе н и я в ы водит на экран вспом о ­
гател ь н ы е п и кто гра м м ы в п равой части каждой строки
п редставл е н и я . Эти п и ктогра м м ы назы ваются и нди ка ­
тора м и раскрытия . Е сл и коснуться строки с та к и м и н ­
ди катором , то отоб раз ится табл и ч ное п р едставл е н и е
бол ее н и з кого уро в н я
Выбор любой строки в этом представлении верхнего уровня затал кивает кон­
троллер представления в стек контроллеров навигации . П и ктограм м ы в правой
части ,каждой строки назы ваются вспомогател ь н ы м и (accessory icons). В част­
ности, такая вспомогател ьная п и кто грамма (в в иде серой стрел ки) наз ы вается
и нди катором раскрытия (di sclosure indicator), поскол ьку уведомляет пол ьзова­
теля о том , что при выборе этой строки раскроется еще одно табл и чное пред­
ставление.
352
ГЛАВА 9 � КОНТРОЛ Л Е Р Ы НАВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
Подконтроллеры приложения Fonts
П режде чем присrупать к написанию приложения Fo11ts, необходимо вкратце
рассмотреть все его подконтроллер ы .
Контроллер списка шрифтов
Коснувшись первой строки табл ицы, показанной на рис. 9.2, можно открыть
дочернее представление, показанное на рис. 9.4.
C•rrw •
( Fonts
-
4:01 РМ
Gill Sans
GillSans
Ol,ИS1ns
(Т)
GIJISans-Bokl
G!-Sмit·Bokl
(])
Gil/Saм�wfrc
ooss.nt ·llaic:
(!)
Gl//Sans-Boldltollc
OOIS•nt·&�li..I�
G.11Sans-1Jgh1
GllSllnt ·LIQht
GNSans ug11lhahc
OiltSan•·LIQl'ltlt.tlic
GIПSan1-Semi8old
GIUant·Seml8old
Gll/San1..S..mf8oldltalk
GillSan•·Semf8old11alk
............ ." ••••d
Od/S8ttt•Uhr•Вold
(i)
(i)
Q)
(!)
CD
(i)
Рис . 9 . 4 . П е р в ы й из подконтрол л е р о в п р иложе н и я Fonts
реал и зует табл и цу, в кото р о й каждая строка с оде ржит
к н о п ку раскрытия детал и з и рова н н ой и н фо р м а ц и и
Вспомогательные пиктограм м ы в правом конце каждой строки (рис. 9.4) нем но­
го отличаются от стрелок, которые м ы видели раньше. Они наз ываются кнопками
раскрытия детализированной информации (detail disclosure butto11). В отличие
от индикатора раскрытия, кнопка раскрытия детал изированной информации - это
ГЛАВА 9 >ii КОНТРОЛ Л Е Р Ы НАВ И ГАЦИ И И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
353
не nросто nи кгограмма, а уnравляющий элемент, который nользователь может на­
жи мать. Это означает, что строка с такой кнопкой nредоставляет nол ьзовател ю
два варианта действия: одно связы вается с выбором строки, а другое - с на­
жатием кнопки раскрытия . Нажатие маленькой информацион ной кнопки должно
позволить пол ьзователю просматривать и, возможно, изменять более подробную
и нформацию о текущей строке. Наличие же стрелки, наnравленной вправо, сооб­
щает пол ьзователю, что имеется возможность более глубокой навигации, которую
можно найти путем нажатия в другом месте строки .
Контроллер представления размеров шрифтов
Прикосновение к л юбой строке табл ицы, показанной на рис. 9.4, nриводит к
выводу дочернего представления, показанного на рис. 9 . 5 .
( Gill Sans
GillSans-Вold
-8 0 0011'1
CJIUl.ans·8old
13.О pom1
GlllSant·Bold
14.0 pojn1
CilllSans·Bold
18.0 poil'lt
GlllSans- Bold
2• о ро1м
G ШSans - Bold
38 О ро1111
G i l l Sans - Bold
Рис . 9 . 5 . Контрол л е р п р едста вл е н и я размеров ш р и ф­
то в , н аходя щийся н а оди н урове н ь глубже контроллера
п редста вл е н и я с п и ска ш р и фто в , п о к а з ы вает раз н ы е
размеры выбран ного ш р и фта по одн о м у в строке
354
ГЛАВА 9 � КОНТРОЛ Л Е Р Ы НАВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
Использование индика торов и кнопок раскрытия
Сформулируем краткие правила применения индикаторов и кнопок раскры­
тия детализированной информаци и .
.li
Есл и вы хотите предложить еди нственный выбор при нажатии строки, не
испол ьзуйте вспомогател ьную п и ктограм му, когда нажатие строки 'ведет
только к более детал ьному представлению строки.
�
Помечайте строку и ндикатором раскрытия (стрелка вправо), если нажатие
строки ведет к новому п редставлению, содержащему больше элементов
(не к детал изированному п редставлению).
�
Если вы хотите предложить два варианта выбора в строке, пометьте ее
л ибо с помощью инди катора раскрытия детал изирован ной и нформации,
л ибо с помощью кнопки детал изиро ван ной информаци и . Это позволит
пользовател ю нажать строку для получения нового представления ил и
кнопку раскрытия для получения подробной и нформации .
Контроллер представления информации о шрифте
Наш последний подконтроллер приложения - еди нствен ный, которы й не я в­
ляется табл и ч н ы м представлением, - показан на рис. 9.6. Это представление
поя вляется при нажатии п и ктограм м ы и нформации в л юбой строке в контрол­
лере представления сп иска шрифтов, показанного на рис. 9.2.
Это представление позволяет пол ьзовател ю перетащить ползунок, чтобы на­
строить размер отображаемого шрифта. Оно также в кл ючает переключател ь,
которы й позволяет указать, должен ли этот шрифт быть перечислен среди пред­
поч итаемых шрифтов пол ьзователя . Есл и некоторые шрифты установлены как
предпоч итаем ые, они поя вляются в отдел ьной группе ко нтроллера корневого
представления.
О снова прилож ения для работы с шрифтами
Програм ма Xcode предлагает очень хоро ш и й шаблон для создания прило­
жен и й на основе навигации, и вы, скорее всего, будете часто его испол ьзовать,
когда потребуется создавать иерархические приложения. Однако сейчас мы не
собираемся испол ьзовать этот шаблон - мы будем строить наше приложение на
основе навигаци и "с нуля'', чтобы прочувствовать, как все соединяется в единое
приложение. М ы пройдем через весь п роцесс создания приложения постепен но,
так что он не должен быть тяжелы м для вас.
В среде Xcode нажм ите ком б инацию клавиш <X +Shift+N> для создания
нового проекта. В ы берите элемент Single View Application из списка шаблонов
iOS, а затем щелкн ите на кноп ке Next. Установите значение Font s дл я атрибута
Product Name, выберите пункт Swift в сп иске Language и пункт U niversal в спис­
ке Devices. Убедитесь, что флаг U se Соге Data сброшен, щел кн ите на кнопке
Next и выберите местоположение для сохранения вашего проекта.
ГЛАВА 9 !'l КОНТРОЛЛ Е Р Ы НАВ И ГАЦИ И И ТАБЛ И Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
( Gill Sans
355
OillSans·Вold
AaBbCcDd
Ee FfGgH h l
iJj Kk LI M m
N nOoPpQ
q RrSsTtU
uVvWw . . .
lncl\Jde ln favorites:
61
Рис . 9 . 6 . П оследн и й контролл е р п редставл е ­
н и я в п р иложе н и и Fonts п о з вол я ет просмот­
реть в ыб ра н н ы й ш р и фт л ю бого раз м ера
Настройка контроллера навигации
Теперь нужно создать базовую структуру навигации для нашего приложения.
Ее ядром будет класс U INavi g a t i onCont ro l l e r, у правляющий стеком конт­
роллеров представлений, между которы м и может перемещаться пользователь, и
класс U I TaЬ l eViewCon t ro l l e r, показы вающий список строк верхнего уровня,
который мы собираемся выводить. Оказывается, l nterface Bui lder делает это легко.
В ы бер ите файл M a i n . s t o r y b o a r d . Шабл о н создал дл я нас контрол­
лер основного п редставления, но вместо него нам надо испол ьзовать класс
U I Nav1i g a t i onCon t ro l l er, так что выберем контроллер представления л ибо в
области редактора, л ибо в окне Docu ment Outl i ne и удали м его, чтобы раскадров­
ка стала пустой. Затем воспол ьзуемся библ иотекой объектов, найдем в библ ио­
теке класс U INavi g a t i onCont r o l l e r и перетащим его экземпляр в редактиру­
емую область. В ы увидите, что фактически получил и вместо одной две сцены,
подобно тому, что м ы видел и при создании контроллера представления вкладок
в главе 7. Слева находится класс U I Navi g a t i onCont r o l l e r . В ыберите этот
контроллер, откройте окно инспектора атрибутов и установите флажок ls l n itial
356
ГЛАВА 9 �• КОНТРОЛ Л Е Р Ы Н А В И ГАЦИ И И ТА БЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
View Contro l l e r в разделе View Contro l l e r, чтобы этот контроллер поя влялся при
запуске приложения на вы полнение.
Класс U INavi g a t i onCont rol l e r подключен ко второй сцене, которая содер­
жит класс U I TaЬ l eVi ewCont r o l l e r . Вы увидите, что табл ица имеет заголовок
Root View Contro l l e r . Щел кните на нем, откройте окно и нспектора атрибутов
и установите в качестве заголовка Fon t s .
Таки м образом, м ы получаем представление, созданное контроллером нави­
гаци и, составное представление, которое содержит комби нацию, состоя щую из
панел и навигации в верхней части экрана (обычно она содержит какой-то заго­
ловок и зачастую некоторую кнопку возврата слева) и содержания того, что кон­
троллер текущего представления контроллера нави гации план ирует вы водить.
В нашем случае н ижняя часть дисплея будет запол нена табл и ч н ы м представле­
нием, которое было создано вместе с контроллером нав игаци и .
По мере изучения главы в ы узнаете бол ьше о том, как управлять тем, что
контроллер навигации отображает на панел и нави гаци и . Вы также будете пони­
мать, как контроллер нави гации перемещает фокус с одного контроллера под­
ч и нен ного представления на другой . Пока что в ы зал ожил и достаточ н ы й фун­
дамент, чтобы можно было присту п ить к о пределению того, что собираются
делать ваш и контроллеры пользовател ьских представлен и й .
В данн ы й момент основа приложения, по существу, завершена. Вы увиди­
те предупрежден ие о настрой ке повторно испол ьзуемого идентифи катора для
ячейки табл и цы прототи па, но сейчас его м ожно игнорировать. Сохраните все
ваш и файл ы, а затем постройте и запустите приложение. Есл и все прошло хо­
рошо, приложение должно запуститься и должна п оя в иться панел ь нави гации
с заголовком Fon t s . Вы не предоставил и табл и ч ному п редставлению ни какой
и нформации о том, что следует показы вать, так что пока н и какие строки в нем
не отображаются (рис. 9.7).
Отсл еживание предпочитаемых шрифтов
В нескол ьких точках дан ного приложения мы план ируем дать пол ьзователю
возможность поддержки сп иска любимых шрифтов, позволяя ему добавлять в
него выбран ные шрифты, просматривать с п исок уже выбранных предпоч итае­
мых шрифтов и удалять из него шрифты . Для того чтобы согласованно управлять
этим списком, мы собираемся создать новый класс, который будет работать с
масси вом предпоч итаемых шрифтов и хран ить их в пользовател ьских параметрах
настройки дан ного приложения. В ы узнаете намного бол ьше о пользовательских
настройках в главе 1 2; здесь же мы коснемся тол ько некоторых основ.
Нач нем с создания нового класса. Выберите папку Fon t s в окне нави гатора
проекта и нажм ите комби нацию клавиш <�+N> для вызова нового файлово­
го помощн и ка. В ыберите элемент Swift F i l e в разделе IOS Sou rce и щел кн ите
на кнопке N ext. На следующем э кране назовите новый файл Favo r i t e s L i s t .
swi f t и щел кн ите на кноп ке C reate . Выберите новый файл в окне нави гатора
проекта и добавьте в него код, представлен н ы й в л исти н ге 9 . 1 .
ГЛАВА 9 lli КОНТРОЛЛ Е Р Ы Н АВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П Р ЕДСТА В Л Е Н И Я
....
-Caпier •
ne 6а - IOS 10.G (14A!i2117tl
8:27 АМ
Fonts
-
Рис. 9 . 7 . О с н о в а п р ил оже н и я
без каких-л и б о дан н ых
Л истин г 9 . 1 . Файл класса Favo r i t e s Li s t
imp o r t Founda t i o n
imp o r t U I K i t
c l a s s Favo r i t e s L i s t
s t a t i c l e t s h a r e d F a vo r i t e s L i s t = Favo r i t e s L i s t ( )
p r i v a t e ( s e t ) va r f a vo r i t e s : [ S t r i n g ]
init ( ) {
l e t de f a u l t s = U s e r D e f a u l t s . s t a nda rd
l e t s t o r e d Fa vo r i t e s = de f a u l t s . ob j e c t ( f o r K e y : " f a vo r i t e s " ) a s ?
[ S t r i ti g ]
f a vo r i t e s = s t o r e d Favo r i t e s ! = n i l ? s t o r e d Fa vo r i t e s ! : [ ]
f u n c addFavo r i t e ( f o n tName : S t r i n g ) {
i f ! f a vo r i t e s . co n t a i n s ( f o n t N ame ) {
favo r i t e s . append ( f o n t N ame )
s ave Favo r i t e s ( )
357
358
ГЛАВА 9 � КОНТРОЛ Л Е Р Ы НАВ И ГАЦИИ И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
f u n c rernove Favo r i t e ( f o n t N arne : S t r i n g ) {
i f l e t i ndex
f a vo r i t e s . i ndex ( o f : f o n tN arne )
f a vo r i t e s . r ernove ( a t : i n dex )
s ave Favo r i t e s ( )
=
p r i va t e f u n c s ave Favo r i t e s ( ) {
l e t de f a u l t s = U s e r D e f a u l t s . s t a n d a r d
de f a u l t s . s e t ( f a vo r i t e s , f o r Ke y : " fa vo r i t e s " )
de f a u l t s . s yn c h r o n i z e ( )
В п редыдущем фрагменте м ы объя вил и и нтерфейс прикладного програм ми­
рован ия для нашего нового кл асса. Для начала мы объя вил и свойство класса с
и менем sharedFavo r i t e s L i s t , которое возвращает экземпляр дан ного класса.
Независ и м о от того, с коль ко раз вызывается этот метод, всегда будет возвра­
щаться оди н и тот же э кзе м пляр. Идея заключается в том, что Favo ri t e s L i s t
должен б ыть синrлтоном, т.е. в о всем приложении может испол ьзоваться тол ько
оди н экземпляр этого класса.
Затем мы объя вляем свойство для хранения имен наш их предпоч итаемых
шрифтов. Обратим особое вниман ие на о пределение этого масси ва:
p r i va t e ( s e t ) va r f a vo r i t e s : [ S t r i n g ]
Квалификатор private ( set ) означает, что массив может быть прочитан кодом,
находящимся вне класса, но модифицировать его может только код внутри клас­
са. Это именно то, что нам надо, поскол ьку м ы хотим, чтобы пользователи класса
были способны читать список предпочитаемых шрифтов:
l e t f a vo r i t e s
ра зреше но
=
Favo r i t e s L i s t . s h a r e d Favo r i t e Li s t . favo r i t e s / / Ч те ние
Однако мы не хоти м, чтобы был и позволены приведенные далее действия:
Favo r i t e s L i s t . s h a r e d Fa vo r i t e L i s t . f a vo r i t e s
[ ] / / Н е р а зреше но
Favo r i t e s L i s t . s h a r e d Favo r i t e L i s t . f a vo r i t e s . ap p e n d (
" C orn i c S a n s MS " ) / / Н е р а зрешено
=
Ин ициализатор класса отвечает за установку н ачал ьного содержи мого мас­
сива favo r i t e s :
init ( ) {
l e t de fa u l t s = U s e r De f a u l t s . s t a n d a r d
l e t s t o r e d Fa vo r i t e s
de f a u l t s . ob j e c t ( f o r Ke y : " f avo r i t e s " ) a s ? [ S t r i ng ]
f a vo r i t e s
s t o r e d Favo r i t e s ! = n i l ? s t o r e d Fa vo r i t e s ! : [ ]
=
=
Как вы вскоре увидите, в л юбой момент, когда м ы что-то добавляем в масси в
ил и удаляем из него, м ы сохраняем его содержи мое в настрой ках пол ьзователя
ГЛАВА 9 ;i, КОНТРОЛЛ ЕРЫ НАВ И ГАЦИИ И ТАБЛИ Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
359
(о чем мы поговорим более п одробно в главе 1 2) так, чтобы содержимое спис­
ка сохранялось при перезапуске приложения. В и н и циал изаторе мы п роверяем,
имеется ли у нас сохраненный список предпочитаемых шрифтов, и если да, то
используем его дл я и н и циализаци и с войства favo r i t e s . Есл и нет, то просто
делаем его пусты м .
Оставш иеся три метода предназначены для добавления и удаления записей
из массива предпоч итаемых шрифтов . Реал изаци и должны быть самоочевидны .
Обратите вни мание, что первые два метода вызы вают s ave Favo r i t e s ( ) , кото­
рый сохраняет обновленное значение в пол ьзовател ьских настройках с тем же
ключом ("favorites"), которы й и н и циал изатор испол ьзует для чтения . О том, как
это работает, вы узнаете подробнее в главе 1 2 ; а сейчас достаточно знать, что
объект N S U s e rDe faul t s , который м ы испол ьзуем здесь, действует как своего
рода сохраняемый словарь, и все, что м ы поместим в него, будет доступно при
следующем запуске, когда м ы выпол н и м запрос, - даже если при этом прило­
жение было остановлено и перезапущено позже.
ЗАМЕЧАНИЕ. В верс и и Xcode 8 ком п а н и я Apple сделала м ногие старые объе кты ,
имя класса которых начинается с префикса N S - , более удоб н ы м и дл я использова­
ния в языке Swift ; в частности , класс N S U s e r D e f a u l t s теперь назы вается п росто
U s e r De faul t s .
Создание контроллера корневого представления
Теперь м ы готовы начать работу над наш и м первым контроллером представ­
ления. В предыдущей главе мы испол ьзовал и простые массивы строк для запол­
нения таблицы. М ы собираемся сделать что-то подобное и здесь, но на этот раз
будем испол ьзовать класс U I Font для получения списка семейств шрифтов, а
затем использовать имена этих семейств шрифтов для запол нения каждой стро­
ки . Мы также будем испол ьзовать сам и шрифты для отображения их названи й
так, чтобы каждая строка, по сути, содержала небол ьшой предварител ь н ы й про­
смотр семейства шрифтов.
Настало время дл я создания первого кл асса контроллера данного прило­
жен и я . Шаблон создает для нас контролл ер п редставления, но его и мя ViewCont r o l l e r - не сл и ш ком удачное, потому что в этом приложении бу­
дет нескол ь ко контроллеров представления . Так что сначал а в ыберите файл
V i e w,C o n t r o l l e r . s w i f t в окне нави гатора п роекта и н ажм ите клавишу
<Delete>, чтобы удалить его и переместить в корзи ну. Далее выберите пап­
ку Fon t s в окне навигатора проекта и нажмите комбинацию клавиш <X+N>,
чтобы вызвать помощн и к по создан и ю новых файлов. В ы берите элемент Со­
соа Touch Class в разделе IOS Source и щел кн ите на кно п ке Next. На следу­
ющем экране назов ите новый кл асс Ro o t V i ewC o n t r o l l e r и в ведите и м я
U I TaЬ leVi ewCon t ro l l e r в качестве значен ия атрибута Su bclass of. Щелкните
на кнопке Next, а затем на кнопке C reate для создания нового класса. В ыберите
360
ГЛАВА 9 :JJ: КОНТРОЛЛ Е Р Ы НАВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
файл Ro o tV i ewCont ro l l e r . s w i f t в о к н е нави гатора п роекта и добавьте в
него в ыделен н ы е полужирн ы м шрифтом строки из приведен ного далее фраг­
мента кода.
c l a s s Ro o t V i ewCon t r o l l e r : U I T a Ь l eV i e w C o n t ro l l e r
private var fami lyNames : [ S tring ] !
private var cel lPointSize : CGFloat !
private var favori te s L i s t : Favorite s Li s t !
private s tatic let fami lyCell
" FamilyName "
private s tatic let favoritesCell
" Favori te s "
=
=
М ы будем с самого н ач ала присваи вать значения перв ы м трем и з этих
свойств, а затем испол ьзовать их в разл и чные моменты, когда испол ьзуется этот
класс. Массив f ami l yName s будет содержать с писок всех семейств шрифтов,
которые м ы плани руем отображать; свойство ce l l P o i nt S i z e будет содержать
размер шрифта, который м ы будем испол ьзовать во всех ячейках нашего таб­
личного представления; а favo r i t e s L i s t будет содержать указатель на сингл­
тон Favo r i t e s L i s t . Последние два свойства я вляются константами, которые
представля ют идентифи каторы я чеек, которые мы будем испол ьзовать для я чеек
табл ичного представления в этом контроллере.
Установите все свойства этого класса, добавив в метод viewDidLoad ( ) код,
представленн ы й в листин ге 9.2.
Листинг 9 . 2 . Метод viewDidМethod дл я файла RootVi ewCont r o l l e r . swi f t
ove r r i de f u n c v i e w D i dL o a d ( )
s up e r . v i e w D i d L o a d ( )
f ami l yName s
( U I Fo n t . fami l yName s ( ) a s [ S t r i ng ] ) . s o r t e d ( )
l e t p r e f e r r e dT a Ь l e V i e w Fo n t
U I Fo n t . p r e f e r r e d Fo n t ( f o r T ex t S t y l e : U I Fon t T e x t S t y l e H e a d l i n e )
c e l l Po i n t S i z e
p r e f e r r edTaЬ l e V i e w Fo n t . po i n t S i z e
f a v o r i t e s L i s t = Favo r i t e s L i s t . s ha r e d Fa vo r i t e s L i s t
ce l l Po i n t S i z e
t a Ы e V i e w . e s t im a t edRow H e i gh t
=
=
=
=
В л исти н ге 9 . 2 м ы запол н ил и масс и в f ami l yName s , запраш и вая у класса
U I Font все известные семейства шрифтов, а затем сортируя получившийся в
резул ьтате масс и в . После этого м ы обратил ись к классу U I Fo n t еще раз, за­
праш ивая п редпочтител ь н ы й шрифт для заголовка. Мы сделали это с помощью
фун кции, добавленной в систему iOS 7, которая испол ьзует размер шрифта, за­
давае м ы й пользователем в приложе н и и Settings. Это динами ческое изменение
размера шрифта позволяет пол ьзователю установить общий масштаб шрифта,
применяе м ы й во всей системе. Здесь м ы испол ьзовал и с войство p o i n t S i z e
для установки базового размера шрифта, который будет испол ьзоваться везде
в этом контроллере представления . Наконец мы получили синглтон с объектом
списка предпоч итаемых шрифтов и задал и свойство e s t imat edRowH e i ght таб­
лич ного представления, чтобы указать примерную высоту строк таблицы. Есл и
ГЛАВА 9 � КО НТРОЛЛ Е Р Ы НАВ И ГА Ц И И И ТАБ Л И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
361
свойство e s t ima t edRowHe ight задано, табл ица самостоятел ьно вычисл ит пра­
вил ьную высоту строк для каждой ячейки на основе ее содержания . Оставим
значен ие свойства e s t ima t edRowHe i ght рав н ы м его значению по умолчанию
U I TaЬ l eVi ewAutoma t i c D imen s i o n и будем испол ьзовать стандартные я чейки
таблич ного представления (есл и хотите настроить ячейки табл ичного представ­
ления по-своему, испол ьзуйте огран ичения Auto Layout).
Прежде чем двигаться далее, удал и м метод d i dRe ce iveMemo ryWa rni ng ( ) , а
также закомментированные методы делегата табл и чного п редставления и источ­
ника дан ных - м ы не соби раемся испол ьзовать их в этом классе.
Идея, лежащая в основе этого контроллера представлен ия, заключается в том,
чтобы показать два раздела. Первый раздел - список всех доступных семейств
шрифтов, каждое из которых приводит к с п ис ку всех шрифтов семейства. Вто­
рой раздел - для предпочитаемых шрифтов - содержит только одну запись,
которая ведет пользователя к списку предпочитаем ых и м шрифтов . Однако, если
у пол ьзователя нет предпоч итаемых шрифтов (например, когда приложение за­
пускается в первый раз), мы не показываем второй раздел вообще, так как будет
выведен пустой сп исок. Таким образом, м ы должны выпол н ить несколько дей­
ствий в остальной части класса, чтобы обработать этот случай. Первое из них за­
ключается в реализации метода, который вызывается непосредственно перед тем,
как представление корневого контроллера представления отображается на экране:
override func viewWi l lAppear ( animated : Boo l ) {
super . viewWillAppear ( animated)
taЬleView . reloadData ( )
Причина этого заключается в том, что могут быть ситуации, когда м ножество
вы водимых объектов меняется от одного просмотра к следующему. Напри мер,
пол ьзовател ь может начать работу без предпочитае м ы х шрифтов, но затем рас­
крыть детал ьную и нформацию, выбрать шрифт, добавить его в список п редпо­
читаемых, а потом вернуться к кор невому п редставлению. В этот момент нам
нужно повторно загрузить табл и чное п редставление, так как должен будет поя­
виться второй раздел .
Далее м ы реал изуем некоторый служебн ы й метод для использования в этом
классе. В паре точек при настрой ке табл и чного п редставления с помощью ме­
тодов источн и ка данн ы х мы должны быть в состоя н и и выяснить, какой шрифт
должеtI отображаться в ячейке. М ы помещаем эту фун кционал ьную возмож­
ность в отдел ьный метод, показанн ы й в листин ге 9.3 .
Листинг 9 . 3 . Выяснение , какой ш рифт мы хотим вывести на экран
func fo n t Fo r D i s p l a y ( a t l nde x Pa t h i nde x Pa t h : N S i nd e x Pa t h ) -> U I Fo n t ?
i f i n de x P a t h . s e c t i o n
О {
l e t fami l yName = fami l yName s [ i n de x Pa t h . r ow ]
l e t f o n t N ame = U I Fo n t . f o n t N ame s ( f o r Fami l yName : fami l yName ) . f i r s t
r e t u r n f o n tName ! n i l ?
= =
=
362
ГЛАВА 9 11 КОНТРОЛ Л Е Р Ы Н АВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
U I Fo n t ( n ame : f o n t N ame ! , s i z e : ce l l Po i n t S i z e ) : n i l
else {
return n i l
Этот метод испол ьзует класс U I Font, чтобы найти все и мена шрифтов дан­
ного семейства, а потом получить первы й шрифт семейства. Нам не обязательно
знать, что первы й из именован н ы х шрифтов семейства я вляется луч ш и м для
представления всего семейства, но это предположение не хуже любого другого.
Если в семействе нет имен шрифтов, возвращается значение n i l .
Теперь перейдем к основному коду контроллера представления, а именно к методам источн и ка данных. Для начала определим кол ичество разделов:
ove r r i d e f u n c n umbe r O f S e c t i o n s ( i n t aЬ l eV i e w : U I T a Ь l e V i e w )
r e t u r n favo r i t e s L i s t . f a vo r i t e s . i s Emp t y ? 1 : 2
-
> Int {
М ы испол ьзуем список п редпоч итаемых шрифтов, чтобы определ ить, нуж­
но л и показы вать второй раздел . Далее определяем кол и чество строк в каждом
разделе:
ove r r i de f u n c t a Ь l e V i e w ( t a Ы e V i e w : U I T a Ь l e V i e w ,
n umbe rO fRow s i n S e c t i o n s e c t i o n : I n t ) - > I n t {
1 1 В о з в р а ща е т коли ч е с т в о с т р о к в р а зделе .
r e t u r n s e c t i on = = О ? fami l yName s . c o u n t : 1
Эта реализация тоже очен ь проста. М ы просто испол ьзуем номер раздела для
выяснения, показывает л и этот раздел все и мена семейств шрифтов ил и тол ько
одну ячейку, связанную со списком предпочитаемых шрифтов. Теперь определим
еще один метод - необязатель н ы й метод протокола U I T aЬl eVi ewDa t a S ource,
которы й позволит нам указать наз вание для каждого из разделов:
ove r r i de f u n c t a Ь l e V i ew ( t a Ь l eV i e w : U I T a Ь l e V i e w ,
_
t i t l e Fo r H e a de r i n S e c t i o n s e c t i o n : I n t ) - > S t r i n g ?
r e t u r n s e c t i on
О ? "Al l F o n t Fami l i e s " : " М у Favo r i t e Font s "
==
Это еще оди н п ростой метод, испол ьзующи й номер раздела, чтобы опреде­
л ить его заголовок. Последним фундаментал ь н ы м методом, который должен ре­
ал изовать кажд ы й источн и к дан н ы х табли ч ного представления, я вляется метод
для настройки каждой ячейки, приведе н н ы й в листи н ге 9.4.
Л истинг 9 . 4 . Функция ce l l ForRow ( at i ndexPath : )
ove r r i de f u n c t a Ы e V i ew ( t a Ь l e V i e w : U I T a Ь l e V i ew ,
c e l l Fo r RowAt i ndex P a t h : I nde x Pa t h ) - > U I T a Ь l eVi ewCe l l
i f i nd e x P a t h . s e c t i o n = = О
1 1 С п и с о к име н шри ф т о в
ГЛАВА 9 � КОНТРОЛЛ Е Р Ы Н АВ И ГА Ц И И И ТАБЛИ Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
363
let cell
t a Ы e V i e w . d e qu e u e Re u s a Ь l e C e l l ( w i t h i de n t i f i e r :
Roo tVi ewCont r o l l e r .
f am i l yCe l l , f o r : i n de x Pa t h )
ce l l . t e x t Lab e l ? . f o n t = f o n t Fo r D i s p l a y ( a t i nde x Pa t h : i nd e x P a t h )
ce l l . t e x t La b e l ? . t e x t
fami l yName s [ i ndex P a t h . r ow ]
ce l l . d e t a i l T e x t La be l ? . t e x t
fami l yName s [ i ndex P a t h . r ow ]
r e t u r n ce l l
else {
1 1 Список предпочита емых шри ф т о в
r e t u r n t a Ы e V i e w . deque u e Re u s a Ь l e C e l l ( w i t h i de n t i f i e r :
Roo tVi ewCo n t r o l l e r .
favo r i t e s C e l l , f o r : i n dex P a t h )
=
=
=
Создавая этот класс, м ы определ или два разл и ч н ы х идентификатора я чеек,
которые испол ьзуем для загрузки двух прототипов ячеек из раскадровки (так же,
как мы загружал и ячейку табл и цы из niЬ-файла в главе 8). Мы еще не настра­
и вали эти прототи п ы ячеек, но скоро эти м зай мемся . Далее испол ьзуем номер
раздела, чтобы определ ить, какие из этих я чеек хотим показать для текущего
index Path. Есл и я чейка должна содержать и м я семейства шрифтов, помеща­
ем имя семейства в свойства T e x t Labe l и d e t a i l T e x t Labe l . М ы также ис­
пол ьзуем в текстовой метке один из шрифтов семейства (тот, который получаем
с помощью метода font Fo r D i s p l a y ( a t i ndex Pa t h : ), так что имя семейства
шрифтов вы водится как шрифтом этого семейства, так и (его умен ьшен н ы й ва­
риант) стандартны м систем н ы м шрифтом.
Начальная настройка раскадровки
Теперь, когда у нас есть контроллер представления ( который, как м ы думаем,
должен что-то показы вать), настрои м раскадровку, чтобы заставить его рабо­
тать. Выберите файл Ma i n . s t o rybo a r d в окне нави гатора п роекта. В ы уви­
дите контроллер нави гаци и и контроллер табл и ч ного п редставления, которые
добавил и ранее. Первое, что нужно настроить, - это контроллер табличного
представления . Класс контроллера по умолчанию - U I TaЬleVi ewCont r o l l e r .
М ы должны замен ить его классом корневого контроллера представления. В окне
Docu ment Outl ine выберите желтую п и ктограм му с надписью Root View Control­
ler, а затем используйте инспектор идентичности для изменения параметра Class
контроллера представления на Roo tVi ewCont r o l l e r .
Еще одно изменение кон ф и гураци и, которое необходимо в нести прямо
сейчас, - это создание пары я чеек-прототипов для сопоставления с иденти­
фи каторам и я чеек, которые мы испол ьзовал и в нашем коде. Изначал ьно таб­
личное представление имеет еди нствен ную ячейку-прототип . В ы берите ее и
нажм ите комби нацию клавиш < X +D>, чтобы создать дубл и кат; вы увидите,
что теперь у вас есть две ячейки . В ы берите первую, а затем воспол ьзуйтесь
инспектором атрибутов, чтобы задать для нее атрибут Style рав н ы м S uЬt i t l e ;
ldentifier - Fami l yName ; Accessory - D i s c l o s u r e I nd i c a t o r . Далее выбе­
рите вторую ячейку-прототи п и задайте для нее атрибут Style равн ы м Ba s i c;
364
ГЛАВА 9 &.Ч КОНТРОЛЛ Е Р Ы Н АВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
Favo r i t e s ; Accessory
D i s c l o s u r e I nd i c a t o r . Дважды щел­
кн ите на заголовке, отображаемом в ячейке, и замен ите слово T i t l e словом
Favor i t e s .
l d eпtifier
-
-
ПОДСКАЗКА. Обе ячейки -п рототип ы , которые м ы используем в дан ном п римере , имеют
стиль ячеек стандартного табличного представления . Если вы установите Style р ав­
ным Cu s t om, то с можете с проектировать схему ячейки прям о в ячейке- п рототипе, так
же, как вы создавали ячейку в niЬ-файле в главе 8 .
Теперь постройте и запустите это п р иложе н и е на вашем устройстве ил и
симул яторе, и увидите крас и в ы й с п исок шрифтов . Прокрутите его нем ного,
и увидите, что не все шрифты дают текст одной и той же высоты (рис. 9.8).
Тем не менее все ячейки и м еют достаточную в ысоту, чтобы вмещать их со­
держание, даже нес мотря на то, что для этого м ы ничего специал ьно не дела­
л и . Есл и в ы забыл и, почему это происходит, верн итесь к обсуждению метода
viewDidLoad ( ) .
Первый подконтроллер : п редставление сп иска шрифтов
В настоя щее в ремя наше приложение отображает тол ько сп исок семейств
шрифтов. М ы хотим добав ить для пол ьзователя возможность прикоснуться к
семейству шрифтов и увидеть все шрифты, которые он содержит, так что давай­
те сделаем новый контроллер представления, который может управлять списком
шрифтов. Воспол ьзуемся новым файловы м помощн иком в среде Xcode для со­
здания нового класса Сосоа Touch под наз ванием Font L i s tViewCon t ro l l e r,
я вляющегося подклассом U I TaЬ l eVi ewCont ro l l e r . Выберите файл FontLi s t
Vi ewCon t ro l l e r . s w i f t в окне навигатора проекта и добавьте в него следую­
щие свойства:
c l a s s Fo n t L i s t V i e w C o n t r o l l e r : U I T aЬ l e V i e w C o n t r o l l e r
var fontNames : [ S tring ] = [ ]
var showsFavori te s : Bool
fal se
private var cellPointSi ze : CGFloat !
private s tatic let cel l i denti fier = " FontName "
=
С войство fontName s п редставляет собой именно то с войство, которое м ы
будем испол ьзовать для у казан и я контроллеру представления, что требуется
вы водить. Мы также создал и свойство s h o w s Favo r i t e s , которое будем ис­
пол ьзовать для того, чтобы дать знать контроллеру п редставления, показы вает
л и он список предп оч итаемых шрифтов ил и просто сп исок шрифтов в семей­
стве, поскольку это окажется полезным в дал ьнейшем. Мы будем испол ьзовать
свойство ce l l Po i nt S i z e для хранения предпочтител ьного размера для выво­
да каждого шрифта; этот размер м ы получаем с помощью U I Fo n t . Наконец
c e l l i d e nt i f i e r
это идентифи катор, испол ьзуе м ы й для я чеек табл и ч ного
представления данного контроллера.
-
ГЛАВА 9 "' КОНТРОЛ Л Е Р Ы Н А В И ГА Ц И И И ТАБЛ И Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
C1rrier •
;Рhом 13� ·- iOS 10.0 114Ab29.lc}
10:22 АМ
Fonts
365
-
All Font Families
Лc•<lem1· Engra• е<1 LET
Academy Enor•ved LET
AI Nile
AI Nile
AluriOlll 'l'yptwriter
Amerlcan Т'ypewrlter
App l e
Color
Applo Color Emojl
Emo j i
Ai>r>� SO Gc.:h1c Neo
Applo SD Goth<e Neo
Arlal
Arlal Нebrew
Arlal Hebrew
Arlal Rounded МТ Bold
Arlal Raundecl МТ Bold
Avenir
Avenir
Aveni r N ext
Avenlr Ne•t
Awnlr hirt CollClнмd
Avtnir Ntxt Condensed
Bangla Sangam MN
Bangla Sangam MN
Рис . 9 . 8 . Контрол л е р корневого п редстав ­
л е н и я в ы водит и н сталл и рован н ы е с е м е й ­
ства ш р и фтов
Дnя и н и циал изации свойства c e l l Po i n t S i z e добавьте в метод v i e w D i d
Load ( ) код, представлен н ы й в л исти н ге 9 . 5 .
Листинг 9 . 5 . Метод viewDidМethod для файла RootVi ewCont r o l l e r . swi ft
ove r r i d e f u n c v i e w D i dLoad ( )
s u pe r . v i e w D i dLoad ( )
l e t p r e f e r r e d T aЬ l e V i e w F o n t
U I Font . p r e f e r r e d F o n t ( f o r T e x t S t y l e : U I F o n t T e x t S t y l e He a d l i n e )
ce l l P o i n t S i z e
p r e f e r r e d T a Ь l e V i e w Fo n t . p o i n t S i z e
t a ? l e V i e w . e s t ima t e dRowH e i g h t
ce l l P ointS i z e
=
=
Следующее, что нам надо сделать, - это создать небол ьшой вспомогатель­
ный метод для выбора шрифта для показа в каждой строке, похожий н а тот,
который испол ьзуется у нас в классе Ro otVi ewCont ro l l e r . Однако здесь код
нем ного отл ичается . В место сп иска семейств шрифтов в этом контроллере пред­
ставления мы хран и м список н азван и й шрифтов и будем испол ьзовать класс
U I Font для получения каждого имени шрифта следующи м образом :
366
ГЛАВА 9 1'1 КОНТРОЛЛ Е Р Ы НАВ И ГАЦИ И И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
f u n c f o n t Fo r D i s p l a y ( a t i nde x P a t h i nde x P a t h : NS i nde x P a t h ) - > U I Font {
l e t f o n tName
f o n tName s [ i ndex P a t h . r ow ]
r e t u r n U I F o n t ( n ame : f o n t N ame , s i z e : ce l l P o i n t S i z e ) !
=
Теперь создадим небол ьшое допол нение в в иде реал изации метода vi ewWi l l
Appe a r ( ) . Вспомните, как в классе Roo tVi ewCon t ro l l e r м ы реал изовал и этот
'
метод для случая, когда сп исок п редпочитаемых шрифтов может изменя ться,
требуя обновления. То же самое применимо и здесь. Этот контроллер пред­
ставления может показывать сп исок п редпоч итаемых шрифтов, и пол ьзовател ь
может перекл юч иться на другой контроллер п редставления, изменить предпо­
ч итаемые шрифты (об этом - позже), а затем вернуться обратно. В таком слу­
чае нам нужно повторно загрузить табличное представление. И менно для этого
предназначен метод, приведенный в листин ге 9.6.
Листинr 9 . 6 . Обновление представления в случае изменений
ove r r i d e func v i e wW i l lAp p e a r ( _ a n i ma t e d : Bo o l ) {
s up e r . v i e wW i l lApp e a r ( a n i ma t e d )
i f s ho w s Favo r i t e s {
f o n t Name s = Favo r i t e s L i s t . s h a r e d Favo r i t e s L i s t . f a vo r i t e s
t a Ы e V i ew . r e l o adDa t a ( )
Основная идея закл ючается в том, что этому контроллеру представления в
нормальном режиме передается с писок названий шрифтов перед тем, как он бу­
дет выведен на экран, и этот список остается неизменным на все время вы вода
контроллера. В одном частном случае (которы й вы увидите позже) этот контрол­
лер представления должен перезагрузить свой список шрифтов.
Продолжая работу, м ы можем полностью удал ить метод numЬe rOf S ec t ion­
s i nTaЬ l eView ( ) . Здесь у нас будет только оди н раздел, так что его удаление эк­
вивалентно его реал изации, которая всегда возвращает единицу. Далее реализуем
два других метода главного источн и ка данных (листинг 9.7).
Листи н г 9 . 7 . Методы источника данных
ove r r i de func t a Ь l e V i ew ( t a Ь l e V i e w : U I T a Ь l e V i e w ,
n umb e r O f R ow s i n S e c t i on s e c t i o n : I n t ) - > I n t {
/ / В о з в р аща е т колич е с т в о стро к в р а зделе .
r e t u r n f o n t Name s . c o u n t
ove r r i de f u n c t a Ь l e V i ew ( _ t a Ь l e V i ew : U I T a Ь l e V i e w ,
c e l l F o r RowAt i n d e x P a t h : I nd e x P a t h ) - > U I T a Ь l e V i e wC e l l
l e t c e l l = t a Ы e V i e w . deque u e Re u s a Ь l e C e l l (
w i t h i de n t i f i e r : Font L i s t V i ewCon t r o l l e r . c e l l i d e n t i f i e r ,
f o r : i ndex P a t h )
ГЛАВА 9 !llr! КО НТРОЛЛ Е Р Ы НАВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
367
c e l l . t e x t L ab e l ? . f o n t
f o n t F o r D i s p l a y ( a t i nd e x P a t h : i nd e x P a t h )
ce l l . t e x t Lab e l ? . t e x t = f o n t Name s [ i nd e x P a t h . r ow ]
c e l l . d e t a i l T e x t La be l ? . t e x t = f o n tName s [ i n de x P a t h . r ow ]
=
r e t u r n ce l l
Ни один из этих методов н е нуждается в каких-л ибо объяснениях, потому что
они очень похожи на методы, которые м ы испол ьзовал и в RootViewControl l e r,
и даже проще них.
М ы допол н и м этот класс позже, но сначала хотим увидеть его в действи и .
Дл я этого следует настроить раскадровку, а затем внести некоторые изменения
в RootVi ewCon t ro l l e r . Перейдем для начала к файлу Ma i n . s t o ryboa rd.
Раскадровка списка шрифтов
Раскадровка в настоя щее время содержит контроллер табл ичного представ­
ления, которы й отображает с п исок семейств шрифтов, встроен н ы й в контрол­
лер навигаци и . Нам нужно добавить оди н новый слой глуби н ы для включения
контроллера представления, которы й будет отображать шрифты для дан ного
семейства. Найдите элемент ТаЫе View Controller в библиотеке объектов и пе­
ретащите его в область редактирован ия, справа от существующего контроллера
табл ич ного представлен ия . В ыберите нов ы й контроллер табл ич ного представ­
ления и с помощью и нспектора идентичности установите в качестве его класса
FontLi s tVi ewCon t ro l l e r. Выберите ячейку-прототип в табл и ч ном представ­
лении и откройте окно и нспектора атрибутов для внесения некоторых исправле­
ний. Измените атрибут Style на SuЬt i t l e, l d entifier
на FontName, а Access o­
ry
на De t a i l D i s c l o s u r e . Испол ьзован ие раскрытия детал изации позвол ит
строкам этого ти па отвечать на два вида нажати й, так что пол ьзователи смогут
активизировать два разных действия в зависимости от того, нажимают л и они
аксессуар ил и л юбую иную часть строки.
Одни м из способов добиться того, чтобы одно действие пользователя в од­
ном контроллере п редставления при водило к созданию экзем пляра и отобра­
жению другого контроллера представления, я вляется создание перехода (segue)
между н и м и . Вероятно, это слово не знакомо большинству из вас, так что по­
ясн и м : segue, по сути, означает "переход" и и ногда испол ьзуется писателями
и кинематографистами для оп исани я плавного перехода от одного абзаца (или
сцены � к следующему. Ком пания Apple могла бы быть попроще и наз вать его
просто переходом , но, возможно, из-за того, что это слово уже появляется в
интерфейсах API U I K it, разработч ики реш ил и испол ьзовать отдел ьный термин,
чтобы избежать путаницы. Следует также заметить, что слово "segue" произно­
сится точ но так же, как название S e gw ay для самоката (зато теперь вы знаете,
почему он носит такое название).
Часто такие переходы создаются искл юч ител ьно в пределах п рограм м ы
Interface Bui lder. Идея закл ючается в том, что действие в одной и з сцен может
-
-
368
ГЛАВА 9 �,; КОНТРОЛ Л Е Р Ы Н А В И ГА Ц И И И ТАБ Л И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
вызвать переход к загрузке и отображению другой сцен ы . Есл и вы используете
контроллер навигации, такой переход может внести следующи й контроллер в
стек навигации автоматически. М ы будем испол ьзовать эту фун кциональность
в нашем приложении и начнем прямо сейчас .
Дn я того чтобы ячейки контроллера корневого представления вы водили кон­
троллер представления с писка шрифтов, необходимо создать пару пер�ходов,
соединяющих две сцены. Это делается путем проведения соединител ьной линии
от первой из двух ячеек-прототипов в сцене Fonts к новой сцене; вы увидите,
что вся сцена подсвечи вается , когда указател ь проходит над ней, а это указы вает
на то, что она готова к под кл ючен и ю (рис. 9.9).
·
-
<
> :-
t'f*'\llwo.11
rJ о о
- --
8
•
--
_1
1
.....
� "f
ci Ф • о 11 е
'
__,,
оо..:--. �
,_ ..,..
OlfWI
· - � blltir!e
•
8
•
•
u ;
...... "". ем..°"
....,._ °"_ ...._
•
,_
1
i � Noft ktitt ft 'JI
_ _"
,"
8
8
о :
_..._. . Utl8f ....... ......
....,. ,_
,,
- === •
в
TaЬl&Viow
· ·-
.....
f..М. VW CМ\t
• ,\
_...... _ _....., , _ _
D Y'м - 1Ptian8 et 1... c 1t1
li1
•
li
'•
•
; о � "
-
-
Рис . 9 . 9 . Созда н и е п е рехода и з ко нтролл ера с п и ска ш р и фтов к контроллеру
и м е н ш р и фтов
Отпустите кно п ку м ы ш и и выберите пункт show в разделе Selection Segue
всплы вающего меню. Потом сделайте то же самое для других ячеек-прототипов.
Создание этих переходов означает, что, как тол ько пол ьзователь коснется какой­
либо из этих клеток, будет в ыделен и подготовлен контроллер представления на
другом кон це соединени я .
подготовка контроллера корневого представления к переходам
С охран ите внесе н н ые изменения и верн итесь к R o o t V i e w C o n t r o l l e r .
swi f t . Обратите вни мание, что м ы говорим не о нашем последнем классе, Font
L i s tV i ewCon t r o l l e r, а о его "родител ьском" контроллере. Это место, где
ГЛАВА 9 �§ КОНТРОЛЛ Е Р Ы НАВ И ГА Ц И И И ТАБЛИ Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
369
вы должны реагировать на прикосновения пол ьзователя в корневом табл и чном
представлении путем подготовки нового класса FontL i s tVi ewCon t ro l l e r (оп­
ределенного одн и м из тол ько что созданных переходов) для отображения и пе­
редач и ему значен ий, которые требуется в ывести.
Реал ьная подготов ка нового контроллера п редставления в ы полняется с ис­
пользованием метода p r e p a r e Fo r S e g u e { : s e nde r : ) . Добавьте реал изаци ю
этого метода, приведенную в листи н ге 9 . 8 .
Листинг 9 . 8 . Подготовка нового контролера представления к выводу на экран
1 1 MARK : - Navi g a t i o n
ove r r i de f u n c p r e p a r e ( f o r s e g u e : U I S t o r yb o a r d S e g u e , s e nde r : AnyOb j e c t ? ) {
1 1 Получ а е т новый к о н т р оллер предс т а вл е ни я , и с п ол ь зуя
11 [ s e g u e de s t i n a t i o n V i e w C o n t r o l l e r ] .
1 1 Переда е т выбр анный объе кт н о в ому контроллеру п р е д с т а в л е ни я .
l e t i ndex P a t h
t a Ы e V i e w . i nde x P a t h ( f o r : s e nde r a s ! U I T a Ь l eV i ewCe l l ) !
l e t l i s tVC
s e gue . de s t i n a t i o n V i ewCo n t r o l l e r a s ! Fon t L i s t V i e w C o n t r o l l e r
=
=
i f i nd e x Pa t h . s e c t i o n
О {
1 1 Список имен шри ф т о в
l e t f ami l yName
f ami l yName s [ i ndex P a t h . r ow ]
l i s t VC . f o n t Name s
( U I Fo n t . f o n t Name s ( f o r Fami l yName : fami l yName )
a s [ S t r i ng ] ) . s o r t e d ( )
l i s t VC . n a v i ga t i on l t em . t i t l e
f ami l yName
l i s t VC . s h o w s Favo r i t e s
false
else {
1 1 С п и с о к предпочти т е л ь ных шриф т о в
l i s t VC . f o n t N ame s = favo r i t e s L i s t . f a vo r i t e s
l i s t VC . navi g a t i o n l t em . t i t l e
" Favor i t e s "
l i s tVC . s h o w s Favo r i t e s
true
= =
=
=
=
=
=
=
Этот метод испол ьзует параметр s e nder ( п роизошло прикосновение к объек­
ту класса U I T aЬleVi ewCe l l) для определения, какой строки коснулся пол ьзо­
вател ь, и запраш и вает переход к объекту de s t i na t i onVi ewCont ro l l e r, пред­
ставля ющему собой экземпляр класса F o n t L i s tV i ewC on t r o l l e r, который
будет вы водиться . Затем м ы передаем некоторые значения новому контролле­
ру представления, в зависимости от того, что нажал пол ьзовател ь : семейство
шрифтов (раздел О) ил и ячейку предпочитаемых шрифтов (раздел 1 ). Так же,
как и при установке пол ьзовательских свойств целевого контроллера представ­
ления, мы обращаемся к свойству navi gat i on i tem контроллера для того, что­
бы задать заголовок. С войство navi g a t i o n i t em представляет собой экземпляр
U I Navi g a t i o n i tem, которы й я вляется классом каркаса U I Kit, содержащим све­
дения о том, что будет вы водиться на панел и навигации для л юбого заданного
контроллера представления.
Теперь запустите приложение. В ы увидите, что после нажатия на имя л юбого
шрифта семейства отобразится с писок всех отдел ьных шрифтов, которые оно
содержит (рис. 9. 1 О). Кроме того, вы можете нажать на метку Fonts в заголовке
370
ГЛАВА 9 tii КОНТРОЛ Л Е Р Ы НАВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
списка шрифтов контроллера навигаци и списка шрифтов, чтобы вернуться к ро­
дительскому контроллеру и выбрать другой шрифт.
( Fonts
Cetrletr •
11:64 АМ
American Typewriter
Amer1ca.nТypewr1ter
AmerlcanTypewriter
Amerioan'rypewriter·Вold
Am&ticanTypewriter-8oki
AmerlcanTypewr!tel'Condensed
Amtric:anTypewriter�Condensed
Alatr\C811fn!llWrlier-CoJU11111dlo
1 ld
AmericanTypewriter-Condensed8old
AmeMcan'Гypewi·11.вr-CondenвedlJgh1
AmerlcanTypewriter-Condensedllght
A111t.Jrlc:an1'ypвw1·itc1 ··Ligl 1t
AmerКanTypewriter-Llght
Amer1oanТypewr1ter-Sem1bold
AmerlcanТypewriter-SemlЬold
-
CD
CD
CD
CD
CD
CD
CD
Рис. 9 . 1 О. Де м о н страция отдел ьных ш р и ф ­
тов , соде ржа щихся в с е м е й стве ш р и фтов
С озда н и е контролл е ра п р е дставл е н и я
разм е ров ш рифтов
Однако вы должны заметить, что в настоя щее время приложение не поз­
вол яет вам идти дал ьше. На рис. 9.4 и 9 . 5 показаны допол н ительные экран ы,
которые позволяют просматри вать выбран н ы й шрифт разл и ч н ы м и способами
и которые пока что отсутствуют. Но это ненадол го ! Создадим показан ное на
рис. 9.4 представлен ие, которое показы вает сразу нескол ько размеров шрифта.
Испол ьзуя те же шаги, что и при создании класса Font L i s tViewCon t ro l l er,
добав ьте новый контроллер представления, я вля ющийся подклассом класса
U I T a Ь l eVi ewCon t ro l l e r, и н азовите его Font S i z e sVi ewCont r o l l e r. Един­
ствен н ы м параметром, которы й этот класс будет получать от родител ьского
контроллера, я вляется шрифт. Кроме того, нам понадобится пара закрытых
свойств.
ГЛАВА 9 m КОНТРОЛ Л Е Р Ы НАВ И ГАЦ И И И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
371
Для начала nерейдите к файлу Font S i z e sViewCont r o l l e r . swi ft и удали­
те методы d i dRe ce iveMemo ryWa r n i n g и numЬerO f S e c t i on s i nT a Ь l eVi ew, а
также все заком ментирован ные методы в н ижней части - они нам не нужн ы .
Затем добавьте следующие свойства в верхней части оnределения класса:
imp o r t U I K i t
c l a s s Fon t S i z e s V i e wC o n t r o l l e r : U I T a Ь l e V i e w C o n t r o l l e r
v a r f o n t : U I Font !
p r i v a t e s t a t i c l e t p o i n t S i z e s : [ CG F l o a t ] = [
9, 10, 1 1 , 12 , 13, 1 4 , 18, 2 4 , 36, 4 8, 64 , 72, 96, 144
p r i va t e s t a t i c l e t ce l l l de n t i f i e r = " F o n t NameAn d S i z e "
С войство f o n t будет устанавл и ваться объектом класса F o n t L i s t V i e w
Contro l l e r nеред тем, как он затолкнет этот контроллер n редставления в стек
контроллеров навигации . С войство p o i n t S i z e s n редставляет собой массив раз­
меров, с которы м и будет отображаться шрифт. Н ам также нужен следующий
вс nомогател ьный метод, который nолучает версию шрифта с заданн ы м разме­
ром на основе и ндекса строки табл и цы :
f u n c f o n t Fo r D i s p l a y ( a t i n de x P a t h i ndex P a t h : NS i nd e x P a t h ) > U I F o n t {
l e t p o i n t S i z e = F o n t S i z e s V i ewCo n t r o l l e r . p o i n t S i z e s [ i n d e x P a t h . r ow ]
r e t u r n f o n t . w i t h S i z e ( po i n t S i z e )
-
М ы также должны задать свойство табл и ч ного n редставления e s t ima t ed
RowH i gh t , чтобы табл ица могла автоматически корре ктировать высоту каж­
дой строки в зависимости от ее содержан ия . Для этого добавим в метод view
D i dLoad ( ) следующий код.
taЬleView . e s timatedRowHeiqht = FontSi zesViewController . pointS i z e s [ O ]
Значен ие, которое nрисваи вается этому свойству, н а самом деле н е и грает
н икакой рол и, м ы n роизвол ьн ы м образом в ыбрал и сам ы й маленький размер
шрифта, которы й может отображаться в табл и це.
Для этого контроллера n редставления м ы соби раемся и гнорировать метод,
который nозволяет нам оnредел ить коли чество в ыводим ы х разделов, nоскол ьку
собираемся исnол ьзовать только их число no умол чанию ( 1 ). Однако м ы должн ы
реализовать методы для указан ия ч исла строк и содержимого каждой ячейки.
Эти два метода nри ведены в листин ге 9.9.
'
Л истинг 9 . 9 . Методы источн ика дан н ых для табличного
представления Font S i z eVi ewCont r o l l e r
/ / MARK : - Т а Ы е v i e w d a t a s o u r ce
ove r r i d e f u n c t a Ы e V i e w ( _ t a Ь l e V i e w : U I T a Ь l e V i e w ,
n umb e r O f Row s i n S e ct i on s e c t i o n : I n t ) - > I n t {
r e t u r n Font S i z e s V i ewCo n t r o l l e r . p o i n t S i z e s . c o u n t
372
ГЛАВА 9 !<i КОНТРОЛЛЕРЫ НАВ И ГАЦИ И И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
ove r r i de f u n c t a Ы e V i ew ( _ t a Ь l e V i e w : U I T aЬ l e V i e w ,
c e l l For RowAt i ndex P a t h : I ndex P a t h ) - > U I T aЬ l eVi ewCe l l
l e t ce l l
t a Ь l e V i e w . d e q u e u e Re u s a Ь l e C e l l (
w i t h i de n t i f i e r : F o n t S i z e s V i ewCon t r o l l e r . ce l l i de n t i f i e r ,
f o r : i ndex P a t h )
=
ce l l . t e x t Lab e l ? . f o n t = f o n t Fo r D i s p l a y ( a t i n de x P a t h : i ndex P a t h )
c e l l . t e x t Lab e l ? . t e x t
f o n t . f o n t Name
c e l l . deta i l Text Labe l ? . text
" \ ( F o n t S i z e s V i ew C o n t r o l l e r . p o i n t S i z e s [ i n dex P a t h . r ow ] ) p o i n t "
return cell
=
=
В каждом и з этих методов нет н ичего того, чего м ы н е видел и ран ьше, так
что сразу перейдем к создани ю графического и нтерфейса пол ьзователя.
Создание раскадровки контроллера
представления ра з мер о в шрифтов
Верн итесь к файлу Ma i n . s t o ryboa r d и перетащите еще оди н контроллер
табл ичного представления в область редактирован и я . Воспол ьзуйтесь и нспек­
тором идентичности, чтобы установить его класс Font S i z e sVi ewCont r o l l e r .
В а м нужно создат ь п од кл юч е н и е п е рехода о т родител ьско го узла
Fon t L i s tVi ewCon t r o l l e r . Так что найдите контроллер, нажм ите клавишу
<Control> и перетащите у казател ь от его ячейки-прототипа в новей ший конт­
роллер представления, а затем выберите пункт show в разделе Selection Segue
вспл ы вающего меню. Далее выберите ячейку-прототи п в тол ько что добавлен­
ной новой сцене и испол ьзуйте и нспектор атрибутов, чтобы установить для ат­
рибута Style значение SuЬt i t l e, а для ldentifier - FontNameAndS i z e.
Подготовка контроллера п редставления
списка шрифтов к переходам
Теперь, так же, как и в п рошл ы й раз, когда м ы рас ш и рял и иерархию на­
в и гации раскадровки, перейдем к родител ьскому контроллеру, чтобы он мог
настроить свой дочер н и й контроллер. Это означает, что мы должны перей­
ти к файлу Font L i s tViewCont r o l l e r . s w i f t и реал изовать метод prepare
ForSegue ( : sende r : ) так, как показано в л истин ге 9 . 1 О .
Л истинг 9 . 1 О . Метод preparedFo r S e gue для табличного
представления Font S i zeVi ewCont rol l e r
1 1 MARK : - Navi g a t i o n
ove r r i d e f u n c p r e p a r e ( f o r s e g u e : U I S t o r y b o a r d S e g u e , s e n de r : AnyOb j e c t ? ) {
1 1 П олуч а е т н о в ый к о н т р оллер п р е дс т а вл е ни я , и с п о л ь зуя
1 1 [ s e g u e de s t i n a t i o n V i e wC o n t r o l l e r ] .
1 1 П е р е да е т выбра нный объе кт н о в ому к о н троллеру предс т а вл е н и я .
l e t t a Ь l e V i ew C e l l
s e nde r a s ! U I T a Ь l e V i e w C e l l
l e t i n dex P a t h = t a Ь l e V i e w . i ndex P a t h ( f o r : t a Ы e V i e w C e l l ) !
l e t font
fo n t Fo r D i s p l a y ( a t i n d e x P a t h : i n d e x P a t h )
=
=
ГЛАВА 9 "' КОНТРОЛ Л Е Р Ы НАВ И ГА Ц И И И ТАБ Л И Ч Н Ы Е П Р ЕДСТА В Л Е Н И Я
373
l e t s i ze sVC
s e g u e . de s t i n a t i o nV i e w C o n t r o l l e r a s !
Fon t S i z e s V i ewCo n t r o l l e r
s i z e s VC . t i t l e
f o n t . f o n t N ame
s i z e s VC . f o n t
font
=
=
=
Вероятно, все в ы глядит довольно знакомо для вас, поэтому не будем оста­
навл и ваться на этом коде.
Запустите приложен ие, выберите семейство шрифтов, шрифт (путем нажатия
строки в любом месте, кроме ее правой части), и вы увидите список с раз н ы м и
размерам и шрифтов, показан н ы й на р и с . 9 . 1 1 .
Cauler •
( Васk
12:82 РМ
AcademyEngravedLetPlaln
-
\).0 poinl
10.О po1nt
11.0 po!nt
N111k11111::!1A1"11• �1..·1Plfiu1
12.О point
,\\·м1k·111•J,;,i.яra1t·1ILc:1!'1<1i11
13.О point
Л1"Jt•1щf.щ�raн."tl1c1Plain
14.0 point
,\cadeш)Engra\t'<IJ,.,1Pl&111
18 О poinl
Acade111yEng1·a,,cdLctPlain
24.0 poinl
AcadlemyEnga'aved!L . . .
36.О potnt
Academy Engr . . .
48.О polnt
Рис . 9 . 1 1 . С п и с о к табл и ч н о го п р едставл е ­
н и я с п е ре м е н н ы м и раз м е р а м и ш р ифтов
Создание контроллера представления и нформации о шрифте
Последн и й контроллер представления, которы й мы создадим, показан на
рис. 9 . 5 . Этот контроллер не основан на табл и ч ном представлен и и . В место это­
го он оснащен бол ьшой текстовой меткой, ползун ком дл я настройки размера
текста и перекл ючателем для вкл ючения этого шрифта в сп исок предпоч итае­
мых шрифтов . Создайте в вашем проекте новы й кл асс Сосоа Touch, испол ьзуя
U IViewCont ro l l e r как суперкласс, и назовите его Font i n foVi ewCon t ro l l e r.
Как и больши нство других контроллеров в этом приложении, данный контроллер
должен иметь пару параметров, передаваемых ему родител ьски м контроллером .
374
ГЛАВА 9 ()! КОНТРОЛ Л Е Р Ы НАВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
Эт а проблема решается путем определения в файле Font i n foViewControl ler .
swi ft свойств и четырех выходов, которые м ы будем испол ьзовать при постро­
ении пол ьзовательского и нтерфейса:
c l a s s Fo n t i n f o V i e w C o n t ro l l e r : U I V i ew C o n t ro l l e r
var font : UI Font !
var favori te : Bool
fal se
@ IBOutlet weak var fontSampleLaЬel : UILaЬel !
@ IBOUtlet weak var fontS i zeSlider : UISl ider !
@ IBOUtlet weak var fontS i zeLaЬel : UI LaЬel !
@ IBOUtlet weak var favorite Swi tch : UI Swi tch !
=
Затем реал изуйте viewDi dLoad ( ) и пару методов действи й , которые будут
запускаться соответственно ползу н ком и перекл ючателем (листинг 9. 1 1 ).
Л истинг 9 . 1 1 . Методы viewDidLoad ( ) , ползунка и переключателей
ove r r i de func v i e w D i dLoad ( )
s up e r . v i e w D i dLoad ( )
1 1 Дополнител ь н а я н а с тройка п о сл е за гру з ки предс т а в л е ни я .
f o n t S amp l e L a be l . f o n t = f o n t
f o n t S amp l e L a b e l . t e x t =
"AaBb C c DdE e F fGgHh i i J j K k L l МmN nOo PpQqR r S s T tUuVv"
+ " WwXx Y y Z z 0 1 2 3 4 5 6 7 8 9 "
f o n t S i z e S l i de r . va l u e = F l o a t ( f o n t . p o i n t S i z e )
f o n t S i z e La b e l . t e x t = " \ ( I n t ( fo n t . p o i n t S i z e ) ) "
f a vo r i t e S w i t c h . i s On = f a vo r i t e
@ I BAct i o n f u n c s l i d e Font S i z e ( s l i de r : U I S l i de r ) {
l e t n e w S i z e = r o u n d f ( s l i de r . va l u e )
f o n t S amp l e L a b e l . f o n t = f o n t . w i t h S i z e ( CG F l o a t ( n e w S i z e ) )
f o n t S i z e La b e l . t e x t = " \ ( I n t ( n e wS i z e ) ) "
@ I BAct i o n f u n c t o g g l e Fa vo r i t e ( s e nde r : U I Sw i t c h ) {
l e t f a vo r i t e s L i s t = Favo r i t e s L i s t . s h a r e d Favo r i t e s L i s t
i f s e n de r . i s On {
f a vo r i t e s L i s t . add Favo r i t e ( f o n t N ame : f o n t . f o n tN ame )
else {
f a vo r i t e s L i s t . r emove F a vo r i t e ( f o n t N ame : f o n t . fontName )
Эти м етоды довольно п ростые. Метод vi ewDidLoad ( ) устанавл ивает отоб­
ражение на основе в ыбранного шрифта; s l i d e Fo n t S i z e ( ) изменяет размер
шрифта в метке f o n t S amp l e Labe l на основе значения п олзу н ка; а t o gg l e
Favo r i t e ( ) добавляет текущий шрифт в с писок предпочитаемых шрифтов или
удаляет его оттуда в зависимости от значения перекл ючател я .
ГЛАВА 9 tA КОНТРОЛ Л Е Р Ы НАВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И �
375
Р аскадровка контроллера представления
инфор м ации о шрифте
Теперь вернемся к файлу Ma i n . s t o ryboa rd, чтобы создать графический ин­
терфейс пол ьзователя для этого последнего контроллера представления в при­
ложении. Найдите в библ иотеке объектов стандартн ы й элемент View Controller.
Перетащите его в область редактирован ия и воспол ьзуйтесь инспектором иден­
тичности, чтобы задать его класс Font i n foViewCont ro l l e r . Затем найдите в
библ иотеке объектов остал ьные объекты и перетащите их в новую сцену. Вам
нужны три метки, перекл ючател ь и ползунок. Расположите их примерно так,
как показано на рис. 9 . 1 2 .
•
1111
-
�аЬеl
о
о
lnclude in Favorites
«::)
22
Рис . 9 . 1 2 . М а кет м етки , пе рекл ю ч ател я и ползун ка
Обратите вни ман ие, что мы оставил и некоторое пространство выше верхней
метки, так как собираемся в конечном итоге разместить там панел ь навигации .
Кроме того, м ы хоти м, чтобы верхняя метка могла отображать дли н н ые фраг­
менты текста в нескол ько строк, но по умолчанию метка вы водит только одну
строку. Для того чтобы измен ить это поведение, выберите метку, откройте окно
инспектора атрибутов и установите в поле Lines значение О .
376
ГЛАВА 9 � КОНТРОЛЛЕР Ы НАВ И ГА Ц И И И ТАБ Л И Ч Н Ы Е П Р ЕДСТА В Л Е Н И Я
На рис. 9 . 1 2 также показан изменен н ы й текст в двух н ижних метках. В не­
сите и здес ь такие же изменен и я . На рису н ке не показано, что для выравни­
ван ия обеих меток по п равой стороне был испол ьзован и нспектор атрибутов.
В ы должн ы посту п ить так же, так как обе они должны б ыть привязаны к пра­
вому краю. Кроме того, установите ползунок в н ижней части и воспол ьзуйтесь
инспектором атрибутов, чтобы установить значение M i n i m u m рав н ы м 1, а Maxi­
mum
2 00.
Те перь пора п одключать все соедине ния дл я этого графическо го и нтер­
фейса. Н ач н ите с в ы бора контроллера п редставл е н и я и открытия и нспек­
тора с вязей . Когда требуется сдел ать м ного соеди н е н и й , этот и нсп е ктор
предоставляет возможность неплохого их обзора. Перетаскивая указател ь, свя­
жите кажды й в ы ход (мален ькие кружки рядом с и менам и favo r i t e S wi tc h,
font Samp l eLab e l , font S i z e Lab e l и font S i z e S l ide r) с соответствующи м и
объектами в с цене . В ы ход fo n t S amp l e L abe l должен б ыть с вязан с меткой
в верхней части; выход f o nt S i z eLabe l
с меткой в правом н ижнем углу;
выходы favo r i t e S w i t ch и font S i z e S l i d e r
с л юб ы м и местам , где они
могут располагаться . Для связ ы вания действий с элементам и у п равления мож­
но п родолжать и спол ьзовать инспектор с вязе й . Находяс ь в разделе Received
Actions для контроллера п редставления, п еретащите у казател ь от маленького
кружка рядом с s l i d e FontS ize : к ползун ку, отпустите кно п ку м ы ш и и выберите
из вспл ы вающего меню пун кт Val u e C h a nged . Затем перетащите указател ь от
маленького кружка рядом с togg l e Favorite: к перекл ючател ю и вновь выберите
ю вспл ы вающего меню пун кт Va l u e C h a n g ed . С вязи должны в ы глядеть так,
как показано на рис. 9 . 1 3 .
Кроме того, нам нужно создать переход для демонстрации представления.
Напом н и м , что это п редставлен ие будет отображаться вся кий раз, когда пол ь­
зовател ь нажимает п и ктограмму просмотра детал ьной информаци и (маленькая
синяя буква "i" в круге) в ко нтроллере п редставления сп иска шрифтов. Итак,
найдите этот контроллер, нажм ите клавишу <Contro l>, перетащите указател ь от
прототипа ячейки к новому контроллеру представления информаци и о шрифте
и выберите пункт show из раздела Accessory Action вспл ы вающего меню. Обра­
тите вни ман ие, что мы говорим Accessory Action, а не Selection Seg ue (рис. 9. 1 4).
Действие аксессуара я вляется переходом, которы й запускается, когда пол ьзова­
тел ь касается п и ктограм м ы детал ьной и нформаци и, тогда как выбор перехода
я вляется переходом, которы й запускается нажатием в л юбом ином месте стро­
ки. М ы уже устано в ил и , что выбор перехода этой ячейки откры вает объект
Font S i z e sViewCont ro l l e r .
Теперь у нас есть два разных перехода, которые могут запускаться нажати­
я м и в разных частях строки. Поскол ьку они представляют разные контроллеры
представления с раз н ы м и свойствами, нам нужно и м еть возможность их раз­
личать. К счастью, класс U I S to ryboa rdS egue, который п редставляет переход,
позволяет это сделать: м ы можем испол ьзовать идентифи катор так же, как м ы
делаем это с ячейками табл ично го п редставления .
-
-
-
ГЛАВА 9 г,; К О НТРОЛЛ Е Р Ы НАВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П Р ЕДСТА В Л Е Н И Я
Trl1111•red Segun
1
11
-1
11
L.зbel
1
1
1
1
1
1
lnclude in Favorites
1
[
с:)
22
___
__ _ __ _
1
manual
OUtleta
Preaentlng S.11-
о
о
о
о
о
о
о
о
о
Rel1donahlp
Show
Shaw Oetlll
Pret.пt Mod1Ny
Prtunt As Popover
еmью
Pulh (deprecatedl
MOOll (dePf8C81ed)
Cu1tom
Aeferenclng OUtleto
о
New ReferencJng Outlet
Reler8flclng Outlet Cotlectlon1
J
Рис. 9 . 1 3 . Связи в раскадро вке контроллера Fon t i n foVi ewCon t r o l l e r
,_ .._
: < •-
<
>
:. А- • ' >
1 . . .�-
� • (, <1 е
�:::-: .' "�:-�_:;�-�- .
---- -- - ·--�-
•;) ;
l)
..... " ..... " t. C · _,
l!i] . t!
�".,r. '
-�··"
! ""..
. " .
. . ." .
о >
'
•
.
.
.. " . " "
· · · · · ··
"
.......
"."
Рис . 9 . 1 4. Н астро й ка п е реходов дл я действи я Accessory Action
377
378
ГЛАВА 9 � КОНТРОЛ Л Е Р Ы НАВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
Все, что в а м нужно сделать, - это выбрать переход в области редактиро­
ван ия и испол ьзовать и нспектор атрибутов для задания его иде нтифи катора.
Вам может потребоваться нем ного сдви нуть ваш и сцены, чтоб ы видеть оба пе­
рехода, выходящие из п равой части контроллера представления списка шриф­
тов . В ы берите тот, который у казы вает на контроллер представления размеров
шрифта, и задайте его атрибут l d e ntifier равн ы м ShowFont S i z e s . Далее вы­
берите тот, кото р ы й указы вает на контроллер п редставления и нформаци и о
шрифте, и установите его атрибут ldentifier рав н ы м S howFo nt i n f o, как пока­
зано на рис. 9. 1 5 .
8tory-nl .....
ldontiflor ShowFontlnfo
Cl1ss
Modulo '
Klnd
Peok & Рор
vL.
Show (e.g. Push)
S Anlmetes
оа
а
в
Prevlew & Commlt Seguos
-"
о
•
•
-
Рис. 9 . 1 5 . Иденти фи кация пе реходов
Настройка ограничений
Н астрой ка этого перехода дает знать п рограм ме l nterface Builder, что наша
новая сцена будет испол ьзоваться, как и все остал ьное, в контексте контроллера
навигации, так что сцена автоматически получает пустую панел ь навигации в
верхней части . Теперь, когда у нашего п редставления поя вил ись реальные пре­
делы, самое время для настрой ки ограничений. Это довол ьно сложное представ­
ление с несколькими п редставлениям и , особенно в н ижней части, поэтому м ы
не можем пол ностью полагаться на то, что системные автоматические ограниче­
ния сделают все вместо нас. Мы будем использовать кнопку P i n в н ижней части
области редактирования и вспл ы вающее окно, которое откры вает эта кнопка,
чтобы создать большую часть необходим ы х нам огран и чен и й .
Нач нем с самой верхней метки . Щел кните на кноп ке P i n , а затем в о вспл ы­
вающем окне выберите небол ь ш ие красные полоски выше, слева и справа от
ГЛАВА 9 f1: КОНТРОЛЛ Е Р Ы НАВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
379
небол ьшого квадрата, но не под н и м . Затем щелкните на кно п ке Add 3 Con­
strai nts в нижней части .
Выберите ползунок в н ижней части и щелкните на кно п ке Pi n . На этот раз
выберите красные полоски н иже, слева и справа от маленького квадрата, но не
над н и м . В новь щел кн ите на кно п ке Add 3 Constra i n ts, чтобы поместить их на
место.
Для каждой из двух оставш ихся меток и перекл ючателя выпол н ите следую­
щие действия : выберите объект, щел кн ите на кнопке P i n , выберите красные по­
лоски н иже и справа от маленького квадрата, установите флажки Width и Height
и щел кн ите на кнопке Add 4 Constraints. Установка этих ограничений для всех
трех объектов будет привязы вать их к н ижнему п равому углу.
Есть еще тол ько одно ограни чен ие, которое надо создать. М ы хотим, чтобы
верхняя метка увел ичи валась, чтобы содержать текст, но не в ырастала настол ь­
ко, чтобы перекрывать представления снизу. Этого можно добиться с помощью
еди нственного огран ичен и я . П роведите соед и н ител ьную л и н и ю от верхней
метки к метке l nclude i n favorites, отпустите кнопку м ы ш и и выберите Vertical
Spacing из вспл ы вающего меню. Затем щелкните на новом ограничении для его
выбора (это голубая вертикальная полоса, соединяющая две метки) и открой­
те окно инспектора атрибутов, в котором вы увидите некоторые настраи ваемые
атрибуты ограничени я . Измените значение атрибута Relation н а Greater Than
or Equa 1, а затем задайте значение Constant рав н ы м 1 О. Это гарантирует, что
расширение верхней метки не затронет другие представления в н ижней части .
Адаптация контроллера представления списка
ш рифтов для нескольких переходов
Вернемся вновь к файлу F o n t L i s t V i e w C o n t r o l l e r . s w i f t . Поскол ь ку
этот класс теперь будет иметь возможность запускать переходы к двум различ­
н ы м дочерн и м контроллерам п редставлений, необходимо адаптировать метод
prepa re ForSegue ( : s ende r : ) так, как показано в л истин ге 9. 1 2 .
Л истинг 9 . 1 2 . Обработка нескольких переходов
1 1 МАRК :
-
Nav i g a t i on
ove r r i de f u n c p r e p a r e ( f o r s e g u e : U I S t o r yb o a r d S e g u e , s e n de r : An yOb j e c t ? ) {
1 1 Получ а е т но вый кон троллер пр е д с т а в л е ни я , и с п ол ь зуя
1 1 , [ s e g u e de s t i n a t i onVi ewCon t ro l l e r ] .
1 1 Передает выбр а н ный объе кт н о в ому кон троллеру предс т а вл е ни я .
l e t t a Ь l e Vi ewCe l l
s e nde r a s ! U I T a Ь l eV i ewCe l l
l e t i ndex P a t h = t a Ы e V i e w . i ndex P a t h ( f o r : t a Ь l e V i ewCe l l ) !
let font
f o n t Fo r D i s p l a y ( a t i n dex P a t h : i ndex Pa t h )
=
=
i f s e g u e . i d e n t i f i e r == " S h o w F on t S i z e s "
l e t s i z e sVC
s e g u e . d e s t i na t i o n V i ewCont ro l l e r a s !
Font S i z e sVi e w C o n t r o l l e r
s i z e s VC . t i t l e
f o n t . f o n t N ame
s i z e s VC . f o n t
font
=
=
=
380
ГЛАВА 9 ;rJ КОНТРОЛЛ Е Р Ы Н А В И ГА Ц И И И ТАБЛ И Ч Н Ы Е П РЕДСТАВЛ Е Н И Я
else (
l e t i n foVC = s e g u e . d e s t i n a t i o nVi e w C o n t ro l l e r a s !
Fo n t i n f o V i e w C o n t r o l l e r
i n foVC . t i t l e = f o n t . f o n t N ame
i n foVC . f o n t = f o n t
i n foVC . favo r i t e =
Favo r i t e s L i s t . s h a r e d F a vo r i t e s L i s t . f a vo r i t e s . c o n t a i n s ( f o n t .
f o n t Name )
)
Запустите приложение и посмотрите, что у вас получ илось. Выберите се­
мейство, содержащее много шрифтов ( например, G i l l Sans), а затем косн итесь
знач ка посредине строки л юбого шрифта. Отобразится сп исок, который вы ви­
дели ранее, с шрифтам и разл и ч н ы х размеров. Н ажм ите кнопку навигаци и в ле­
вом верхнем углу (она помечена как Gill Sans ), чтобы вернуться обратно, а затем
нажм ите другую строку (на этот раз нажм ите справа, на п и ктограмме детал ьной
и н формации). Это нажатие должно вызвать последн ий контроллер представле­
ния, который отображает образец шрифта с ползу н ком в н ижней части, позво­
ляющим выбрать л юбой размер шрифта.
Кроме того, теперь можно воспол ьзоваться перекл ючателем l nclude in favor­
ites для отметки этого шрифта как избранного. Сделав это, нажм ите кноп ку на­
в и гации в левом верхнем углу нескол ько раз, чтобы вернуться к контроллеру
корневого представления .
П редпочитаемые шрифты
Прокрутите экран в н из до нижней части корневого контроллера представле­
ния, и увидите нечто новое : второй раздел, показанн ы й на рис. 9. 1 6.
Тонкости табличного п редставления
Итак, основные функции нашего приложения готовы. Тем н е менее, прежде
чем м ы сможем действител ьно назвать его гото в ы м , реал изуем в нем еще не­
сколько возможностей. Если вы уже некоторое время испол ьзуете систему iOS,
то, вероятно, вам известно, что можно удалить строку из таблич ного представ­
ления, проведя пал ь цем справа налево. Напри мер, в приложе н и и Mail можно
испол ьзовать этот метод для удаления сообщения из списка. Этот жест вы водит
небол ьшой графический и нтерфейс в строке табл ич ного представления. Он за­
праши вает подтверждение удаления, после чего строка исче'3ает, а оставш иеся
строки подн имаются вверх, чтобы запол н ить п робел . Обо все м этом взаимо­
действии - вкл ючая обработку жеста, запрос подтверждения и анимации затро­
нутых строк - заботится само табл и ч ное представление. Все, что вам нужно
сделать, - это реал изовать два метода в своем контроллере.
Кроме того, табл и ч ное п редставление позволяет пол ьзовател ю легко изме­
н ить порядок строк в этом табл и ч ном представлении, перетаски вая их вверх и
вниз. Как и в случае жеста удален ия, табл и ч ное представление само заботится
ГЛАВА 9 �.1 КОНТРОЛ Л Е Р Ы НА В И ГА Ц И И И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
381
обо всем . Все, что вы должны сделать, - это добавить одну строку установки
(чтобы создать кноп ку, которая акти визирует переупорядочение графического
и нтерфейса), а затем реализовать оди н метод, которы й вызывается, когда пол ь­
зовател ь заканчи вает перетаскиван ие.
''Ч
'
Carrler •
IPhone в. - юs 10.0 (14A5287el
( Fonts
ArialMT
2:21 РМ
Favorites
Ari1IMT
SinhalaSangamMN-Bold
Slnh1\1S1ngamMN·Bold
Arfal-BoldltallcMT
Atial·ВoldltallcMT
''"""
...
CD '
CD >
CD >
Рис . 9 . 1 6 . С п и с о к ранее в ы б р а н н ы х
п редп о ч и тае м ых ш р и фтов
Реализация ж еста удаления
В этом п риложении класс Fon t L i s tVi ewCon t r o l l e r я вляется ти п и ч н ы м
прим ером испол ьзован ия этой возможност и . Вся к и й раз, когда п р иложение
отображает список предпочитаемых шрифтов, м ы должны позволить пол ьзова­
тел ю удал ить шрифт из списка предпоч итаемых, сделав жест пальцем, коротким
путем, т.е. не нажи мая п и ктограм му детал ьной информации и перекл ючател ь .
Выберите для начала файл FontLi s tVi ewCon t r o l l e r . s w i f t в среде Xcode.
Начн ите с добавления реал изаци и метода taЬleV i ew ( _ : canEdi tRowAt : I ndex
Path : ) :
ove r r i de f u n c t a Ы e V i e w ( t a Ь l e V i e w : U I T a Ь l e V i ew ,
c a n E d i t RowAt i n dex P a th : I n de x P a t h ) - > B o o l (
r e t u r n s ho w s Favo r i t e s
382
ГЛАВА 9 ;i КОНТРОЛЛ Е Р Ы НАВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
Этот метод будет возвращать значение t rue, есл и выводится список пред­
почитаем ы х шрифтов, и f a l s e в п роти в ном случае . Это означает, что фун к­
ция редактирования, которая позволяет удалять строки, включается тол ько при
отображен и и списка предпоч итаемых шрифтов. Есл и вы попытаетесь запустить
приложение и удалить строки с помощью тол ько что внесенного изменен ия, то
не увидите н и какой разницы . Табли чное п редставление н и как не отреагирует на
жест удаления, потому что еще не реал изован метод, которы й требуется для за­
вершения удаления. Так что добавьте реализацию метода taЬleView ( _ : commi t
Edi t i ng S t y l e : forRowAt i ndexPath : ) , как показано в листи н ге 9. 1 3 .
Листинг 9 . 1 З . Метод, обеспечивающий возможность
удаления строк из списка п редпочитаемых ш рифтов
ove r r i de f u n c t a Ы e V i ew ( _ t a Ы e V i ew : U I T a Ь l e V i e w , comrni t e d i t i n g S t y l e :
U I T a Ь l e V i ewC e l l Ed i t i n g S t y l e , f o r RowAt i n de x P a t h : I n dex Pa t h ) {
i f ! s hows Favo r i t e s {
return
i f edi t i n g S t y l e == U I T a Ы e V i ewC e l l Ed i t i n g S t y l e . de l e t e
1 1 Уда л я е т с т р о ку и з и с т очника данных
l e t f a vo r i t e = f o n tNarne s [ i ndex P a t h . r ow ]
Favo r i t e s L i s t . s h a r e d Favor i t e s L i s t . r ernove Favo r i t e ( f o n tNarne :
favor i t e )
f o n t Narne s
Favor i t e s Li s t . s h a r e d Favor i t e s L i s t . f a vo r i t e s
=
t a Ь l e V i ew . de l e t eRows ( a t : [ i nd e x P a t h ] ,
w i t h : U I T a Ь l e V i ewRowAn i rna t i o n . f a de )
Этот метод вызы вается после завершения редактирования таблицы. Он до­
статочно п рост, но в нем есть некоторые тон кости. Первое, что м ы делаем, убеждаемся, что показы ваем с писок п редпоч итае м ы х шрифтов ; есл и нет, то
п росто н ичего не делае м . В ообще-то, это н и ко гда не должно произойти, так
как мы указали в предыдущем методе, что редактируем ы м может быть тол ько
сп исок предпочитае мых шрифтов . Тем не менее на всяк и й случай м ы немно­
го перестрахо в ы ваемся . После этого проверяем стил ь редактирован ия, чтобы
убедиться, что кон кретная операция, которую мы собираемся выпол н ить, действител ьно удаление. Можно добавить вставку в табл и ч ное представление,
но не без допол н ител ьной настройки, которую мы здес ь не делаем, а потому
нам не следует беспокоиться о других действиях, кроме удале н и я . Далее м ы
определяем, какой шрифт следует исключ ить и з с п иска, удаляем его и з сингл­
тона Favo r i t e s L i s t и обновляем локал ьную коп и ю списка предпоч итаемых
шрифтов .
Наконец м ы требуем от табл ичного представления удалить строку и заставить
ее исчезнуть с визуальным заrуханием . Важно понимать, что именно происходит,
ГЛАВА 9 и КОНТРОЛ Л Е Р Ы НАВ И ГА Ц И И И ТАБЛИ Ч Н Ы Е П РЕДСТАВ Л Е Н И Я
383
когда вы сообщаете таблич ному представлению о том, что нужно удал ить стро­
ку. И нтуитивно вы можете подумать, что вызов этого метода будет удалять не­
которые данн ые, но это не так. На самом деле м ы уже удал или данн ы е ! Пос­
ледний вызов метода - на самом деле просто наш с пособ сказать табличному
представлению "Я внес изменения и хочу,
чтобы ты анимировало удаление этой стро­
Cerrter •
2:48 РМ
ки . Если тебе нужно что-то еще, обращайся
( Fonts
Favorltes
ко мне". Когда это произойдет, табл и ч ное
ArlalMT
CD >
Аг1а1МТ
представление начнет анимацию всех строк,
находя щихся ниже удаленной, перемещая их
SinhalaSangamMN·Bold
CD >
SlnhalaSongamMN·Bold
вверх, так что вполне возможно, что одна
CD >
licMT
ил и нескол ько строк, которые б ыл и ранее
не видн ы, теперь отобразятся на экране, и
произойдет запрос контроллера о данн ых
ячейки обы ч н ы м и методам и . Поэтому важ­
но, чтобы наша реал изация метода t а Ы е
Vi ew ( : commi tEdi t i n g S t y l e : fo rRowAt I
ndex Pa th : ) вносила необходимые измене­
ния в модел ь дан ных (в данном случае в синглтон Favo r i t e s L i s t) перед тем, как
требовать от табл ич ного представления уда­
лить строку.
Снова запустите приложен ие, убедитесь,
что у вас есть некоторые предпоч итаемые
шрифты, а затем перейдите к их списку и
удал ите строку, проводя по ней пальцем спра­
ва налево. Строка частично сдвинется влево,
а справа поя вится кнопка Delete (рис. 9. 1 7). Рис . 9. 1 7 . Стро ка п редпоч итае ­
Нажмите ее, и строка будет удалена.
м о го ш р и фта с к н о п кой Delete
Р еализация переупорядочения перетаскиван ием
Последняя возможность, которую м ы собираемся добавить в список шриф­
тов, позволяет пол ьзователя м изменять сп исок п редпоч итае м ы х шрифтов, пе­
ретаски вая их вверх и вниз. Для того чтобы добиться этого, добави м в класс
Favori t e s L i s t один метод, который позволит нам переу порядоч ивать элемен­
ты . Оtкройте файл Favo r i t e s L i s t . s w i f t и добавьте в него следующий ме­
тод:
func move i t em ( f r om i ndex f r om : I n t , t o i ndex t o : I n t ) {
l e t i t em
f a vo r i t e s ( f r om ]
favo r i t e s . r emove ( a t : f r om )
f a vo r i t e s . i n s e r t ( i t e m , a t : t o )
s ave Favo r i t e s ( )
=
384
ГЛАВА 9 м1, КОНТРОЛ Л Е Р Ы НАВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П Р ЕДСТАВЛ Е Н И Я
Этот нов ы й метод обеспечивает основу для того, что м ы собираемся делать.
Выберите файл Fon t L i s tViewCont ro l l e r . swi f t и добавьте следующие стро­
ки в кон це метода vi ewDidLoad:
i f showsFavorite s {
navi9ati on i tem . ri9htBarButton i tem
=
edi tButto n i tem ( )
М ы уже упом и н ал и об этом элементе навигаци и . Это объект, содержащи й
информацию о том , что должно поя в иться на панел и навигаци и контроллера
представления. Он имеет свойство r i ghtBarBut t o n i t em, которое может содер­
жать экземпляр U I B a rBut t o n i tem, особ ы й вид кноп ки, предназначенной толь­
ко для панелей навигации и и нструментов. Здесь этому свойству присваивается
edi tButton i t em, свойство U IVi ewCon t ro l l er, которое дает нам специальную
кнопку, настроенную для акти визации графического и нтерфейса редактирован ия
ил и переупорядочения табл ичного представления .
Попробуйте запустить п р иложение и перейти к с п иску предпоч итаемых
шрифтов. В ы увидите, что теперь в п равом верхнем углу имеется кнопка Edit.
Нажатие этой кнопки вкл ючает графически й и нтерфейс редактирован ия табл ич­
ного п редставления, которы й означает, что каждая строка получает кнопку уда­
ления слева, а содержание сдвигается немного вправо, чтобы освободить место
для кнопки (рис. 9 . 1 8). Это еще оди н способ, которы м пол ьзовател и могут уда­
лять строки, испол ьзуя уже реализован ные нами методы .
Однако наша гл ав ная цел ь - добавл е н и е фун кционал ь н ости переу по­
рядочения . Все, что для этого нужно сдел ать, - это добавить в файл Font
L i s tVi ewCont ro l l e r . swi f t следующий метод:
ove r r i d e f u n c t a Ы e V i e w ( _ t a Ы e V i e w : U I T a Ь l e V i e w ,
move RowAt s o u r c e i n de x P a t h : I nde x P a t h ,
t o de s t i n a t i on i nde x P a t h : I n d e x P a t h ) {
Favo r i t e s L i s t . s h a r e d Fa vo r i t e s L i s t . move i tem (
f r om l nde x : s o u r c e i ndex P a t h . r ow ,
t o l nd e x : de s t i n a t i o n i ndex P a t h . row )
f o n t Name s
Favo r i t e s L i s t . s h a r e d Favo r i t e s L i s t . f a v o r i t e s :
Этот метод вызывается, как тол ь ко пол ьзовател ь завершает перетаскивание
строки. М ы сообщаем с и н глтону Favo r i t e s L i s t о том , чтобы он вы пол н ил
переупорядочен ие, а затем обновляем наш с писок наз ван и й шрифтов так же,
как п осле удаления элемента. Чтобы увидеть эту возможность в действии, за­
пустите приложение, перейдите в список п редпоч итаемых шрифтов и нажм ите
кно п ку Edit. В ы увидите, что в режиме редактирован ия строки вкл ючают в пра­
вой части п и ктограм м ы для перетаскиван ия, которые можно испол ьзовать для
изменения порядка элементов.
ГЛАВА 9
.•, ,
.
КОНТРОЛЛ Е Р Ы Н АВ И ГА Ц И И И ТАБЛ И Ч Н Ы Е П РЕД С ТАВЛ Е Н И Я
385
iPЬone 6s - iOs 10.0 (14А5297о)
Carrier '?
( Fonts
•
ArialMT
•
Verdana
•
•
З:1 5 РМ
Favorites
-
Done
Ar\alMT
SinhalaSangamMN-Bold
SinhalaSangamMN·Bold
Verdana
Markerfelt-Wlde
MarkerFelt·Wide
Рис. 9 . 1 8 . Табл и ца п редпоч итае м ых ш р и ф ­
тов с добавл е н н о й фун кци е й редакти рова н и я
Р е зюме
Несмотря на то что в этой главе м ы много работал и с табл и ч н ы м и п ред­
ставлен иями, наше основное вн имание было сосредоточено на контроллерах
навигации и способах просмотра иерархически организован ного содержания в
условиях ограниченного пространства, которые характерны для бол ь ш и нства
устройств i Phone, особенно в книжной орие1паци и .
М ы создал и 11 риложение для 11 росмотра сп иска шрифтов, которое демон­
стрирует не тол ько с11особы 11ерехода к детал изированным представлениям, но и
методы обработки многочисленных переходов из отдел ьной ячейки табл ич ного
представления, напри мер при просмотре размеров ил и и нформации о шрифтах.
В заключение м ы показал и, как можно откорректировать табл и чное представ­
лен ие, чтобы вкл ючить в него возможности удаления ил и перемещения строк.
ГЛ АВА 1 О
• • •
П р едста в л е н ие к о лл е к ц и и
Многие годы разработчи ки п рограмм дл я системы iOS испол ьзовал и ком по­
нент U I TaЬleView для создания самы х разнообразных и нтерфейсов. Благодаря
тому что класс U I T a Ь l eView п редоставляет программ исту возможности опре­
делять нескол ько типов я чеек, создавать их "на лету" и прокручи вать в вер­
ти кал ьном нап равлении, он стал ключев ы м ком понентом для тыся ч приложе­
ний. На протяжении дол гого времени ком пания Apple основывала свой подход
к созданию интерфейсов прикладного программ и рования на классе таблич ного
представления, постоя н но добавляя новые, более эффекти вные возможности для
его наполнения в новых вы пус ках систе м ы iOS. Однако во м ногих областя х
обработки данных табл и ч ное представление не является окончател ьным реше­
нием. Напри мер, есл и необходимо представить данные из нескол ьких столбцов,
приходится объединять все столб цы в каждой строке дан ных в одну я чейку.
Кроме того, ком понент U I T aЬ l eV iew не позволяет прокручи вать свое содер­
жимое в горизонтал ьном направлен и и . В целом бол ьшая часть мощи класса
U I T aЬ l eView я вляется резул ьтатом определенного компром исса: разработч ики
не имеют контроля над общей схемой табл и чного представления. Программ ист
может как угодно определ ить внеш н и й вид любой отдел ьной ячейки по своему
желанию, но в кон це дня они просто нагромождаются одна над другой в одном
большом сп иске прокрутки .
В системе iOS 6 был в веден новый класс U I C o l l e c t i o nVi ew, которы й
должен был устран ить эти недостатки . Как и табл и чное представлен ие, этот
класс позволяет вы водить на экран совоку п ность я чеек, заполненных дан н ы ­
ми, и работать с ними, располагая неиспол ьзованные ячейки в очереди для ис­
пол ьзования в буду щем . Однако, в отличие от табличного представления, класс
U I C o l l e c t i onView не создает из этих ячеек вертикал ь н ы й стек. На самом деле
ком понент U I C o l l e c t i onVi ew вообще их не представляет на экране. Вместо
этого он поручает эту работу вспомогательному классу.
388
ГЛАВА 1 О �· П Р ЕДСТАВЛ Е Н И Е КОЛЛ Е К Ц И И
Создание п роекта DialogViewer
Дл я то го чтобы проде м о н стри ровать н е которые возможности кл асса
U I Co l l e c t i onVi ew, мы будем испол ьзовать его для представления нескольких
абзацев текста. Каждое слово будет помещаться в отдел ьной ячейке, и все я чей­
ки каждого абзаца будут объеди няться в раздел ы . Каждый раздел также будет
иметь свой заголовок. Все это, может быть, не сл и ш ком захваты вающе, о � обен­
но есл и учесть, что библиотека U I K it уже содержит другие превосходн ые спо­
собы для представления текста, но их испол ьзован ие было бы непедагогичным,
поскол ьку м ы хотим объяс н ить вам, наскол ько гибки м я вляется новы й кл асс.
На практи ке вы вряд ли станете делать что- нибудь подобное тому, что изобра­
жено на рис. 1 0. 1 , с помощью табл и ч ного представления.
Сан�.- •
irtt Wltch
Неу, when wlll
up
later?
8:28 РМ
the
three
of
us mee t
When everything's straightened out.
That'll Ье Just Ьefore sunset.
lrst Wltch
Where?
1
guess we'll see Мае there.
Рис . 1 0 . 1 . Каждое с л о в о н аходится в отде ­
л ьн о й я ч е й ке за и с кл ю ч е н и е м загол о в ко в . Все
они в ы водятся н а экран с п о м ощью ко м п о н е нта
U I C o l l e c t i onView и не требуют от п рограм м и с ­
т а я в н ы х геом етр и ч еских в ы ч и сл е н и й
ГЛАВА 1 О ,,i П РЕДСТАВЛ Е Н И Е КОЛЛ Е К Ц И И
389
Дл я то го чтоб ы реш ить п о ставл е н ну ю задачу, необход и м о о п реде­
л ить н е с кол ь ко п ол ьзовател ь с к и х кл ас с о в и в о с п ол ьзо ваться кл ассом
U I Co l l e c t i onViewFl owLa yout (единстве н н ы м вспомогател ь н ы м классом для
вывода дан ных на экран, вкл юченных в библиотеку U I Kit в настоящее время ),
а затем, как обы ч но, ис пол ьзовать контроллер представления для того, чтобы
связать все это в одно целое.
Откройте в среде Xcode новый проект Single View Applicatio n , как м ы дела­
ли уже м ного раз. Назовите с вой п роект D i a l ogVi ewer и испол ьзуйте стан­
дартные настройки, при меняем ые повсеместно в этой к н и ге (выберите пу н кт
Swift в списке Language и пункт U n iversal в списке Devices). Откройте файл
ViewCont ro l l e r . s w i ft и измен ите его суперкласс на U I Co l l e c t i onVi ew:
class ViewController : UICollectionViewController {
Откройте файл Ma i n . s t o r yboard. Нам нужно настроить контроллер пред­
ставления, чтобы он соответствовал тому, что м ы тол ько что указал и в файле
Vi ewCont rol l e r . s w i f t . Выберите элемент View Controller в окне Document Out­
l i ne и удал ите его, оставив раскадров ку пусто й . Найдите в библиотеке объектов
элемент Co l l e c t i o n View Contro l l e r и перетащите его в область редактиро­
вания . Вы увидите, что объект Collection View в о кне Document Outline имеет
вложен ное представление коллекци и . Его отношение с представлением коллек­
ции очен ь похоже на отношение между классами U I T a Ь l eVi ewCon t ro l l e r и
вложенным в него классом U I T a Ь l eVi ew. В ыберите п и ктограмму контролле­
ра представления коллекци и и с помощью инспектора иденти чности измените
его класс на Vi ewCo n t r o l l e r точ но так же, как м ы это сделали в подкл ассе
U I Co l l e c t i onVi ewCont ro l l e r . Перейдите в окно инспектора атрибутов и ус­
тановите флажок l s l n itial View Controller. Затем выберите представление коллек­
ции в окне Document Outl i n e и с помощью инспектора атрибутов измените цвет
его фона на бел ы й . В заключение в ы увидите, что п редставление коллекции
имеет дочернее представление с именем Col lection View Cel l . Это ячейка-прото­
тип, которую можно испол ьзовать для разработки макета ваш их реальных ячеек
в программе lntertace Bui lder. Мы не собираемся делать это в дан ной главе, так
что выдел ите эту ячейку и удал ите ее.
Определение пользовательских ячеек
Теперь определ и м нескол ько классов для я чеек. Как показано на рис. 1 О. \ ,
мы в � 1 води м на экран два основ н ы х вида ячеек: "обыч ную", которая содер­
жит слово, и "необ ы чную", которая испол ьзуется как заголовок. Л юбая ячей­
ка, которую в ы будете испол ьзо вать совместно с классом U I C o l l e c t i onVi ew,
должна быть подклассом системного класса U I C o l l e c t i onVi ewC e l l , обес­
печи вающего основные фу нкционал ьные возможности, аналогичные возмож­
ностя м класса U I T a Ь l eVi ewCe l l . Эта фун кционал ьн ая возможность вкл юча­
ет bac kgroundVi ew, conte ntVi ew и т.д. Посколь ку две наши ячейки и меют
390
ГЛАВА 1 О ,.:; П Р ЕДСТАВЛ Е Н И Е КОЛ Л Е КЦ И И
сходные фун кцион ал ь н ые возможности, м ы сделаем одну и з них подклассом
другой и будем замещать в подклассе некоторые методы .
Нач нем с создания нового класса Сосоа Touch в среде Xcode. Назовите новый
класс ContentCe l l и сделайте его подклассом класса U I Co l lect i onViewCe l l .
В ы берите исходный файл нового класса и добавьте в него объя вления трех
свойств и заготовку метода класса, как показано в листи н ге 1 0. 1 .
Листинг 1 0 . 1 . Определение класса ContentCe l l
c l a s s C o n t e n t Ce l l : U I Co l l e c t i on V i e w C e l l
var laЬel : UI LaЬel !
var text : String !
var maxWidth : CGFloat !
class func si zeForContentString ( s : S tring ,
forМ&xWidth maxWidth : CGFloat) -> CGSize {
return CGS i z e . zero
С войство l abe l будет указывать на объект U I Labe l, испол ьзуемый для вы­
вода метки на экран . С войство text будет сообщать ячейке, что именно в ней
должно отображаться, свойство maxWidth - управлять максимальной шириной
я чейки, а метод s i z e Fo rConte nt S t r i ng ( _ : fo rMaxWidth : ) , который м ы вско­
ре реал изуем, будет испол ьзоваться для запроса размера ячейки, чтобы она мог­
ла уместить заданную строку на экране. Это удобно при создании и настройке
экземпляров классов, описывающих наш и ячейки.
Добавьте переопредел е н и я методов i n i t ( f r ame : ) и i n i t ( c o d e r : ) в
U IVi ew, как показано в л истин ге 1 0.2.
Листинг 1 0 . 2 . Переопределения методов в классе Conte nt c e l l
ove r r i de i n i t ( f r ame : CGRe c t ) {
s up e r . i n i t ( f r ame : f r ame )
l ab e l
U I La be l ( f r ame : s e l f . c o n t e n t V i e w . b o u n d s )
l ab e l . i s Op a q u e
false
l ab e l . b a c kg r o u ndCo l o r =
U I C o l o r ( r ed : О . В , g r e e n : 0 . 9 , Ы u е : 1 . 0 , a l p h a : 1 . 0 )
l ab e l . t e x t C o l o r = U I Co l o r . Ы a c k ( )
l ab e l . t e x tA l i g nme n t = . ce n t e r
l abel . font
s e l f . dynami c T yp e . de f a u l t Fo n t ( )
c o n t e n t V i e w . addSubv i e w ( l ab e l )
=
=
=
r e qu i r e d i n i t ? ( c ode r a De c o de r : N S C o de r ) {
s up e r . i n i t ( c ode r : a De c o de r )
Код, приведенный в л истин ге 1 0.2, довол ьно п ростой. О н создает метку, задает
ее свойства для отображения на экране и добавляет ее в объект contentView.
Еди нственная тон кость состоит в том, что этот код определяет шрифт для метки
ГЛАВА 1 0 ii! П Р ЕДСТАВЛ Е Н И Е КОЛЛ Е К Ц И И
391
с помощью метода defau l t Font ( ) . Идея заключается в том, что этот класс дол­
жен определять, каким шрифтом отображать содержимое, позволяя своим под­
классам объя влять собствен н ые шрифты, переопределяя метод de faul t Font ( ) .
Поскол ьку м ы пока не создал и метод defaul t Font ( ) , настал момент это сделать.
class func defaul tFont () - > U I Font (
return UI Font . preferredFontForTextStyle (UI FontTextStyleBody)
Все довол ьно п росто . Здесь, чтобы п олуч ить п редпочтител ь н ы й пол ь­
зовател ьский шрифт дл я основного текста, испол ьзуется м етод p r e f e r r e d
Font ForTex t S t y l e ( ) класса U I Font . Пол ьзовател ь может испол ьзовать прило­
жение Settings, чтобы измен ить размер дан ного шрифта. С помощью этого мето­
да (вместо жесткого кодирования размера шрифта) м ы делаем наши приложения
более удоб н ы м и для пол ьзователей. Обратите в н и мание на то, как вызывается
этот метод.
l ab e l . f o n t = s e l f . dynam i c T yp e . de f a u l t Fo n t ( )
Метод de f a u l t Fo n t ( ) я вляется методом типа класса C o n t e n t Ce l l . Для
того чтобы вызвать его, должно было бы использоваться имя класса:
C o n t e n t Ce l l . d e f a u l t Fo n t ( )
В дан ном случае это не сработает. Есл и вызов производится от имени под­
класса ContentCe l l (такого, как класс HeaderC e l l, который м ы вскоре созда­
ди м), то на самом деле мы хотим вызвать замеще н н ы й метод defaul t Font ( )
из подкласса. Для того чтобы сделать это, нам нужна ссыл ка на объект подклас­
са. Это именно то, что дает нам выражение s e l f . dynami cType . Если это выра­
жение вы полняется из экземпляра класса ContentCe l l , оно возвращает объект
типа ContentCe l l , и мы будем вызы вать метод de faul t Font ( ) этого класса;
но в подклассе HeaderCe l l оно возвращает объект Heade rCe l l, так что будет
вызы ваться метод d e f a u l t Fo n t ( ) класса HeaderCe l l , а это и менно то, что
нам нужно. Для того чтобы закончить этот класс, реал изуем метод, заготовку
которого добавил и ранее и который в ы числяет подходя щий размер ячейки, как
показано в л исти нге 1 0.3 .
Л истинг 1 0 . 3 . Вычисление п рибл изительного размера ячейки
c l a s i func s i z e Fo r C o n t e n t S t r i n g ( s : S t r i n g ,
f o rMaxW i d t h maxW i dt h : C G F l o a t ) - > CGS i z e
l e t ma x S i z e = CGS i z e ( w i dt h : maxW i dt h , h e i gh t : 1 0 0 0 . 0 )
let opts
N S S t r i n g D r a w i ngOp t i on s . u s e s L i n e F r a gme n t O r i g i n
=
l e t s t y l e = N S M u t aЫ e P a r a g r a p h S t y l e ( )
s t y l e . l i ne B r e a kMode = N S L i n e B r e a kMode . byCha rWrapp i n g
let attributes
[ N S FontAt t r i b u t e Name : de f a u l t Fo n t ( ) ,
N S P a r a g rap h S t y l eAt t r i b u t eName : s t y l e ]
l e t s t ring = s as N S S t r i ng
=
392
ГЛАВА 1 О 'f.· П Р ЕДСТАВ Л Е Н И Е КОЛЛ Е К Ц И И
l e t r e c t = s t r i n g . boundi n g R e c t ( w i t h : ma x S i z e , op t i o n s : op t s ,
a t t r i b u t e s : a t t r i b u t e s , con t e x t : n i l )
return rect . s i ze
Метод, при веде н н ы й в л истин ге 1 0. 3 , делает м ного полезного, так что его
стоит рассмотреть подробнее. С н ачала м ы объя вляем максимальный размер так,
1
что не допускаются слова, которые могут быть ш и ре, чем значение аргум ента
maxWidth, которое получается из ширины U I C o l l e c t i onVi ew. Мы также со­
здаем стил ь абзаца, который п озволяет переносить сл и ш ком бол ьшие строки
текста на следующие строки абзаца. Мы еще создаем словарь атрибутов, ко­
торый содержит о пределенн ы й нами для дан ного класса шрифт по умолчанию
и стил ь абзаца, которы й мы тол ь ко что создал и . Наконец испол ьзуем функции
класса N S S t r i ng, предоставляемого библ иотекой U I K it, который позволяет нам
рассчитать размеры строки . М ы передаем макс и мал ь н ы й размер и другие на­
строенные нами параметры и атрибуты и получаем размер ячей ки.
Осталось правильно задать свойство t e x t . Вместо обы ч ной практи ки, когда
м ы испол ьзуем нея вную переменную экземпляра, определ им get- и sеt- методы,
которые будут извлекать и задавать значение на основе объекта класса U I Labe l,
созданного ранее, испол ьзуя в качестве хранил и ща для отображаемого значения
объект класса U I Labe l . Благодаря этому мы можем также испол ьзовать sеt-ме­
тод для повторного вычисления геометрических размеров ячейки при измене­
нии текста. Замен и м о пределение свойства text в файле ContentCe l l . swi ft
кодом, приведенн ы м в л истин ге 1 0.4.
Л истинг 1 0 . 4 . Определение текстового свойства в файле Cont entCe l l . swi ft
va r l abe l : U I La b e l !
va r t e x t : S t r i n g ! {
get {
r e t u r n l ab e l . t e x t
s e t ( n ewTe x t ) {
labe l . text = newText
va r n e w L a b e l F r ame = l abe l . f r ame
va r n e w C o n t e n t F rame = c o n t e n t V i e w . f rame
let text S i ze
s e l f . dynam i c T yp e . s i z e Fo r C o n t e n t S t r i n g (
s : newTex t ,
f o rMaxW i d t h : maxW i d t h )
newLab e l F r ame . s i z e = t e x t S i z e
n e w C o n t e n t F r ame . s i z e = t e x t S i z e
l a be l . f r ame
newLabe l F r ame
newC o n t e n t F r ame
con t e n t V i e w . f rame
=
=
=
В gеt-методе нет ничего особен ного, но sеt-метод в ы полняет некоторую до­
пол нител ьную работу. В основном он модифицирует рам ку для метки и пред­
ставления содержимого, ориентируясь на размеры, требуемые для вы вода теку­
щей строки.
ГЛАВА 1 О �? П Р ЕДСТАВЛ Е Н И Е КОЛЛ Е К Ц И И
393
Это все, что требуется для базового класса ячейки. Теперь создадим класс ячей­
ки для заголовка. Создайте в среде Xcode еще оди н новый класс на языке Сосоа
Touch, назовите его HeaderCe l l и сделайте его подклассом класса ContentCe l l .
Заголовочный файл трогать н е надо, поэтому перейдите к файлу HeaderCe l l .
swi ft и внесите в него нескол ько измене н и й . В этом классе м ы заместим не­
скол ько методов класса C o n t e n t C e l l для изменения внешнего представления
ячейки, чтобы оно отл ичалось от обычного, как показано в л истин ге 1 0. 5 .
Листинг 1 0 . 5 . К ласс HeaderCe l l
c l a s s H e a d e r Ce l l : C o n t e n t C e l l {
ove r r i d e i n i t ( f r ame : CGRe c t )
s u p e r . i n i t ( f r ame : f r ame )
l a b e l . b a c kgroundCo l o r = U I Co l o r ( r e d : 0 . 9 , g r e e n : 0 . 9 ,
Ы u е : О . В , a l pha : 1 . 0 )
l a b e l . t e x t Co l o r = U I C o l o r . Ы a c k ( )
r e q u i red i n i t ? ( c ode r a De c ode r : N S C ode r ) {
s up e r . i n i t ( c ode r : a De c o de r )
ove r r ide c l a s s f u n c de f a u l t Fo n t ( ) - > U I Fo n t {
r e t u r n U I Font . p r e f e r r e d Fo n t ( f o r T e x t S t y l e : U I Fon t T e x t S t y l e H e a d l i n e )
Теперь ячейка, содержащая заголовок, будет в ы глядеть иначе, потому что у
нее свои цвет и шрифт.
Настройка контроллера п редставления
Выберите файл Vi ewCont r o l l e r . s w i f t и нач н ите с объя вления масси ва
для содержимого, которое м ы собираемся вы водить (л истинг 1 0.6).
Л истинг 1 0 . 6 . Содержимое класса Vi ewCont rol l e r . swi ft
private var sections
[
[ 11 header 11 : 1 1 F i r s t Wi tch 11 ,
11 conten t 11 : 11 Неу , when wi l l the three of us meet up later? 1 1 ] ,
[ " header 11 : 11 Second Wi tch 11 ,
11 content 11 : "When everything ' s s traightened out . 11 ] ,
[ 11 h • ader 11 : " Third Wi tch 11 ,
11 content 11 : " That ' 1 1 Ье j us t Ьefore sunse t . " ] ,
[ " header " : 1 1 Fir s t Wi tch 11 ,
11 content " : "Where? " ] ,
[ " header " : " Second Wi tch 11 ,
" conten t " : " The dirt patch . " ] ,
[ " header 1 1 : " Third Wi tch 11 ,
" conten t " : 1 1 ! gues s we ' 1 1 see Мае there . " ]
=
394
ГЛАВА 1 0 � П Р ЕДСТАВЛ Е Н И Е КОЛ Л Е К Ц И И
Массив s e c t i ons содержит список словарей, каждый из которых имеет два
ключа: heade r и content. Значения, ассоциированные с этим и кл ючам и, будут
использованы для определения содержи мого экрана.
А налогично классу U I T a Ь l eVi ew, класс U I C o l l e c t ionVi ew позволяет заре­
гистрировать класс повторно используемой ячейки, испол ьзуя идентифи катор.
Это позволяет в дал ьнейшем вызвать метод извлечен ия из очереди, в которой
будет находиться ячейка, и, есл и ячейка недоступна, представление коллекции
создаст ее автоматически, как и класс U I TaЬleView. Добавьте следующую стро­
ку в конец метода viewDi dLoad ( ) , чтобы реал изовать эту возможность:
sel f . collectionView? . reqi s ter ( ContentCell . self ,
forCel lWithReuseidentifier : " CONTENT " )
Так как это приложение н е и меет панел и нав и гации, основное представление
будет перекры ваться со строкой состоя н и я . Для того чтобы п редотвратить это
я вление, добавьте следующие строки в конец viewDidLoad ( ) :
var contentinset
collecti onView ! . contentinset
contentinset . top = 2 0
collectionView ! . contentinset
contentinset
=
=
Указан ной конфигурации метода viewDi dLoad ( ) пока достаточ но. Прежде
чем код станет запол нять п редставление коллекци и, необходимо написать не­
бол ьшой вспомогател ь н ы й метод. Все наше содержи мое экрана содержится в
дл и н н ы х строках, а м ы собираемся вы водить слова одно за другим, помещая
их в отдел ьные ячейки . Следовател ьно, нам нужен внутренний метод для раз­
деления строк на слова. Этот метод будет получать номер раздела, извлекать
соответствующие строки из данных указан ного раздела и разделять их на слова.
f u n c w o r d s i n S e c t i o n ( s e c t i o n : I n t ) -> [ S t r i n g ] {
l e t content = s e ct i ons [ s e c t i o n ] [ " conten t " J
l e t s p a c e s = N S C h a r a c t e r S e t . w h i t e s p a c e s AndNew l i n e s
l e t w o r d s = c o n t e n t ? . comp o n e n t s ( s e p a r a t edBy : s p a c e s )
return words !
П редоставление содержимого ячеек
Пришло время для гру п п ы методов, которые будут заполнять представление
коллекции реал ь н ы м и дан н ы м и . Следующие три метода очень похожи на свои
аналоги из класса U I T a Ь l eVi ew. Для начала нам нужен метод, сообщающий
коллекци и, скол ько разделов надо вы вести на экран .
override func numЬerOfSections (in collectionView : UICollectionView) -> Int {
re turn sections . count
Далее при веден метод, сообщающи й коллекци и, с кол ько элементов содер­
жится в каждом разделе. Эту задачу решает метод words I nS e c t i on : , опреде­
лен н ы й ранее.
ГЛАВА 1 0 ;; П Р ЕДСТАВЛ Е Н И Е КОЛЛ Е К Ц И И
395
override func collectionView ( collectionView : UICollectionView ,
_
nwnЬerOfi tems i nSection
section : Int) - > Int {
let words
words i nSection ( section : section)
return words . count
=
В листи нге 1 0. 7 метод возвращает отдельную ячейку, предназначенную для
хранения одного слова. Этот метод испол ьзует метод w o r d s i n S e c t i o n ( ) .
Он применяет метод извлечения из очереди к объекту класса U I C o l l e c t i onVi ew
аналогично классу U I TaЬleView. Поскол ьку мы зарегистрировал и класс ячейки
для идентифи катора, м ы знаем, что м етод извлечения из очереди всегда возвра­
щает экземпляр.
Л истинг 1 0 . 7 . Содержимое класса Vi ewCont ro l l e r . swi ft
ove r r i d e func co l l e c t i o n V i e w ( c o l l e c t i on V i e w : U I C o l l e c t i on V i e w ,
c e l l Fo r i t emAt i ndex P a t h :
I n dex P a t h ) - > U I C o l l e c t i on V i e w C e l l
l e t w o r d s = w o r d s i n S e c t i o n ( s e c t i o n : i ndex P a t h . s e c t i o n )
l e t ce l l
c o l l e c t i on V i e w . d e q u e u e Re u s a Ь l e Ce l l (
w i t hReu s e i de n t i f i e r : " CONTENT " , f o r : i nde x Pa t h ) a s ! C o n t e n t Ce l l
ce l l . maxW i d t h
c o l l e c t i on V i e w . bounds . s i z e . w i d t h
ce l l . t e x t = w o r d s [ i nd e x P a t h . r ow ]
r e t u r n ce l l
=
=
Зная, как работает кл асс U I T a Ь l eVi ew, вы
можете предположить, что в этот момент при­
ложение уже способно что-то делать. С ком п и­
лируйте и запустите приложение, и увидите, что
это не так (рис. 1 0.2).
М ы видим отдел ьные слова, а не поток слов.
Все ячей ки имеют оди наковые размеры, и все
они прижаты одна к другой . Причина заключа­
ется в том , что нам нужно п редпринять меры
для допол нител ьной ответственности делегатов .
meet
up
Ье
Jus\
dlr\
patch.
later?
everythirstraightEOutJ
guess
we'U
Ьefore sunset.>
see
Мае
there.
Создан ие п о т о ка
До сих пор м ы работал и с кл ассом U I C o l ­
l e c t' ionVi ew, но, как уже указ ы валось, у это­
го класса есть ассисте нт, кото р ы й на самом
деле реал изует макет. Класс U I C o l l e c t i o n
ViewF l owLayout, п о умолчанию вы пол няющий
работу по созданию макета для класса U I C o l ­
l e c t i onVi ew, и меет нескол ько методов делега­
та, с помощью которого он выдает нам инфор­
мацию. Оди н из этих методов реал изуем прямо
Рис. 1 0 . 2 . Это в ы гл ядит н е
сл и ш ком работоспособ н ым " .
396
ГЛАВА 1 0 ;r;; П РЕДСТАВ Л Е Н И Е КОЛ Л Е К Ц И И
сейчас . Объект макета применяет этот метод к каждой ячейке, чтобы определ ить
ее требуе м ы й размер. Здесь м ы снова используем метод word s i nSect i on ( ) для
получения доступа к требуемому слову, а затем метод, определенный ранее в
классе Conte ntCe l l и определяющий требуем ы й размер ячейки.
При и н и циал изации U I C o l l e c t i onVi ewCont ro l l e r он становится делега­
том своего класса U I C o l l e c t i onVi ew. U I C o l l e c t i onViewFl owLayout п ред­
ставления коллекци и будет рассм атривать контроллер представления как соб­
стве н н ы й делегат, если он объявит о его соответствии протоколу U I C o l l e c t
i o nVi ewDe l e g a t e F l owLayout . П ервое, что н а м нужно сделать, - это изме­
н ить объя вление нашего контроллера представления в файле Vi ewCont ro l l e r .
swi ft так, чтобы он объя вил о соответств и и этому протоколу:
c l a s s V i e w C o n t r o l l e r : U I Co l l e c t i o nVi e w C o n t r o l l e r ,
UICol lectionViewDelegateFlowLayout {
Все методы п ротокола U I C o l l e c t i onVi ewDe l e g a t e F l owLayout я вляются
необязател ь н ы м и , и нам нужно реал изовать тол ько оди н из н их. Добавьте сле­
дующий метод в файл Vi ewContro l l e r . swi ft (л исти нг 1 0.8).
Л истинг 1 0 . 8 . Изменение размеров ячейки с помощью
п ротокола U I C o l l e c t i onVi ewDe l egat e F l owLayout
func c o l l e c t i on V i e w ( c o l l e c t i o n V i e w : U I C o l l e c t i o n V i e w ,
l a y o u t c o l l e c t i o n V i e w L a y o u t : U I C o l l e c t i on V i e w L a yo u t ,
s i z e Fo r i temAt i ndex P a t h i ndex P a t h : N S i n d e x P a t h ) - > CGS i z e
l e t words
w o r d s i n S e c t i on ( i n de x Pa t h . s e c t i o n )
let s i ze
Con t e n t C e l l . s i z e Fo r C o n t e n t S t r i n g ( w o r d s [ i ndex P a t h . r ow ] ,
f o rMaxWi d t h : c o l l e c t i o n V i e w . b o u n d s . s i z e . w i d t h )
return s i ze
=
=
С компилируйте и запустите п риложение снова, и увидите, что оно стало на­
м ного луч ше (рис. 1 0.3 ).
Теперь ячейки образуют поток и текст стал более удобочитаемым, причем
каждый раздел немного смещен в н из. И все же раздел ы сл и ш ком прижаты один
к другому. Это не сли ш ком крас и во. Исправ и м это, добавив немного параметров
конфигурации. Добавьте следующие строки в конец метода viewDidLoad ( ) :
let l ayout
col lectionView ! . collectionViewLayout
let flow
layout a s ! UICollectionViewFlowLayout
flow . section inset
UIEdgeinsetsмake ( l O , 2 0 , 3 0 , 2 0 )
=
=
=
Здесь м ы извлекаем объект макета и з представления коллекции. Сначала присва­
и ваем его временной переменной, тип которой вы водится как указател ь на объект
класса UICo l lect ionViewLayout. М ы делаем это в основном для того, чтобы под­
черкнуть, что только этот объект знает о существовании обобщенного класса макета,
но в действительности он использует экземпляр класса UICol lectionFlowLayout,
который я вляется подклассом класса UICol l e c t i onVi ewLayout. Зная истинный
ГЛАВА 1 0 >: П Р ЕДСТАВЛ Е Н И Е КОЛЛ Е К Ц И И
397
тип объекта макета, м ы можем использовать операторы приведения типа для при­
своения его другой переменной корректного типа и для доступа к методам, кото­
рые содержатся тол ько в этом подклассе, - в данном случае нам нужен sеt-метод
для свойства sectioninset. Еще раз скомпилируйте и выпол ните приложение, и
увидите, что ячейки более равномерно заполняют пространство (рис. 1 0.4).
Carrier •
IP hone 6s - iOS 10.О (14А6297с)
еу, when will
later?
7:29 АМ
the th ree
of
us
hen everythi"9'S straightened out.
at'll ье just ьеtоге sunset.
еге?
he dirt pateh.
guess we'll see Мае there.
--
Ciirrler 'f"
Неу,
1Phon11 � - IOJI 10.0 (14A5297cl
when
up later?
7:38 АМ
-
wili the three of us meet
When eveiYthJng's straightened out.
That'll
Ье just before sunset.
Where?
The dirt patch.
1 gu es s we'fi see мае there.
Рис . 1 0 . 3 . Те п е р ь абзацы в ы ­
Рис . 1 0. 4 . Стало куда своб одн ее
дел я ются
Представления заголовка
Осталось вы вести на экран объекты заголовков. Класс U I T aЬ l eV i ew и меет
представления для заголовков и сносок. Их можно было бы испол ьзовать для
вы вода каждого раздела. Класс U I C o l l e c t i onVi ew испол ьзует эту кон цепцию
в нескол ько более обобщенном виде, обеспечи вая бол ьшую гибкость макета.
Наряду с системой доступа к об ы ч н ы м ячейкам из делегатов существует па­
раллел ьная систе ма для доступа к допол н ител ь н ы м п редставлен и я м , которые
можно испол ьзовать для заголовков, с носок и других элементов. Добавьте сле­
дующи й код в конец метода viewDi dLoad ( ) , чтобы представление коллекци и
знало о существовании класса я чеек для заголовка:
398
ГЛАВА 1 О а П Р ЕДСТАВЛ Е Н И Е КОЛ Л Е К Ц И И
sel f . col lectionView? . regi s ter ( HeaderCel l . self ,
forSupplementaryViewOfKind : UICollectionE lementкindSectionHeader ,
wi thReuseidentifier : " НEADER" )
Как в идим, в данном случае м ы не тол ько указы ваем класс ячейки и ее иден­
тификатор, но и вид. Идея заключается в том, что разные макеты могут опреде­
лять разные виды допол нител ьных представлений и запраш ивать эти представ­
ления у делегатов. Класс U I C o l l e c t i o n F l owLayout будет запраш ивать раздел
заголовка для каждого раздела представления коллекци и (листи нг 1 0.9).
Листи н г 1 0 . 9 . Раздел представления коллекции
ove r r i de f u n c c o l l e c t i o n V i e w ( _ c o l l e c t i on V i e w : U I C o l l e c t i o n V i e w ,
v i e w Fo r S up p l eme n t a r y E l eme n t O f K i nd k i n d : S t r i n g ,
a t i nde x P a t h : I nd e x P a t h ) - >
U I Co l l e c t i on Re u s aЬ l e V i e w {
i f ( kind
U I C o l l e c t i o n E l eme n t K i n dS e c t i o n H e a de r ) {
l e t ce l l =
c o l l e c t i o n V i e w . d e q u e u e Re u s a Ы e S up p l eme n t a r yVi e w (
o f K i n d : k i n d , w i t hRe u s e i de n t i f i e r : " HEADER " ,
f o r : i nd e x P a t h ) a s ! H e a d e r C e l l
ce l l . ma x W i d t h
c o l l e c t i on V i e w . b o u n d s . s i z e . w i d t h
ce l l . t e x t = s e c t i o n s [ i nd e x P a t h . s e c t i o n ] [ " h e a de r " J
r e t u r n ce l l
==
=
abo r t ( )
Обратите вни мание на вызов abort ( ) в кон це дан ного метода. Эта фун кция
заставляет приложение немедленно п рекратить работу. Это не та вещь, к кото­
рой следует часто п рибегать в рабочем коде. Здесь м ы ожидаем тол ько вызова
для создан ия ячейки заголовка и ничего не сможем сделать, есл и будет запро­
шен другой вид ячеек, - мы даже не сможем вернуть n i l, потому что возвра­
щаем ы й тип метода это не допускает. Есл и этот метод вызван для создания
другой разновидности заголовка, то это серьезная ошибка нашей програм м ы
ил и ошибка в библ иотеке U I Kit.
С ком п ил и руйте и вы пол ните приложен ие, и увидите " . постойте ! А где же
заголовки? Оказывается, класс U I Co l l e c t i on F l owLayout не выделяет для них
места, есл и ему точно не указать их размер ы . Вернемся к методу viewDidLoad ( )
и добавим в него следующую строку :
flow . headerReferenceSize
=
CGSi ze ( width : 1 0 0 , height : 2 5 )
С нова скомп илируйте и выпол н ите приложен ие, и теперь все заголовки ока­
жутся на своих местах, как показано на рис. 1 0. 1 и 1 0. 5 .
ГЛАВА 10 >" П Р ЕДСТАВ Л Е Н И Е КОЛЛ Е К Ц И И
IP hone � � юs 1 м \14A5297cl
8:02 АМ
will
399
-
the three of us meet
ond Witch
When everything's straightened oUt.
That'll Ье just before sunset.
Flrst Witch
Where?
1 guess we'll see Мае there.
Рис . 1 0 . 5 . О к о н ч ател ь н ы й вид
п р иложе н и я D i a logVi ewe r
Р ез ю ме
В этой главе мы тол ько слегка коснулись класса U I C o l l e c t i onView и того,
что может быть достигнуто с помощью класса по умолчанию U I C o l l e c t i on
F l owLayou t . С его помощью путем оп ределения собственных кл ассов маке­
тов можно получ ить еще более крас и вые приложения, но это тема для другой
книги.
Рассматри вая приложения, созданные с помощью представлен и й коллекций,
следует не забы вать о представлениях стека. Эта ал ьтернативная возможность
может, сэконом ить вре м я . Поскол ьку по мере поя вления новых верс и й языка
Swift, среды Xcode и iOS книга становится все больше и бол ьше, представления
стека м ы оставляем читателю в качестве упражнения .
ГЛ АВА 1 1
• •
Раз де л енные п ре дст а в л ения
и в сп л ы в а ющие м еню
В главе 9 м ы удел ил и м ного в н и мания нави гации приложений, основанной
на выбран ных элементах в табл и ч н ы х представлениях, где выбор каждого эле­
мента вызы вает представление верхнего уровня, которое запол няет весь экран
с перемещением влево и отображением следующего в иерархии представления,
возможно, уже из другой табл и цы . Так работают м ногие прил ожения для уст­
ройств i P/юne и i Pod touch, например приложе н ие Mai/, которое позвол яет вам
пробираться через учетн ые зап иси и папки до тех пор, пока вы, наконец, не
найдете сообщение. Несмотря на то что этот метод работы подходит и для уст­
ройства i Pad, он может затруднить взаи модействие с пол ьзователем .
Размеры экранов i Phone и i Pod touch позволяют плавно заменять одно пол но­
экран ное представление други м . На устройстве i Pad аналогичная операция вы­
пол няется менее гладко, а иногда даже становится совершенно неприемлемой.
Кроме того, в больши нстве случаев использован ие такого бол ьшого дисплея для
одного таблич ного представления неэффекти вно. По этой причине во встроен­
ные i Раd-приложения заложено совсем другое поведение. Л юбые нави гационные
действия, подобные тем, которые испол ьзуются в приложении Mai l, низводятся
до испол ьзования одного узкого столбца, содержимое которого смещается влево
ил и вп раво по мере того, как пол ьзовател ь погружается вглубь своих изыска­
ний ил и "выныривает" назад. При использован ии устройства i Pad в ал ьбом ном
режиме навигационный столбец фиксируется слева, а содержимое выбран ного
элемента отображается справа. Это называется разделен н ы м п редставлением
(split v iew) (рис. 1 1 . 1 ), а приложения, создан ные таки м образом, именуются при­
ложения м и master-detai l (master-detai l app lication - главное п редставление детал изирован ное представление).
Разделенное представление идеал ьно подходит для разработки таких прило­
жен и й master-detail, как Mai l . До появления версии iOS 8 класс разделенного
представления U I Sp l i tVi ewC ont ro l l e r был доступен тол ь ко на i Pad, а это
402
ГЛАВА 1 1 "' РАЗДЕЛ Е Н Н Ы Е П Р ЕДСТАВ Л Е Н И Я И ВСПЛ Ы ВАЮ ЩИ Е М Е Н Ю
означает, что есл и бы вы захотел и построить универсальное приложен ие master­
detail, вам при шлось бы делать это одн и м способом на i Pad и другим - на
i Phone. Теперь же класс U I Sp l i tV i e w C o n t ro l l e r доступен везде, т.е. вам
больше не нужно п исать специал ьн ы й код для работы с устройством iPhone .
." .
--
ма�tЬохеs
Edit
Ба All lпboxes
9 Yahoo!
*
ф
VIP
ACCOUNTS
11 Gmal
1:1
С1
r
1
i
1
1
Yahoo!
No M essage Se lected
--
Рис. 1 1 . 1 .
•.,.., 8) • 1
8:6t PM
--
---
___
•
j_
П р и м е р раздел ен н о го п редставл е н и я в альбо м н о м реж и м е на эк­
ране i Pad . Стол бе ц н а в и гаци и распол ожен сл ева . В ы б е рите в н е м эл емент, в
да н н о м случае - конкретную уч етную з а п и с ь почты , и содержи мое этого эле ­
м е нта отобразится в области сп рава
При испол ьзовании iPad ширина левой области разделенного представления со­
ставляет по умолчан ию 320 точек, а само разделенное представление со смежными
областям и навигации и содержания обычно работает тол ько в альбомном режиме.
Если переключить устройство в книжную ориентацию, разделенное представление,
не теряя фун кциональных возможностей, переходит в неявную форму. Область на­
вигации становится плавающей и может быть акти визирована тол ько нажатием
кнопки панел и и нструментов, которое заставит область навигации "вспл ыть" и
отобразиться поверх всего остального изображения на экране (рис. 1 1 .2).
Однако некоторые приложения не следуют строго этому правилу. Приложение
Setti11gs для устройства i Pad, напри мер, испол ьзует разделенное представление,
которое видимо все время, и его левая часть н и когда не исчезает и не перекры­
вает представление содержи мого справа. Но в этой главе м ы будем придержи­
ваться шаблона стандартного использования разделенного представления .
ГЛАВА 1 1 '<'t РАЗДЕЛ Е Н Н Ы Е П РЕДСТАВЛ Е Н И Я И В С П Л Ы ВАЮ Щ И Е М Е Н Ю
-
403
•
' ! " .,,._
а­
о -·
Рис . 1 1 . 2 . Раздел е н н ое п редставл е н и е на экране i Pad в
к н и ж н о й о р и е нтаци и . И н фо р м а ц и я из л е в о й ч асти п р еж­
н е го раздел е н н ого п редста вл е н и я в альбо м н о м режи м е
п о я вл я ется , тол ько когда пол ьзовател ь в ы пол н я ет жест
скол ьже н и я или нажи м ает к н о п ку на панели и н струменто в
На примере проекта в дан ной главе в ы увидите, как создать приложение
master-detail, которое испол ьзует контроллер разделенного п редставления . Пер­
воначально мы будем тестировать приложения на симуляторе i Pad, но когда оно
будет закончено, вы увидите, что тот же код работает и на устройстве i Phone,
хотя выглядит при этом иначе. Вы также узнаете, как настраивать внешний вид
и поведение разделенного представления и как создавать и вы водить вспл ы ва­
ющие меню (popover), как те, которые в ы в идели в главе 4, когда мы рассмат­
ривали представления предупреждений и списки действи й . В отличие от вспл ы­
вающего меню на рис. 4.28, которое служит "оберткой" для с писка действий, в
данном случае вспл ы вающее меню будет иметь содержи мое, специфичное для
дан ного примера приложения, в частности - список языков (рис. 1 1 .3 ).
П ост роен ие прил ожения master-detai l
с помощь ю кл асса U I SplitViewController
Начнем с простой задач и и воспользуемся п реимуществами одного и з предоп­
ределенных в програм ме Xcode шаблонов для создания нашего проекта. Наша
цел ь - написать приложен ие, которое перечисл яет всех президентов С Ш А и
показы вает статью из Википедии о выбранном президенте.
404
ГЛАВА 1 1 � РАЗДЕЛ ЕН Н Ы Е П РЕДСТАВЛ Е Н И Я И ВСПЛ Ы ВАЮ ЩИ Е М Е Н Ю
Oeorgt Wathlngton
John Adam1
Тhoma1 Jefforeon
J•met Medl1on
Jame1 Monroe
John Qulncy Adam1
1
=
Abraham Lincoln
-
-
Andrtw Jackaon
•
Mart"1 V1n Вuren
Willl•m Нonry Harrtton
John Тyler
Jamн K. Polk
Zachмy Tay1or
Mlllard FШmort
Franklln pterce
Jamet Buch1nan
1tttl ........,. "
.... l.Jlllhd .....
Maroh "4, lll&t . Apr\1 15. 18!!S
� � н.п.il.)IOIH...."1 418f1.itll!ф
�--
J
Рис . 1 1 . З . В с п л ы вающее м е н ю , в и зуал ь н о в ы глядя щее как
растущее и з кноп ки , которая его а кти в и з и рует
Перейдите в среду Xcode и выпол н ите команду F i l e c:> Newc:> Project . " . В разде­
ле IOS Appl ication выберите вариант Master- Deta i l Appl ication и щел кн ите на кноп­
ке N ext. На следующей стран и це э крана назовите новый проект P re s ident s,
выберите пункт Swift в списке Lang uage и пункт U n iversa l в списке Devices . Убе­
дитесь, что все флажки сброшен ы . Щел кн ите на кнопке N ext, выберите место
хранения своего проекта и щел кн ите на кнопке C reate. С реда Xcode сделает
свою обы ч ную работу, создав вместо вас классы и файл раскадровки, а затем
покажет п роект. Рас кройте папку P re s i de n t s и рассм отрите ее содержи мое.
Изначально нов ы й проект содержит класс делегата приложения (как обычно),
классы Ma s t e rVi ewC ont ro l l e r и De t a i lViewC o n t ro l l e r . Эти два контрол­
лера обеспечивают представления, которые будут отображаться соответственно
в левой и правой частях разделенного представления в ал ьбом ной ориентации .
Класс Ma s t e rVi ewC o n t r o l l e r определяет верх н и й урове н ь нави гационной
структуры, а класс De t a i lV i ewCont ro l l e r задает, что именно отображается в
бол ьшей области экрана п р и выборе элемента нав и гаци и . При запуске приложе­
ния оба контроллера содержатся в разделенном п редставлении, которое, как вы
пом н ите, выполняет небол ьшую трансформацию при вращении устройства.
Для того чтобы понять, какие функции п редоставляет этот кон кретны й шаб­
лон приложения, ском понуем его и выпол н и м в симуляторе i Pad. При запус ке
приложения в кн ижной ориентации вы увидите тол ько контроллер детал изи­
рованного представления (рис. 1 1 .4, слева). Нажатие на кнопку M aster панел и
инструментов ил и жест слева направо от левого края экрана при водит к появ­
лению контроллера главного представления поверх контроллера детал изирован­
ного представления (рис. 1 1 .4, справа).
ГЛАВА 1 1 •• РАЗДЕЛ ЕН Н Ы Е П Р ЕДСТАВЛ Е Н И Я И ВСПЛ Ы ВАЮЩИ Е М Е Н Ю
405
.....
, _ _ _ _.
Рис . 1 1 . 4 . П о веде н и е по умол ч а н и ю п р иложе н и я maste r - d etai l в кн и жн о й
ори ентаци и . Раз м е ще н и е сп рава подоб н о п р и веде н н о м у н а ри с . 1 1 . 2
Поверн ите симулятор влево или вправо в альбом ный режи м . При этом
разделенное представление показывает п редставление н авигации слева и
детализирован ное представление справа (рис. 1 1 .5).
IPad Air - iOS 1�·0 (14А5297с)
а. .а ш
Ed.1
+
--
Рис . 1 1 . 5 . П о веде н и е по умол ч а н и ю п ри л оже н и я maste r - deta i l в ал ьбом ­
ной ориентаци и . Раз м е ще н и е сп рава подобно п р и веде н ному на р и с . 1 1 . 1
406
ГЛАВА 1 1 � РАЗДЕЛ Е Н Н Ы Е П Р ЕДСТАВЛ Е Н И Я И В С ПЛ Ы ВАЮ Щ И Е М Е Н Ю
Определение структуры с помощью раскадровки
Итак, у вас действует довольно сложный набор контроллеров представлений.
':�
,\'
Wi:
!�"
,\),
Контроллер разделенного представления, который содержит все элементы .
Контроллер навигаци и для обработки действи й в левой области .
Контроллер главного представления (вы водит главн ы й сп исок элем е нтов)
в контроллере навигаци и .
Контроллер детал изированного представления в правой области .
Контроллер навигации, и грающи й рол ь контейнера для детал изирован ного
представления в правой области .
В стандартном шаблоне приложения master-detail, которы й м ы испол ьзовал и,
эти контроллеры п редставления устанавл и ваются и связы ваются между собой в
основном файле раскадровки, а не в коде. Редактор и нтерфейса l пterface Bui lder
не тол ько предоставляет инструментари й для быстрого построения графическо­
го и нтерфейса пол ьзователя, но и позволяет связы вать различные ком поненты
без нап исан ия кода. Для того чтобы понять, как это п роисходит, необходимо
подробнее рассмотреть файл раскадровки нашего проекта.
Выберите файл Ma i n . s t o ryboa rd, чтобы открыть его в програм ме l nterface
Bui lder. Этот файл раскадровки содержит множество элементов. Для того что­
бы достичь наилу ч ш и х резул ьтатов, следует открыть окно Document Outl ine
(рис. 1 1 .6). Уменьшение масштаба (щел ч ком правой кнопки мыши в редакторе
раскадровки и выбором вел и ч и н ы увел и чения во вспл ы вающем меню) также
может помочь вам увидеть общую картину.
Для того чтобы луч ше разобраться во взаи моотношениях контроллеров, от­
кройте и нспектор связей и удел ите некоторое время изучению контроллеров
представлений, щел кая на каждом из н их, чтобы понять, как они взаи мосвяза­
н ы . Н иже кратко описано то, что вы увидите.
�
Объект класса U I S p l i t V i e w C o n t r o l l e r и м еет отношения переходов
(segues) к двум контроллерам класса U INavi gat ionCont ro l l ers
конт­
роллерам главного и детализированного п редставлени й . Они испол ьзу­
ются для того, чтобы указать объекту класса U I Sp l i tVi ewControl l e r,
что именно он должен испол ьзовать для узкой полосы в левой части (кон­
троллер главного п редставления) и что должно находиться в бол ьшей об­
ласти отображения (контроллер детал изирован ного представления).
-
? r.
Объект класса U I Navi g a t i onCon t ro l l e r, с вязан н ы й переходом с конт­
роллером главного п редставлен и я , имеет отношение контроллера кор­
невого п редставлен и я со своим контроллером корневого представления,
котор ы й я вляется объектом класса Ma s t e rVi ewCont r o l l e r, сгенериро­
ванн ы м шаблоном . Контроллер главного представления я вляется подклас­
сом U I TaЬleVi ewCont ro l l e r, с которы м вы ознаком ились в главе 9 .
ГЛАВА 1 1 � РАЗДЕЛ ЕН Н Ы Е П Р ЕДСТАВЛ Е Н И Я И ВСПЛ Ы ВАЮ ЩИ Е М Е Н Ю
"
8
А ,...•.. . ... ,,,
.._.... � " ... ...
.....
м.... -......., �)
• D ми••k-
.
!I Sllllil Vllow � S-
.,, -..C Vllw Co<>lf'lllllr
-.
...�
. ,.." �'
· ·�
• eJ lfl! vi... c-... 11.-.
,.. __
·-­
· ·�
.
407
1
--
-; -1 -
о • •
_"_
1
'
--
-·�
----
....... OW"8t�
- -...... - �
"..."
. .". ..__
о
о
о
о
о
о
о
о
о
о
о
о
о
о
. ...
._. c:NI" ..... -� .
• 8 ........,, с_..._ ._,..
� < ,......_. �,....
. "" �
11 ••
� ·- - --
[) () @ о
....,.tl.. Ы- · - ·
� .... . .- � " "
" ......а ...,....
GJ
•
оа
-
...
+
B ICН l11o\ I
<
��··
(-.... - � -..­
,,......,. . '-'"'""' _ _
Рис . 1 1 . 6 . Файл Ma i n S t o r yboa rd . s t o rybo a r d, открытый в п рограм м е l nterface
B u i l d e r. Эта сложная и е рархия объектов луч ш е всего видна в о к н е Document
Outl i n e
�.
Аналогично другой объект класса U I Navi g a t i onCont ro l l e r и меет от­
ношение контроллера корневого представления с контроллером детали­
зи рованного п редставлен и я , который я вляется объектом класса шаблона
De t a i l VI ewCon t ro l l e r . Контроллер детализирован ного представления,
сгенерирован н ы й шаблоном, я вляется обы ч н ы м объектом подкласса клас­
са U IVi ewCont ro l l e r, но вы вправе испол ьзовать здесь л юбой контрол­
лер представления, который отвечает требован иям вашего приложения .
Существует переход раскадровки из ячеек контроллера главного представ­
ления к контроллеру детал изирован ного п редставления типа showDeta i l .
Этот переход при водит к вы воду элемента из ячейки в детал изированном
представлен ии, на которой пол ьзовател ь щел кнул м ышью. Больше об этом
вы узнаете позже, когда м ы будем подробно рассм атри вать контроллер
' главного представления.
В дан н ы й момент файл Ma i n . s t oryboa rd содержит определение того, как
взаи мосвязан ы различ ные контроллеры приложения . Как и в бол ьшинстве слу­
чаев, испол ьзование раскадровок позволяет обойтись без написания объем ного
кода, что само по себе приятно. По желанию можете изучить все аспекты кон­
фигурации в коде, но, что касается данного примера, мы ограни ч и мся л и ш ь
теми строкам и кода, которые был и предоставлены средой Xcode.
408
ГЛАВА 1 1 '!:' РАЗДЕЛ Е Н Н Ы Е П РЕДСТА ВЛ Е Н И Я И В С П Л Ы ВАЮЩИ Е М Е Н Ю
Определение функциональной возможности в коде
Одна из основных причин хранить взаимосвязи контроллеров представлен и й
в раскадров ке состоит в том, что он н е перегружает наш исходны й код данны­
м и о конфигурации, которые ему не нужны . Следовател ьно, в коде м ы должны
определ ить толь ко реал ьную фун кциональную возможность. Итак, расс мотрим,
что у нас есть на данн ы й момент. Среда Xcode при создании проекта о п реде­
л ила для нас несколько классов, и м ы , прежде чем вносить в них какие-л ибо
изменения, побл иже познаком имся с кажды м из них.
Делегат приложения
Начнем с рассмотрения файла делегата приложения AppDe l e g a t e . swi ft,
который в ы глядит так, как показано в л исти нге 1 1 . 1 .
Листинг 1 1 . 1 . Файл AppDe l e gat e . swi ft
i mp o r t U I K i t
@ U I App l i c a t i onMa i n
c l a s s App De l e g a t e : U I Re s p onde r , U I App l i c a t i o n De l e g a t e ,
U I S p l i tV i e w C o n t r o l l e r De l e g a t e
v a r w i ndow : U I W i ndow ?
f u n c a pp l i c a t i o n ( _ appl i c a t i o n : U I App l i ca t i on ,
d i d Fi n i s h La u n c h i n gW i t hOp t i on s
l a un c h Op t i o n s : [ N S O b j e c t : An yOb j e c t ] ? ) - > B o o l
1 1 Точ ка з амеще н и я дл я на стройки п о сл е з а груз ки пре дс т а в л е н и я .
l e t s p l i t V i e w C o n t r o l l e r = s e l f . w i ndow ! . ro o t V i ewCo n t r o l l e r a s !
U I S p l i tV i e wC o n t r o l l e r
l e t navi g a t i o n C on t r o l l e r = s p l i tV i e w C o n t r o l l e r . vi ewCo n t r o l l e r s [ s p l i t V i
ewCon t r o l l e r .
v i ewCo n t r o l l e r s . c o u n t - 1 ] a s ! U I Nav i g a t i on C on t r o l l e r
n a vi g a t i on C o n t r o l l e r . t opV i ewCon t r o l l e r ! . n a v i g a t i o n i t em .
l e f t B a r B u t t o n i t em =
s p l i tV i ewCo n t r o l l e r . d i s p l a yMode B u t t o n i tem ( )
s p l i t V i ewCo n t r o l l e r . d e l e g a t e = s e l f
return t rue
Рассмотри м сначала последнюю часть этого кода:
s p l i tV i ewC o n t r o l l e r . de l e g a t e = s e l f
Эта строка настраивает свойство de legate класса U I Sp l i tViewContro l ler,
которое в резул ьтате указы вает на самого себя . Почему м ы создал и это соеди­
нение в коде, а не прямо в раскадровке? В едь совсем недавно мы говорили об
исключении утомительного кодирования ("соедин ите это с тем") - одном из ре­
ал ьных преимуществ Х I В-файлов и раскадровок. М ы много раз видели, как деле­
гаты включаются в I nterface Bнi lder, так почему же не можем сделать это сейчас?
ГЛАВА 1 1 11 РАЗДЕЛ Е Н Н Ы Е П Р ЕДСТА ВЛ Е Н И Я И В С ПЛ Ы ВАЮ Щ И Е М Е Н Ю
409
Для того чтобы понять, почему механизм раскадровок для создания соедине­
ний не может сработать в данной с итуации, надо вспом н ить, чем раскадровка
отличается от Х I В-файла. Х I В-файл - это, по существу, "замороженный" граф
объектов. Когда мы погружаем Х I В-файл в работающее приложен ие, объекты,
которые он содержит, "оттаивают" и "оживают". Это относится и ко всем взаи­
мосвязя м, определен н ы м в файле. С и стема создает новые экзе м пляры каждого
отдел ьного объекта в файле, оди н за другим, и связы вает все в ы ходы и под­
ключения между объектам и . В то же время раскадровка - это нечто бол ьшее.
Можно сказать, что каждая сцена в раскадров ке примерно соответствует Х I В­
файлу. Добавляя в метаданные оп исание того, как сцены связы ваются одна с
другой посредством переходов, вы и меете дело с раскадров кой. Однако в отл и­
чие от оди ноч ного Х I В-файла, сложная раскадровка обычно не загружается вся
сразу. В место этого каждое действие, которое вызывает новую сцену, приводит
к загрузке из раскадровки кон кретного "замороженного" графа объектов, соот­
ветствующего этой сцене. Это означает, что все объекты, которые вы видите в
раскадровке, необязател ьно существуют одновременно.
Поскол ьку программа l nterface Bui lder н ичего не знает о взаимосвязях между
сценам и, она фактически запрещает создавать л юбые выходы или соединения
"цел ь/действие" от объекта в одной сцене к объекту в другой сцене. Фактически
еди нственными разрешенн ы м и связя м и между сценами я вляются переход ы .
Можете попробовать сам и . С начала выберите в раскадров ке элемент Split View
Controller (вы найдете е го в окне Document Outline в разделе Split View Control­
ler Scene). В ызовите и нспектор связей и попробуйте перетащить соединение от
выхода делегата к другому контроллеру представления или объекту. В ы можете
перетас ки вать все в п ределах области макетировани я и представления сп иска
и не найдете н и одной подсказки, которая у каз ы вал а бы на то, что в данном
месте объект можно отпустить. Еди нствен н ы й способ создать такое соедине­
ние - нап исать соответствующи й код. Эти небол ь ш ие допол нител ьные фраг­
менты кода - не сл и ш ком бол ьшая цена, учиты вая, скол ько кода устраняется
из-за нашего испол ьзован ия раскадровок.
Давайте вернемся к началу и посмотрим, что происходит в начале метода а
ppl i c a t i on ( : d i d F i n i s hLaunch i n gWi thOp t i o n s : ) :
l e t s p l i t V i ewCont r o l l e r
s e l f . w i ndow ! . r o o t V i ew C on t r o l l e r a s U I S p l i t V i ewCo n t r o l l e r
=
Эта' инструкция позволяет нам получить свойство окна rootVi ewCont ro l le r,
которое указы вается в рас кадровке плавающей стрел ко й . Есл и вернуться к
рис. 1 1 .6, вы увидите, что стрел ка у казы вает на наш э кзе м пляр класса U I S p l i t
ViewCont ro l l e r . Далее идет код
l e t navi ga t i o n C o n t ro l l e r = s p l i t V i ewCon t r o l l e r . v i ewCo n t r o l l e r s [
s p l i t V i ewC o n t r o l l e r . v i ewCon t ro l l e r s . c o u n t - 1 ]
a s U I N av i g a t i o n C o n t r o l l e r
410
ГЛАВА 1 1 111 РАЗДЕЛ Е Н Н Ы Е П Р ЕДСТАВЛ Е Н И Я И В С ПЛ Ы ВАЮ Щ И Е М Е Н Ю
В этой строке м ы "погружаемся" в массив vi ewCont ro l l e r s объектов клас­
са U I S p l i tViewCont rol l e r . Когда разделенное представление загружается из
раскадровки, этот масси в содержит ссыл ки на контроллеры навигации, оберну­
тые вокруг контроллеров главного и детал изированного представлений. Мы по­
лучаем последни й элемент в этом масси ве, которы й указы вает на объект класса
U I Navi g a t i onContro l l e r для нашего детал изирован ного представления. На­
конец мы видим следующий код:
navi g a t i onCon t ro l l e r . topViewCon t ro l l e r . n a v i g a t i on i t em . l e f t Ba rBut t o n i tem
s p l i tV i ewCon t r o l l e r . d i s p l a yMode B u t t o n i t em ( )
=
Он присваивает с войство d i s p l a yModeBu t t o n i t em контроллера разделен­
ного представления навигационной панел и контроллера детал изированного
представления . С войство d i s p l a yModeBut t on i t em представляет собой кнопку
полосы, которая создается и управляется сам и м разделенн ы м п редставлением .
Этот код фактически я вляется добавлением кнопки Master, которую вы видел и
на панел и навигации на рис. 1 1 .4, слева. В устройстве i Pad разделен ное пред­
ставление показы вает эту кнопку, когда устройство находится в кн ижной ориен­
таци и, и контроллер главного п редставления не виден. Когда устройство пово­
рачи вается в ал ьбом ную ориентацию ил и пользовател ь нажимает кнопку, чтобы
сделать види м ы м контроллер главного представлен ия, кнопка скры вается .
Ко нтр оллер главн о го представления
Рассмотри м кл асс Ma s t e rViewCont ro l l e r, управляющий настройкой таб­
л и чного представления, содержащего панел ь навигаци и приложения. Вот как
в ы гл ядит код в начале файла Ma s t e rVi ewCont ro l l e r . s w i f t (листи нг 1 1 .2).
Л истинг 1 1 . 2 . Файл Ma s t e rVi ewCont r o l l e r . s w i f t
imp o r t U I K i t
c l a s s Ma s t e rVi ewCo n t r o l l e r : U I T a Ь l e V i e w C o n t r o l l e r {
va r de t a i l V i ewCon t r o l l e r : De t a i l Vi e wCo n t r o l l e r ?
var obj ects
[ An yObj e c t ] ( )
nil
=
ove r r ide f u n c v i e w D i dLoad ( )
s upe r . v i e w D i dL o a d ( )
1 1 Дополнител ь н а я н а с тройка после з а грузки п р е д с т а в л е ни я ,
1 1 о быч но и з n i Ь - файла .
s e l f . navi g a t i o n i t em . l e f t B a r B u t t o n i tem = s e l f . e d i t B u t t o n i t em ( )
l e t addBu t t o n
U I B a r B u t t o n i tem ( b a r B u t t on S y s t em i t em : . a dd ,
t a r g e t : s e l f , a c t i o n : # s e l e c t o r ( i n s e r t NewOb j e c t ( : ) ) )
s e l f . n a v i g a t i o n i t e m . r i g h t B a r B u t t o n i tem
addB u t t o n
if let spl i t
s e l f . s p l i tV i e w C o n t r o l l e r {
l e t co n t r o l l e r s
s p l i t . v i ewCo n t r o l l e r s
s e l f . d e t a i l Vi ewCon t r o l l e r
( co n t r o l l e r s [ co n t r o l l e r s . c oun t - 1 ] a s !
U I N avi g a t i onCont r o l l e r ) . t opV i ewCon t r o l l e r a s ? De t a i l V i e wCon t r o l l e r
=
=
=
=
=
ГЛАВА 1 1 u РАЗДЕЛ Е Н Н Ы Е П Р ЕДСТА ВЛ Е Н И Я И В С ПЛ Ы ВАЮ ЩИ Е М Е Н Ю
41 1
Основной и нтерес здесь п редставляет метод v i e w D i dLoad ( ) . В п редыду­
щих главах при реал изации контроллеров табл и чного представления, которые
реагируют на выбор пол ьзователем строки в табли це, на этом этапе вы обычно
создавал и новый контроллер представления и помещали его в стек контроллера
навигации . В дан ном приложе н и и контроллер приложения, которы й мы хотим
отобразить, уже существует: это э кзе м пляр класса De t a i l Vi ewCont rol l e r, со­
держащийся в файле раскадровки. Поэтому здесь м ы получаем экзе м пляр клас­
са Deta i l ViewCont r o l l e r и сохраняем его в виде с войства, так как планируем
использовать его позже. Однако в оставшейся части шаблонного кода это свойс­
тво не используется .
Метод viewDi dLoad ( ) также добавляет кнопку на панел ь инструментов. Это
кнопка +, которая показана в правой части панел и навигации контроллера глав­
ного представления на рис. 1 1 .4 и 1 1 . 5 . Шаблонное приложение использует эту
кнопку для создания и добавления новой записи к табл и чному представлению
контроллера главного представления. Поскольку в нашем "президентском" при­
ложении эта кнопка не нужна, этот код вскоре будет удален.
Имеется еще нескол ько методов, в кл юч е н н ы х в шаблон для этого класса,
но не будем беспокоиться о них сейчас. М ы собираемся удалить одн и из них
и переписать другие, но тол ько после того, как познаком и мся с контроллером
детал изированного представления.
Контроллер детализированного представления
Последн и м классом, создан н ы м дл я нас средой Xcode, я вляется класс
De t a i l Vi ewCon t ro l l e r, который отвечает за отображение элемента, выбран­
ного пол ьзователем . При ведем содержи мое файла D e t a i lVi ewCont r o l l e r .
swi ft (л истинг 1 1 .3 ) .
Л истинг 1 1 . З . Файл Det a i l Vi ewCont ro l l e r . s w i f t
imp o r t U I K i t
c l a s s D e t a i l Vi ewCo n t r o l l e r : U I V i e w C o n t r o l l e r {
@ I BOut l e t w e a k va r de t a i l De s c r i p t i o n L a b e l : U I L a b e l !
f u n c con f i g u r e V i e w ( ) {
1 1 Обновление пол ь з о в а т ел ь с ко г о интерфейса
11 дл я элеме нта де тализир о в а н н о г о пре дс т а в л е н и я
i f l e t de t a i l = s e l f . d e t a i l i t em {
i f l e t l ab e l = s e l f . de t a i l De s c r i p t i o n L a b e l
l a b e l . t e x t = de t a i l . de s c r i p t i o n
ove r r ide f u n c v i e w D i dLoad ( ) {
s upe r . v i e w D i dLoad ( )
1 1 Дополни т е л ь н а я н а с тройка после з а груз ки предс т а в л е ни я ,
1 1 обыч н о и з n i Ь - файл а .
s e l f . con f i g u r e V i e w ( )
41 2
ГЛАВА 1 1 ill РАЗДЕЛ ЕН Н Ы Е П РЕДСТАВЛ Е Н И Я И В С ПЛ Ы ВА Ю Щ И Е М ЕН Ю
ove r r i de f u n c d i d Re c e i veMemo r yWa r n i ng ( ) {
s up e r . d i dR e c e i veMemo r yWa r n i n g ( )
1 1 О с в о бождение любых в о з о б н о в л я емых ре сурс о в .
v a r de t a i l i t em : N S Da t e ? {
didSet {
1 1 Обновление п р е д с т а в л е ни я .
s e l f . con f i g u r e V i e w ( )
}
М етод d e t a i l D e s c r i p t i o n L a b e l п редставля ет собой в ы ход, котор ы й
подключен к метке в раскадров ке . В шаблоне приложения метка просто в ы ­
водит описание объекта в с войстве d e t a i l i t em. С а м о с войство de t a i l i tem
п редназначено для хранения контроллером п редставления ссыл ки на объект,
который пол ьзовател ь выбрал в контроллере главного п редставлен ия. Его на­
бл юдател ь свойств ( код в блоке d i d S e t ), который вызывается после того, как
его значен ие было изменено, вызывает еще оди н созданн ы й для нас метод con f i gureView ( ) . Все, что он делает, - это вызы вает метод описания объек­
та с детал изированной информацией и испол ьзует его резул ьтат для настройки
свойства t e x t метки в раскадровке :
f u n c con f i g u r e V i e w ( ) {
1 1 Обно в л е ние п ол ь з о в а тель с к о г о интерфейса
1 1 дл я элеме н т а де т ализир о в а н н о г о представления
i f let de t a i l = s e l f . de t a i l i t em {
i f l e t l a b e l = s e l f . d e t a i l De s c r i p t i o n L a b e l
l ab e l . t e x t = de t a i l . de s c r i p t i o n
Метод de s c r i p t i o n реал изован в каждом подкл ассе NSOb j e c t . Есл и ваш
класс не переопределяет его, то он возвращает ( вероятно, не очен ь полезное)
значение по умол чанию. Однако в нашем при мере все объекты с детал изиро­
ванной и нформацией я вляются экзе м плярам и класса N S D a t e, а реализация ме­
тода описания в классе N S Da t e возвращает дату и время, сформати рован ные в
обобщенном виде.
Ка к р а бота ет п риложение master-detail
Итак, в ы в идел и все части шаблон ного приложения, но, вероятно, все еще
не очень ясно представляете себе, как оно работает. Так что давайте запусти м
его и посмотрим, что оно собой п редставляет. Запустите приложение на симу­
лятор устройства i Pad и поверните устройство в ал ьбом ную ориентаци ю, чтобы
поя вился контроллер главного представления . В ы можете увидеть, что метки в
контроллере детал изированного представления в настоя щее время и меют текст
по умол чанию, присвоен н ы й им в раскадровке. В этом разделе нас интересует,
ГЛ АВА 1 1 (t РАЗДЕЛ Е Н Н Ы Е П РЕДСТАВЛ Е Н И Я И ВСПЛ Ы ВАЮ Щ И Е М ЕН Ю
413
как выбор элемента в контроллере главного п редставления при водит к изме­
нению этого текста. В настоя щее время в контроллере главного представления
нет элементов. Чтобы исправить ситуацию, нажм ите нескол ько раз кноп ку + в
верхней части панел и навигации. Каждый раз , после того, как вы это сделаете,
в таблич ное представление контроллера добавляется новы й элемент (рис. 1 1 .7).
Clfrler •
Edit
iPad Air
Мaster
+
2016-07-1 3 15:30:23 +0000
-
IOS 10.О (14А5297с)
Detall
10<Ж -
2016-07-13 1 5:29:53 +0000
2016-07-1 3 1 5:29:51 +0000
Detail view content goes here
Рис . 1 1 . 7 . Ш абл о н ное п р иложе н и е с в ыб ран н ы м в контроллере гл авн ого
п редставл е н и я эл е м е нтом и и н формацией в контроллере детал и з и рован ­
н о го п редставле н и я
В с е элементы в табл и це контроллера главного представления я вляются да­
там и . Выберите оди н из н их, и метка в детал изирован ном п редставлении об­
новится, показы вая ту же дату. Вы уже видел и метод con f i gureV i ew в файле
De t a i l ViewContro l l e r . swi ft, который вызы вается, когда новое з начение со­
храняется в свойстве deta i 1 I tem контроллера детал изированного представле­
ния. Что же заставляет устанавл ивать новое значение свойства? Взгляните еще
раз на раскадровку на рис. 1 1 .6. И меется переход, который связывает табличную
ячейку-прототи п в ячейке табл и цы контроллера главного представления с кон­
троллером детал изирован ного представлен ия. Если вы щел кнете на этом пере­
ходе и откроете инспектор атрибутов, то увидите, что это переход Show Deta i l с
идентифи катором showDet a i l (рис. 1 1 .8).
41 4
ГЛАВА 1 1 !« РАЗДЕЛ Е Н Н Ы Е П Р ЕДСТАВЛ Е Н И Я И В С П Л Ы ВАЮ Щ И Е М Е Н Ю
) 1!1 Master Scene ) © Show Detall segue "showDetail' to 'Navigation Controller•
·�t-8
to
_
ry
_
b_
oa
rd
-8
-egu •
Т
)
1
ldentlller
oD
•
Klnd Show Deta�_(e_.:9. �pl�e) В
Ч�
Nav1gation Controller
showDetail
Cl11t1 • ' ..:J or
TaЫe View
D Animatas
Peek & Рор ,.._, Preview & Commit Segues
......
-
-
Рис . 1 1 . 8 . Переход Show Deta i l с в я з ы вает контролл еры гла в н о го и детал и з и ­
рован н о го п редставл е н и й
Как было показано в главе 9, при выборе ячейки табл и чного представления
срабаты вает связанн ы й с ней переход. Следовательно, при выборе строки в таб­
л и ч ном п редставлени и контроллера главного представления система iOS вы пол­
н ит переход Show Deta i l . При этом контроллер навигаци и служит "оберткой" для
контроллера детал изированного п редставления, я вляющегося цел ью перехода.
Это приводит к в ыпол нению двух действи й .
�
С оздается новы й э кзе м пляр контроллера детал изирован ного представле­
ния, и его п редставление добавляется в иерархию представлени й .
!!1
Вызы вается метод prepa reForSegue ( : s ende r : ) в контроллере главно­
го представлен и я .
Пер в ы й ш а г гарантирует видимость контроллера детал и зирован ного пред­
ставления. На втором шаге контроллер главного представления должен вывести
объект, выбранн ы й в контроллере главного п редставления тем ил и и н ы м спосо­
бом . Вот как это делает код шаблона в файле Ma s t e rVi ewCon t r o l l e r . swi ft
(листинг 1 1 .4 ).
Листинг 1 1 .4 . Метод prepare ( forSegue : ) в файле Ma s t e rVi ewCont ro l l e r . swi ft
1 1 MARK :
-
Segues
ove r r i d e f u n c p r e p a r e ( f o r s e g u e : U I S t o r y b o a r d S e g u e , s e nde r : AnyOb j e c t ? )
i f s egue . identi fi e r
" s howDe t a i l " {
i f l e t i ndex P a t h
s e l f . t a Ы e V i e w . i ndex P a t h Fo r S e l e c t e dRow
l e t o b j e c t = ob j e c t s [ i n de x P a t h . r ow ] a s ! N S D a t e
==
=
ГЛАВА 1 1 "" РАЗДЕЛ Е Н Н Ы Е П Р ЕДСТАВЛ Е Н И Я И ВСПЛ Ы ВАЮ Щ И Е М Е Н Ю
41 5
l e t con t r o l l e r = ( s e g u e . de s t i n a t i onVi ewCon t r o l l e r a s !
U I Na v i g a t i onCo n t r o l l e r ) .
t o p V i e w C on t r o l l e r a s ! D e t a i l V i ewCont r o l l e r
co n t r o l l e r . de t a i l i t em = ob j e c t
co n t r o l l e r . n a v i g a t i on i t em . l e f t B a r B u t t o n i tem =
s e l f . s p l i t V i ewCo n t r o l l e r ? .
d i s p l a yModeB u t t o n i tem ( )
con t r o l l e r . n a v i g a t i o n i t em . l e f t i t ems S upp l eme n t B a c kB u t t o n = t r ue
Сначала выпол няется проверка идентифи катора перехода, чтобы убедиться,
что это тот переход, который ожидался, и что получен объект N S Da t e из вы­
бранного объекта табл ицы контроллера представления . Далее контроллер глав­
ного представления находит э кзе м пляр De t a i l Vi ewCont r o l l e r из свойства
topVi ewCont ro l l e r целевого контроллера представления перехода, приведше­
го к вызову этого метода. Теперь у нас есть как в ыбран н ы й объект, так и конт­
роллер детал изированного представления, и все, что м ы должны сделать, - это
установить свойство det a i l i t em контроллера детализирован ного представле­
ния, чтобы обновить детал изирован ное представление. Последн ие две строки
метода prepare ( f o r S e gue : ) добавляют кноп ку режима отображения на па­
нел ь нави гации контроллера детал изирован ного п редставлен и я . Когда устрой­
ство находится в ал ьбом ной ориентаци и, н ичего не п роисходит, поскольку кноп­
ка режима отображения невидима, но есл и вы повернете устройство в книжную
ориентацию, то увидите, как появится кнопка Master.
Так что теперь вы знаете, как выбранн ы й в контроллере главного представ­
ления элемент отображается в контроллере детал изирован ного представления.
Хотя внешне это выглядит не сл и ш ком впечатляющим, на самом деле при этом
вы пол няется много действи й за сценой, обеспечи вающих корректную работу
как на i Pad, так и на i Phone, как в книжной, так и в ал ьбом ной ориентаци и .
Преимущество контроллера разделен ного представления в том , что о н заботится
обо всех деталях и не требует от вас задумы ваться о реал изации своих контрол­
леров главного и детал изированного представлен и й .
На этом мы закончим обзор того, что нам дает шаблон Master-Detai l Applicatioп
в среде Xcode. На первый взгляд, это сл и ш ком бол ьшой кусок информаци и,
чтобы справиться с ним с первого раза, но в идеале разделение приложения на
части поможет вам понять, как эти части взаимодействуют и в резул ьтате дают
единое приложение.
Добавление данн ы х о президентах
Теперь, когда мы разобрал ись в базовой структуре рассматри ваемого при­
ложения, самое время запол н ить пробел ы и превратить этот автоматически
сгенерирован н ы й "каркас" в авторский продукт. Нач нем с архи ва исходного
кода для нашей книги: пап ка 1 1 - P r e s ident s Data должна содержать файл
P r e s i d e n t L i s t . p l i s t . Перетащите этот файл в папку P re s i de n t s своего
41 6
ГЛАВА 1 1 lf! РАЗДЕЛ Е Н Н Ы Е П Р ЕДСТАВЛ Е Н И Я И В С П Л Ы ВАЮ ЩИ Е М Е Н Ю
проекта в среде Xcode, чтобы добав ить его в проект. При этом убедитесь, что
флажок, п редлагающий среде Xcode скопировать файл, установлен. Этот файл
. p l i s t содержит и нформацию обо всех п резидентах С Ш А до настоя щего вре­
мени, которая вкл ючает тол ько и м я и U R L статьи из В и ки педии (Wikiped ia) для
каждого из них.
Рассмотри м контроллер главного п редставления и подумаем, как нужно мо­
дифицировать его для н адлежащей обработки дан н ы х о президентах. Должно
быть достаточно л и ш ь загрузить сп исок п резидентов, представив его в виде таб­
л и цы, и передать U RL в детал изированное представление для отображения. На­
чнем с добавления в файл Ma s t e rVi ewCont ro l l e r . swi ft строки, выделенной
в следующем коде полужир н ы м шрифтом, и удаления зачеркнутой строки :
c l a s s Maste rViewControl l e r : U I TaЬl eVi ewCont r o l l e r {
va r de t a i l V i ew C o n t r o l l e r : De t a i l Vi ewCo n t r o l l e r ?
var
obj ect�
[ l'шyObj ec t ] ( )
var presidents :
=
nil
[ [ Strinq : Strinq ] ] !
Обратите внимание на метод v i ew D i dLoad ( ) , в котором изменения носят
нем ного более сложны й характер (но до сих пор все шло не так уж плохо). Вам
придется добавить несколько строк, чтобы загрузить сп исок президентов, а за­
тем удал ить нескол ько строк, которые создают кнопки редактирования и встав­
ки на панел и инструментов, как показано в л исти н ге 1 1 . 5 .
Листинг 1 1 . 5 . Метод v i ewDidLoad в файле Mas t e rVi ewCont r o l l e r . swi ft
ove r r i d e func v i e w D i d L o a d ( ) {
s u p e r . v i e w D i dL o a d ( )
1 1 Дополнител ь н а я н а с трой ка п о сл е з а гру з ки предс т а вления ,
1 1 к а к пр а в ило , и з n i Ь -файл а .
let path
Bund l e . ma i n . p a t h ( f o r Re s o u r c e : " P r e s i d e n t L i s t " ,
o f T yp e : " p l i s t " )
l e t p r e s i d e n t i n f o = N S D i c t i on a r y ( co n t e n t s O f Fi l e : p a t h ) !
p r e s i de n t s = p r e s i d e n t i n f o [ " p r e s i d e n t s " ] ! a s ! [ [ S t r i ng : S t r i ng ] ]
=
i f l e t s p l i t = s e l f . s p l i tV i ewCo n t r o l l e r {
l e t con t r o l l e r s
s p l i t . vi ewCont rol l e r s
s e l f . de t a i l V i e w C o n t r o l l e r = ( c on t r o l l e r s [ c o n t r o l l e r s . c o u n t - 1 ] a s !
U I Na vi g a t i o n C on t r o l l e r ) . t o p V i e w C o n t r o l l e r a s ?
De t a i l V i e w C o n t r o l l e r
=
На первый взгляд, этот код может показаться нескол ько запута н н ы м :
l e t p a t h = B u n d l e . ma i n . p a t h ( f o r Re s ou r c e : " P r e s i de n t L i s t " , o f Type : " p l i s t " ) !
l e t p r e s i de n t i n f o
NS D i c t i o na r y ( c o n t e n t s O f F i l e : p a t h ) 1
p r e s i de n t s = p r e s i d e n t i n f o [ " p r e s i de n t s " ] ! a s ! [ [ S t r i n g : S t r i n g ] ]
=
Метод p a t h Fo r Re s o u r c e ( _ : o fT ype : ) из файла Bund l e . ma i n получает
путь к файлу Pre s i de n t L i s t . p l i s t , содержание которого затем загружается
в N S D i c t i onary. Этот словарь содержит одну зап ись с ключом " p r e s ident s " .
ГЛАВА 1 1 r.11 РАЗДЕЛ Е Н Н Ы Е П РЕДСТАВЛ Е Н И Я И ВСПЛ Ы ВАЮ ЩИ Е М Е Н Ю
41 7
Значением этой зап иси я вляется масси в, в котором каждый элемент представля­
ет собой словарь класса N S D i c t iona ry. Массив и м еет по одному словарю для
каждого президента; этот словарь содержит пары "кл юч-значение", где и ключ,
и значение я вляются строкам и . Мы при водим массив к правильному типу языка
Swift [ [ S t r i ng : S t r i ng ] ] и присваи ваем 11еременной pre s i dent s .
Этот созданн ы й шаблоном класс вкл ючает также метод i n s e r tNewObj ect ( )
для добавления элементов в массив объектов . У нас больше нет этого масси ва,
так что удаляем весь метод.
Кроме того, у нас есть пара методов источн и ка дан ных, которые позволяют
пол ьзователя м редактировать строки в табл ичном представлени и . М ы не соби­
раемся разрешать какие-л ибо изменения строк в данном приложении, так что
просто удал и м методы canEd i t RowAt и commi tEdi t i ng S t y l e .
Теперь самое время адаптировать методы источ н и ка дан н ых главного таб­
личного представления для наших целей . Нач нем с изменения метода, который
сообщает табл и ч ному п редставлен и ю, с коль ко строк следует в ыводить.
ove r r i d e f u n c t a Ь l e V i e w ( _ t a Ы e V i ew : U I T a Ь l e V i e w ,
n umb e r O f R ow s i n S e c t i on s e c t i o n : I n t ) - > I n t {
r e t u r n p r e s i de n t s . c o u n t
,
После этого отредактируем метод t a Ь l eVi ew ( : ce l l Fo rRowAt i ndexPath : )
чтобы сделать каждую ячейку отображающей имя президента:
ove r r i d e f u n c t a Ь l e V i e w ( _ t a Ь l e V i e w : U I T a Ь l e V i e w ,
c e l l F o r R owAt i nd e x P a t h : I ndex P a t h ) - >
U I T aЬ l eV i ewCe l l {
t a Ь l e V i e w . dequ e u e Re u s aЬ l e C e l l (
let cel l
w i t h i de n t i f i e r : " C e l l " , f o r : i n d e x P a t h )
l e t p r e s i de n t
p r e s i d e n t s [ i nde x P a t h . r ow ]
ce l l . t e x t Labe l ! . t e x t
p r e s i d e n t [ " n ame " ]
r e t u r n ce l l
=
=
Наконец отредактируем метод prepare ( f o r Segue : ) дл я п ередач и дан ных
для выбран ного президента ( которые, как было сказано ранее, п редставля ют
собой словарь ти11а [ S t r i ng : S t r i ng ] ) контроллеру детал изирован ного пред­
ставления (л истинг 1 1 .6).
Л истинг 1 1 . 6 . Метод prepare ( forS egue : )
1 1 MARK :
-
Segues
ove r r ide f u n c p r e p a r e ( f o r s e g u e : U I S t o r yb o a r d S e g u e , s e n de r : AnyOb j e c t ? )
i f s e g u e . i de n t i f i e r
" s ho w De t a i l " {
i f l e t i nde x Pa t h
s e l f . t a Ь l e V i e w . i nd e x P a t h Fo r S e l e c t e dRow
l e t ob j e c t
p r e s i d e n t s [ i n d e x P a t h . r ow ]
l e t c o n t r o l l e r = ( s e g u e . de s t i n a t i o n V i e w C o n t r o l l e r
a s ! U I Na vi g a t i o n C o n t r o l l e r ) . t opVi ewCon t r o l l e r a s !
==
=
=
418
ГЛАВА 1 1 !fi РАЗДЕЛ Е Н Н Ы Е П РЕДСТАВЛ Е Н И Я И ВСПЛ Ы ВАЮ ЩИ Е М ЕН Ю
De t a i l V i ewCo n t r o l l e r
co n t r o l l e r . d e t a i l i tem = ob j e c t
c on t r o l l e r . n a v i g a t i o n i t em . l e f t B a r B u t t o n i t em =
s e l f . s p l i tV i ewC o n t r o l l e r ? . d i s p l a yMode B u t t o n i t em ( )
con t r o l l e r . n a v i g a t i on i t em . l e f t i t ems S upp l eme n t B a c kB u t t o n
true
ЗАМЕЧАН И Е . Есл и п е ре м е н н а я d e t a i l i t e m в шабл о н н о м ф а й л е D e t a i l V i e w
Con t ro l l e r . swi f t и меет значение N S da t e или подобное ему, то и з его текста не­
обходимо убрать строку ' An yOb j e c t ? ' , чтобы избежать потен циал ьных ошибок.
Это все, что нам нужно сделать в контроллере главного представления .
Далее выберите файл Ma i n . s t o ryboard и щел кн ите на п и ктограм ме Mas­
ter в разделе Master Scene окна Docu ment Outline, чтобы выбрать контроллер
главного представления, а затем дважды щел кн ите на его заголовке, замен ите
Ma s t e r на P r e s idents и сохран ите раскадровку.
Теперь можно построить и запустить приложение. Перекл юч итесь в альбом­
ную ориентацию или щелкните на кнопке Master в верхнем левом углу, чтобы
вызвать контроллер главного представления, показы вающий сп исок президентов
(рис. 1 1 .9). Щел кните на имени п резидента для отображения в подробном пред­
ставлен и и пока что не сл и ш ком полезной строки.
iP(ld Air - iOS 10.О (14д5297с)
Prellldento
Detall
John Adema
Тhomao Jefferaon
James Medloon
J81118a Monroe
John Qulncy Adama
Andraw JackSon
Мertln Yan Buren
WHllem Н8nry Harrlson
John Tyter
James к. Polk
Z•chary Taylor
МНlard Flllmore
Franklln Plerce
Jameo Buchanan
AЬraham Lincoln
Рис . 1 1 . 9 . П е р в ы й запуск нашего п р иложе н и я , де м о н стри рующи й с п и ­
с о к п рез иде нтов в контролл е р е гла в н о го п редста вл е н и я , н о п о ка нет
н и ч е го п ол е з н о го в контроллере детал и з и рован н о го п редста вл е н и я
ГЛАВА 1 1 ;ц РАЗДЕЛ Е Н Н Ы Е П РЕДСТАВЛ Е Н И Я И ВС П Л Ы ВАЮ Щ И Е М Е Н Ю
41 9
Закончим наш пример, заставляя детал изирован ное представление делать с
передаваемы м и дан н ы м и что-то нем ного более полезное. Добавьте следующую
выделенную полужирным шрифтом строку в файл D e t a i l Vi ewC o n t o l l e r .
s w i f t , чтобы создать выход для веб-п редставления, отображающего страницу
Википедии для выбран ного президента:
c l a s s De t a i l V i ewCon t r o l l e r : U I V i ewCon t r o l l e r
@ I BOut l e t we a k v a r de t a i l De s c r i p t i o n L a be l : U I Lab e l !
@ IBOutlet weak var weЬView : UIWeЬView !
Прокрутите файл до метода con f i gu reVi ew ( ) и замените его следующим
кодом (л исти нг 1 1 . 7).
Листинг 1 1 . 7 . Метод con f i gueView
f u n c c o n f i g u r e V i ew ( ) {
1 1 Обновляем пол ь з о в а т ел ь с кий интерфейс дл я элеме н т а
11 дет ализиро в а н н о г о предс т а в л е н и я
i f l e t de t a i l = s e l f . de t a i l i tem {
i f l e t l a b e l = s e l f . d e t a i l De s c r i p t i on Labe l
l e t di c t = de t a i l a s ! [ S t r i ng : S t r i n g ]
let urlString = dict [ " ur l " ] !
labe l . text
urlString
=
l e t u r l = NSURL ( s t r i n g : u r l S t r i n g ) !
l e t r e q u e s t = URLRe q u e s t ( u r l : u r l a s URL )
webV i e w . l o adRequ e s t ( r e q u e s t )
l e t name = d i c t [ " name " ] !
t i t l e = n ame
С войство d e t a i l i t em, которое было установлено контроллером главного
представления, - это словарь, содержащий две пары "кл юч-значение": одну с
и менем ключа, который хранит имя президента, а другую - с адресом, который
указы вает URL страницы Вики педии п резидента. Мы испол ьзуем U RL-aдpec,
чтобы задать текст метки детал изированного описания и создать NSURLRequest,
которы й будет испол ьзоваться U IWebV i ew для загрузки страницы. Для установ­
ки заголовка контроллера детал изированного представления мы испол ьзуем имя
президента. Когда контроллер представления представляет собой контей нер в
класс� U INavi gat i onCon t ro l l e r, значение его свойства t i t l e отображается
на панел и нав и гации контроллера навигац и и . Это все, что нам нужно, чтобы
наше веб-представление загрузило запрошенную стран ицу.
Последние изменения коснутся файла Ma i n . s t oryboard. Откроем его для
редактирования и найдем детализированное представление справа в низу. С на­
чала позаботимся о метке в графическом и нтерфейсе (текст которой и меет вид
"Detai l view content goes here" (Здесь находится содержимое детализированного
представления)). Сначала выберите метку. Возможно, проще всего найти метку
420
ГЛАВА 1 1 !<r РАЗДЕЛ ЕН Н Ы Е П Р ЕДСТАВЛ Е Н И Я И В С ПЛ Ы ВАЮ ЩИ Е М Е Н Ю
в разделе Deta i l Scene окна Docu ment O u t l i n e . В ыбрав метку, перетащите е е в
верхн юю часть окна. Обратите в н и мание на то, что метка должна при вести
в движен ие голубую л и н и ю разметки (слева направо) и удобно разместиться под
панелью навигации ( чтобы добиться этого, вы можете измен ить ее размер). На­
значение этой метки - отображать текущий U RL. Но при запуске приложения,
еще до того, как пол ьзователь выберет президента, хотелось бы, чтобы в этом
текстовом поле содержалась подсказка о том, что должен делать пользовател ь.
Дважды щел кн ите на метке и измен ите ее значен ие Select на President. В ы
должны также испол ьзовать инспектор размеров, чтобы убедиться, что метка
при креплена к левому и п равому края м , а также к верхнему краю и что она
сможет менять свои размеры в горизонтал ьном нап равлен и и при переходе из
ал ьбомной ориентации в кн ижную ил и обратно (рис. 1 1 . 1 О). Есл и необходи­
мо настроить эти огран и чения, воспол ьзуйтесь о п исан н ы м ранее методом . Ве­
роятно, вы получ ите то, что хотите, выбрав метку, а затем выпол н ив команду
Ed itorq Resolve Auto Layout l ssuesQ Reset to Suggested Con straints.
i r d (Base) }
l!J Deta l l Scena >
, Vlew
> L Deta i l Descrlption Label
Label
Preferred WI...
'
-·-----
Vlew
Show
А
..,
Arr1nge
Leyout M1rgin1
+
+
···
Expliclt
в
Frama Ractangle
16 :
343 :
Wldth
Detail
а
-
х
."
Sel e ct �resident
/.\ t )r • ,• ! •'
у
Helght
Posltlon Vlaw
Defвult
72 :
17 :
•
в
Preserve Supervlew Marglns
Follow ReadaЫe Wldth
S!1owing Э of 3
COntent Huaalna Prlorltv
Рис. 1 1 . 1 О. И н с п е ктор раз м е р о в , дем о н стри рую щи й огран и ч е н и я , н а ­
ложе н н ы е на м етку Select а P resident в н и ж н е й части экрана
ГЛАВА 1 1 �� РАЗДЕЛ Е Н Н Ы Е П Р ЕДСТАВ Л Е Н И Я И ВСПЛ Ы ВАЮЩ И Е М Е Н Ю
42 1
Затем испол ьзуйте библ иотеку, чтобы найти элемент ти па U I WebVi ew, и
перетащите его под надп ись ( которую м ы тол ь ко что "поставил и на место").
С помощью ман и пуляторов размеров заставьте этот элемент запол н ить остал ь­
ную часть представления под надп исью: от левого края до правого и от синей
направля ющей л и н и и ( как раз под н ижней границей надписи) до н ижней гра­
ницы окна. Испол ьзуя и нспектор размеров, прикрепите наше веб- представление
ко всем четырем края м окна и разреш ите ему изменять размеры как по гори­
зонтал и, так и по верти кал и (рис. 1 1 . 1 1 ). Как и ранее, вероятно, вы получите то,
что хотите, выбрав метку, а затем в ы пол н и в команду Ed itorq Resolve Auto Layout
l ssues c::::> Reset to Suggested Constra i nts.
В ыберите в окне Docu ment O utl i n e контроллер п редставления Master и от­
кройте окно и нспектора атрибутов. В разделе View Controller измените значение
поля Title с Ma s t e r на P r e s i dent s . Таки м
образом, название кноп ки навигаци и в вер­
......
-- хней части контроллера детал изирован ного
��--·---_ w._"
представления станет более полез н ы м .
...... .......
ТМmм Jetr"ton
Осталось вы пол н ить еще оди н шаг. Для
-1:1
р
,
того чтобы подключить выход тол ько что со­
Jlffln MOntOt
г....
John Ol.llnoy Adllml
Jame• Мас18оn
здан ного веб- представления, нажм ите клави­
......, ,.......
l�
шу <Control> и перетащите указатель от п и к­
,..
МartW\ Yan Вurtn
"
Wllll8m н.vу нarn.on
тограм м ы Data i l (в разделе Deta i l Scene окна
Jl8М Tyter
Docu ment Outl i n e ) к новому веб- представле­
J1mн K. Polk
/""'
нию (в том же разделе пря мо под меткой в
"....,., т_
,.
"
Мlt.lrd f1Umor•
" ....... " .,.. "'" м.
окне Document Outl i n e или в раскадров ке) и
Pl'anldМ РМrс.
,_ .......,
подкл юч ите выход webView. Сохраните из­
vi- ,.,...... �� �-.11t•
....
...... !",,..,.1"
AЬr8hamL!noc*\
менения .
1"
--....
Ulytм• s. Orant
Теперь можете ском поновать и запустить
r" -" .......
RutМttcиd 8. Нау"
... ..... .... ....."....
приложение, которое позвол ит п росматри­
...
James А. Oettlнt
вать страни цы Вики педии для каждого пре­
Chnter A.. Al1hw
--" -Orov• CМwllnd
зидента С Ш А (см . рис. 1 1 . 1 1 ). П о верн ите
дисплей, чтобы поменять ориентацию изоб­ Рис . 1 1 . 1 1 . П риложе н и е Pres i ­
ражения, и увидите, как контроллер разде­ d e nts , де м о н стри рующее стра ­
ленного представления обрабатывает вместо н и цу В и к и педи и , п о с в я щ е н ную
вас изменение ситуации при небол ьшой по- Дже й м су М эдисону (James M ad i ­
мощи контроллера детализирован ного пред­ son )
,
ставления.
·--- �
"'-rl • •• - - · ·•·1
...... °"'Y11f1i-1t14
� ь.-
, __
...,._
"""1 t 1 •1 - - t, tl0t
Создание пользовательского всплывающего меню
В главе 4 вы видел и, что можно вы вести с п исок действи й в том виде, в кото­
ром в мультфил ьмах передают реч ь персонажей (см . рис. 4.29). Это визуальное
представление контроллера всплывающе го меню, или просто всплывающее
ме11ю (popover) дл я краткости . Всплы вающее меню, которое вы получаете из
списка действий, создается для вас, есл и сп исок действий представлен классом
422
ГЛАВА 1 1 !!.> РАЗДЕЛ ЕН Н Ы Е П Р ЕДСТАВ Л Е Н И Я И В С П Л Ы ВАЮ Щ И Е М Е Н Ю
U I Popove r P r e s e n t a t i onCont r o l l e r, над которым у вас и м еется очень не­
бол ьшой контроль. Оказы вается, что с помощью класса U I Popove rCont r o l l e r
можно создать собственное вспл ы вающее меню.
Для того чтобы узнать, как это можно сделать, попробуем добавить меню,
которое будет акти визироваться постоян но присутствующи м на панели инстру­
ментов элементом (а не элементом класса U I Spl i tView). Наше всплывающее
меню должно отображать табл и чное представление, содержащее список язы ков.
При в ыборе пол ьзователем нового языка из списка веб-представление загрузит
уже отображаемую страни цу Википедии на заданном языке . Это несложная за­
дача, поскол ьку для перехода с одного язы ка на другой в В и кипеди и достаточно
изменить небол ьшую часть U RL-aдpeca, содержащего встроенный код стран ы .
На рис. 1 1 .3 показано, к чему м ы стремимся. Однако важно заметить, что класс
U I Popove rCon t ro l l e r доступен тол ь ко на устройстве i Pad, так что при работе
приложения на устройстве i Phone выбор языка будет отсутствовать.
ЗАМЕЧАНИЕ. В этом п р и м ере м ы испол ьзуем класс U I P o p o v e r P r e s e n t a t i o n
C on t r o l l e r м е н ю для демонстрации табл ицы , н о это н е должно вводить вас в за­
блуждение: его можно испол ьзовать для обработки вывода любого содержимого кон ­
троллера п редставления ! Почему м ы испол ьзуем в этом примере именно табличные
п редставления? Во-первых, потому, что это самый распространенный случай , во- вто ­
рых , это п росто сделать с помощью небол ьшого по объему кода и , в -третьих, этот
вариант представления вам уже достаточно хорошо знаком .
Итак, начнем. Щелкните правой кнопкой м ы ш и на папке Pre s i dents в сре­
де Xcode и выберите в контекстном меню команду N ew File
В поя вившемся
окне выберите пункт Сосоа Touch Class из раздела IOS Source, а затем щел к­
н ите на кнопке N ext. На следую щей странице экрана назовите новы й класс
Langua g e L i s t C o n t ro l l e r и выберите пункт U I T a Ь l eViewCont ro l l e r в
поле Su bclass of. Щел кните на кно п ке N ext, дважды щел кните на каталоге, в
котором сохраняете файл, и щелкните на кноп ке C reate.
Наш класс L a n g u a ge L i s t C o n t ro l l e r
стандарт н ы й класс контролле­
ра табл ич ного представления. Его назначение - отображать список элемен­
тов и уведомлять контроллер детал изирован ного представления (с помощью
соответствующего указателя ) о том , что в ыбор сделан. Отредактиру йте файл
LanguageLi s tContro l l e r . swi f t, добавив в него следующие выделенные по­
лужирным шрифтом строки :
. . . .
-
c l a s s L a n g u a ge L i s t C o n t r o l l e r : U I T a Ы eVi ewCont r o l l e r {
weak var detailViewController : De tai lViewController? = nil
private let l anquaqeNames : [ S trinq ] =
[ " Enql i sh " , " French " , " German " , " Spanish " J
private let lanquaqeCode s : [ Strinq ] = [ " en " , " fr " , " de " , " es " ]
Эти добавл е н и я о п редел я ют у казател ь н а контроллер детал изирован­
ного п редставления ( кото р ы й мы устано в и м из кода в самом контроллере
ГЛАВА 1 1 �1 РАЗДЕЛ Е Н Н Ы Е П Р ЕДСТАВЛ Е Н И Я И ВСПЛ Ы ВАЮ ЩИ Е М Е Н Ю
423
детал изирован ного представления, когда будем готовы отображать список язы­
ков), а также два масс и ва для хране н и я отображаем ы х значений ("Eng l i sh",
"French" и т.д.) и тех значений, которые будут испол ьзованы для создания URL,
взятых из выбран ного языка ("en", "fr" и т.д.).
Если бы вы скопировал и этот код из архива исходного кода дан ной книги (или
электронной книги) и вставил и в свой проект или ввели его сами, то, скорее всего,
не заметил и бы важное отл ичие объявления свойства de t a i lViewCont ro l l e r
от его предыдущего варианта. В отл и ч ие от большинства свойств, которые ссы­
лаются на объектн ы й указател ь, мы объя вили это свойство с атрибутом wea k,
а не s t rong. Это вызвано необходимостью избежать ц и кла удержания (retain
cyc le).
Что такое цикл удержания? Это ситуация, при которой нескол ь ко объектов
(два ил и бол ьше) ци кл ически ссылаются друг на друга. Каждый из объектов не
позволяет освободить память другого объекта. Больши нства потенциальных цик­
лов удержания можно избежать, если внимател ьно подходить к созданию своих
объектов, стараясь выяснить, "кто кем владеет". В этом смысле экзе м пляр конт­
роллера типа De t a i lViewCont ro l l e r "владеет" э кзем пляром контроллера ти па
LanguageLi s tCont ro l l e r, поскол ьку в действител ьности именно контроллер
De ta i l Vi ewCont ro l l e r создает экзе м пляр ти па Language L i s tContro l l e r,
чтобы обеспеч ить вы пол нение некоторой порции работы. Когда у вас есть пара
объектов, каждому из которых нужно ссылаться на другой, впол не естествен но,
что вы захотите, чтобы объект-"владелец" удерживал другой объект, в то время
как этот другой объект не должен удержи вать своего владел ьца. Поскол ьку мы
используем фун кциональное свойство A RC , в веденное Арр\е в Xcode 4.2, ком ­
пилятор вы пол н ит бол ьшую часть работы вместо нас. Для того чтобы не зани­
маться удалением объектов из памяти и их сохранен ием в памяти, мы должны
всего лишь объявить свойство, ссылающееся на объект, которы м м ы не владеем ,
с испол ьзован ием ключевого слова w e a k вместо s t rong. A RC сделает все ос­
тальное вместо нас.
Теперь перейдем к методу viewDidLoad ( ) и добавим немного кода настройки.
ove r r i de func vi e w D i d L o a d ( )
s u p e r . v i e w D i dLoad ( )
clearsSelectionOnViewWi llAppear
fal se
preferredContentSi ze
CGSi ze (width : 3 2 0 ,
height : ( lanquageCode s . count * 4 4 ) )
taЬleView . regi s ter (UI TaЬleViewCel l . se l f ,
forCel lReuseidentifier : " Cell " )
=
•
Здесь м ы определяем размер, которы й будет испол ьзовать представление кон­
троллера представления в случае его отображения во вспл ы вающем меню. Без
этого определения вспл ывающее меню будет растя гиваться по вертикал и, что­
бы заполнить почти весь экран, даже есл и оно может разместиться в гораздо
424
ГЛАВА 1 1 rt1 РАЗДЕЛ ЕН Н Ы Е П РЕДСТА В Л Е Н И Я И В С П Л Ы ВАЮЩИ Е М Е Н Ю
меньшем представлении . В закл ючение зарегистрируем класс я чейки табл ично­
го п редставления, как было показано в главе 8 .
Идем дал ьше. У нас есть д в а м етода, сгенерирован ных Хсоdе-шаблоном, в
которых вместо кода испол ьзован текст-запол н ител ь. Поэтому этот шаблонный
текст необходимо замен ить реал ьным кодом .
ove r r ide f u n c n umbe rO f S e c t i on s ( i n t a Ь l eV i ew : U I T a Ь l e Vi e w ) - > I n t {
return 1
ove r r i de f u n c t a Ы e V i e w ( t a Ь l e V i e w : U I T a Ь l e V i e w ,
n umb e rO f Row s i n S e c t i o n s e c t i o n : I n t ) - > I n t
r e t u r n l a ng u a g e C o de s . c o u n t
Теперь добави м метод t a Ы eView ( : ce l l ForRowAt i ndex Path : ) ; для по­
лучения объекта ячейки и размещения в ней назван ия язы ка (л истинг 1 1 .8).
_
Л истинг 1 1 . 8 . Ячейка для табличного п редставления
ove r r i de func t a Ы eV i e w ( t a Ы e Vi e w : U I T a Ы e V i e w ,
c e ll Fo r RowAt i n d e x P a t h : I n dex P a t h ) - >
U I T a Ы e V i ewCe l l {
t a Ы e V i e w . d e q u e u e Re u s a Ь l e Ce l l (
l e t ce l l
w i t h i de n t i f i e r : " C e l l " ,
f o r : i nd e x Pa t h )
/ / Н а с тройка я ч е й ки . . .
c e l l . t e x t La be l ! . t e x t = l a n g u a geName s [ i ndex P a t h . r ow ]
return ce l l
Далее реализуем taЫeView ( _ : d i d S e l e c tRowAt i ndex Pa t h : ) так, чтобы
можно было ответить на нажатие пол ьзователя передачей выбран ного языка в
контроллер детал изированного представления.
ove r r i de f u n c t a Ы e V i e w ( t a Ы e V i e w : U I T aЫ e V i e w ,
_
d i dS e l e c t RowAt i nde x Pa t h : I nde x Pa t h )
d e t a i l V i ewCon t r o l l e r ? . l a n g u a g e S t r i n g = l a n g u a g e Code s [ i n d e x P a t h . r ow ]
d i smi s s ( a n ima t e d : t r u e , cornp l e t i o n : n i l )
ЗАМ ЕЧАНИ Е . Обратите в н и м а н ие на то, что в классе De t a i l V i ewCon t ro l l e r свой­
ство l anguage S t r i ng не определено . Это вызовет о ш ибку компиля ц и и . С коро м ы
ее исправим .
Теперь пора модифицировать класс De t a i lViewCo n t ro l l e r, чтобы он мог
обрабатывать всплы вающее меню и генерировать корректны й U RL, когда пол ь­
зователь л ибо изменит язы к отображения, л ибо выберет другого президента. На­
чнем с внесения следующих изменений в файл De t a i l Vi ewCon t ro l l e r . swi ft
н иже объя вления класса U I WebView.
ГЛАВА 1 1 0t РАЗДЕЛ Е Н Н Ы Е П Р ЕДСТА В Л Е Н И Я И В С П Л Ы ВАЮ ЩИ Е М Е Н Ю
425
p r i va t e va r l a n g u a g e L i s t C o n t r o l l e r : L a n g u a g e L i s t C o n t ro l l e r ?
p r i va t e va r l a n g u a g e B u t t o n : U I Ba rB u t t o n i t e m ?
va r l a n g u a g e S t r i n g = " "
Здесь м ы добавили некоторые свойства для отслеживан ия ком понентов гра­
фического и нтерфейса, необход и м ы х для всплы вающего меню и выбранного
пол ьзователем языка. Все, что нам осталось сделать, - это исправить файл
De ta i l Vi ewContro l l e r . swi ft, чтобы обрабаты вать вспл ы вающее меню язы­
ка и создавать U RL.
Для начала добавим фу нкцию, которая п р и н и м ает в качестве аргументов
указател ь U R L на страни цу В и кипедии и двухбуквен н ы й код язы ка, а возвра­
щает новое значение U RL, в котором учте н ы все входные дан н ые. Позже м ы
испол ьзуем эту фун кцию в соответствующих местах нашего кода контроллера
(листинг 1 1 .9).
Л истинг 1 1 . 9 . Функция для создания специального URL с учетом выбранного языка
p r i v a t e f u n c modi f yU r l Fo r L a n g u a g e ( u r l : S t r i ng , l a n g u a g e l a n g : S t r i n g ? )
- > S t ring {
v a r newU r l = u r l
/ / Здесь м ы п ол а г а емся на к о н кр е тный форма т U R L Википедии .
/ / Это не о ч е н ь н а дежно !
i f l e t langS t r = l ang {
1 1 URL име е т вид h t t p s : / / e n . w i k i p e d i a . . .
l e t r a n g e = N S Ma k e Ra n g e ( 8 , 2 )
i f ! l a n gS t r . i s Emp t y & & ( u r l a s N S S t r i ng ) .
s ub s t r i n g ( w i t h : r a n g e ) ! = l a n gS t r
newU r l = ( u r l a s N S S t r i n g ) .
r ep l a c i n g C h a r a c t e r s ( i n : r a n g e ,
w i t h : l a n gS t r )
r e t u r n newU r l
Наш следующий ход - обновление метода c o n f i g u r e V i e w ( ) . Дан н ы й
метод будет испол ьзовать фу н кцию, которую м ы тол ько что о предел ил и, что­
бы объедин ить переданную фун к ц и и U RL-cтpoкy с в ыбран н ы м значением
language S t r i ng и сгенерировать корректн ы й U RL-aдpec, как показано в л ис­
тинге 1 1 . 1 О.
Листинг 1 1 . 1 0 . Настройка метода c o n f i gureV i e w
на указатель URL с учетом выбранного языка
f u n c con f i g u r e V i e w ( ) {
/ / Обновление п ол ь з о в а т ел ь с ко г о и н т е р ф е й с а
/ / дл я элеме н т а де т ализир о в а н н о г о п р е д с т а в л е ни я .
i f l e t d e t a i l = s e l f . de t a i l i tem {
i f l e t l a b e l = s e l f . d e t a i l De s c r i p t i on L a b e l
l e t d i c t = de t a i l a s ! [ S t r i n g : S t r i n g ]
/ / l e t u r l S t r i ng = d i c t [ " u r l " ] !
426
ГЛАВА 1 1 !J РАЗДЕЛ Е Н Н Ы Е П Р ЕДСТАВЛ Е Н И Я И В С ПЛ Ы ВА ЮЩИ Е М Е Н Ю
let u r l S t ring
rnodi fyO r l Fo r L a n g u a g e ( u r l : d i c t [ " u r l " J ! ,
l a n g u a g e : l a ng u a ge S t r i n g )
l abe l . t e x t = u r l S t r i n g
=
l e t u r l = O R L ( s t r i ng : u r l S t r i n g ) !
l e t r e q u e s t = ORLRequ e s t ( u r l : u r l
webV i e w . l o adRequ e s t ( requ e s t )
l e t n arne
d i c t [ " n arne " J !
title
narne
=
=
Теперь необходимо обновить м етод viewDidLoad ( ) . Создадим объект класса
U I Ba rBut t on i t em и поместим его в объект класса U I Navigat i on i tem в верх­
ней части экрана, но только есл и мы работаем на устройстве i Pad, как показано
в л истинге 1 1 . 1 1 .
Листинг 1 1 . 1 1 . Модифицирован ный метод viewDidLoad
ove r r i de func v i e w D idLoad ( ) {
s up e r . v i e w D i dLoad ( )
1 1 Дополнитель н а я на стройка после з а грузки представлени я ,
1 1 обыч н о и з n i Ь - файла .
s e l f . con f i g u re V i e w ( )
l a n g u a g e B u t t o n = O I B a r B u t t o n i t ern ( t i t l e : " Choo s e L a n g u a g e " ,
style : . plain,
ta rget : s e l f , action :
# s e l e c t o r ( De t a i l V i e w C o n t r o l l e r . s h owLa n g u a g e Popove r ) )
n av i ga t i o n i tern . r i gh t B a r B u t t o n i tern = l a n g u a g e B u t t o n
Далее реал изуем н аблюдателя свойств для свойства l a ngua g e S t r ing, ко­
тор ы й вызывается, когда изменяется значение свойства. Наблюдател ь свойства
вызывает c o n f i gu reVi ew ( ) , так что U RL-aдpec может быть регенерирован
(а новая страни ца загружена) немедлен но, и убирает вспл ы вающее меню выбо­
ра языка, есл и оно в идимо:
va r l a n g u ag e S t r i n g = " " {
didSet {
i f l a n g u a ge S t r i n g ! = o l dVa l u e {
configu reView ( )
Теперь реал изуем метод, кото р ы й в ы з ы вается , когда пол ьзо вател ь нажи­
м ает кно п ку C h oose Language. В этом случае мы в ы води м на э кран объект
класса L a n g u a g e L i s t C o n t r o l l e r, создавая его п р и первом в ы воде . Затем
м ы настраи ваем свойства его контроллера вс плы вающего п редставлен и я . По­
местите п р и веде н н ы й метод после метода v i e w D i d L o a d ( ) , как показано в
л исти н ге 1 1 . 1 2 .
ГЛАВА 1 1 lli РАЗДЕЛ Е Н Н Ы Е П Р ЕДСТА В Л Е Н И Я И В С П Л Ы ВАЮ Щ И Е М Е Н Ю
427
George Washington =
,.... " � " ,...,.,._.. .... � � o-,... P!"' /fl/�. �
� W"_.lf/Юn �Of) ,_. fll llllmir!QfrlO. � � � Нtlflfi/lt
o.or.,. � 11t3043
а-.. .......
-/\11� ��.�
,,.,," .... �. n ii. t.Ьt.0 • 1m.
liЬ<trl V.JW1 Vof9.Na. f1-IJ'*"­
l� dlt di-::.wrЬ. Olo 17fW'I P1 ,_ tu. .i
� P,..,,._,. dlt i.. ['8...,. th::IOI
-,. 1 188 'f 11'1tJМ lll N , �
... .ии (!еl t ""°'° с.а."'"""1111
�111 en 111 � oe ll
�181М lot � U�
j1111ii·178Э1 (11 1o8 E-lv\ Unk!(.Jl. 11t "8
cci � .i P10'1 U. ll Ptil1•.811 Jli U
� UllO IМ Ь. P'м•
f\.ll'ICIP:•
:l' CМ !и r..- 1,1rю.. /\lllkl
OCVl ..loln .lidм-... �wtjl� f......
,..._..." н.n11e11, Jur>п, �. n...­
� y --- �
OCl\deoOl'� - ln:ipм U. 11
•
........, . ... ..... i.....
ao • .,. • 17lt-c "" --. " .,..,.
---
--
C'Qlo" • .,. v..po1"8,I JWWll � - �
b•Ur1/Cn 0....-il • lti 0.-. ll f'811CD­
�· f'"'"'11Ц, l.O'l � que .i
tiao-l � •JU06 • •�
U C..9-. Cooo!Nut � •
� � ... ..... tН>
f.*ti:o c;......,.. 'Uf t11 11u, 1· 11111 n
@
� " " с..... � ·
-­
� .- --" . ·m-11 • ......,_ ... ,,,,
Рис . 1 1 . 1 2 . В ыб о р я з ы ка п р и загрузке
стра н и цы
Листинг 1 1 . 1 2 . Метод s howLangua ge Popove r
f u n c s h owLa n g u a g e Popove r ( ) {
i f l a nguag e L i s t C o n t ro l l e r == n i l {
1 1 Отл оже нное соэдание при и с поль з о в ании в п е р вый р а з
l a n g u a g e L i s t C o n t r o l l e r = L a n g u a g e L i s t C on t ro l l e r ( )
l a n g u a g e L i s t C o n t ro l l e r ! . de t a i l V i ewC o n t ro l l e r = s e l f
l a n g u a g e L i s t C o n t r o l l e r ! . moda l P r e s e n t a t i o n S t y l e
. popove r
=
p r e s e n t ( l a n g u a g e L i s t C on t r o l l e r ! , a n ima t e d : t r u e , comp l e t i o n : n i l )
i f l e t ррс
l a n g u a ge L i s t C o n t r o l l e r ? . p opove r P r e s e n t a t i on C o n t r o l l e r
ppc . b a r B u t t o n i t e m = l a n g u a g e Bu t t o n
=
В первой части этого метода м ы проверяем, существует л и объект кл асса
LanguageLi s tCont ro l l e r . Если нет, мы создаем экземпляр этого класса и за­
даем его свойство det a i l ViewCont r o l l e r так, чтобы объект ссылался на са­
мого ' себя . Мы также задаем его свойство moda l Pr e s e n t a t i o n S t y l e рав н ы м
popove r . Это свойство определяет, как будет демонстрироваться контроллер.
Существует нескол ько возможных значений, которые можно найти в докумен­
тации, опис ы вающей класс U IV i ewCont ro l l e r . Не уди вител ьно, что значе­
ние popove r испол ьзуется, есл и контроллер должен демонстрироваться как
вспл ы вающий объект.
Затем м ы испол ьзуем метод pre sentViewCont ro l l e r ( : animated : comp l e­
t i on : ) для того, чтобы объект класса Language L i s tCon t ro l l e r бы л видимым,
.
.
428
ГЛАВА 1 1 >11 РАЗДЕЛ ЕН Н Ы Е П РЕДСТАВ Л Е Н И Я И В С ПЛ Ы ВАЮ ЩИ Е М Е Н Ю
как м ы дел ал и при демонстраци и п редупреждения в главе 4. В ызов этого ме­
тода не сделает объект видим ы м немедленно - библ и отека U I Kit выпол н ит
эту функцию, когда будет завершена обработка события, связан ного с нажатием
кнопки, но она создаст объект класса U I Popove r P r e s e n t a t i o nCont ro l l e r,
которы й будет управлять демонстрацией всплы вающего контроллера. Перед тем
как на экране поя вится всплывающий объект, необходимо сообщить библ иотеке
U I K it, где и менно он должен поя виться . В главе 4 м ы испол ьзовал и этот прием
для размещения вспл ы вающего окна возле кон кретного представления, задавая
свойства s ou rceRect и sourceView класса U I Popove r Pr e s e n t a t i onContro­
l l e r . В этом примере мы хотим , чтобы вспл ы вающий объект появился возле
кнопки выбора языка. Для этого м ы п рисвоим ссыл ку на эту кнопку свойству
контроллера ba rBut toni t ern.
Теперь запустите приложение на симул яторе i Pad и нажм ите кнопку Choose
Language. Во вспл ы вающем окне будет вы веден контроллер списка язы ков, как
показано на рис. 1 1 . 1 2 . Для выбора одного из четырех доступных языков выбе­
рите одну из команд, которая позвол ит в ывести на экран веб-представление для
демонстрации верси и страницы п р иложения President на выбранном языке.
Переключение с одного я з ы ка на дру гой не должно вл иять на выбран ного
президента. А налоги ч но выбор другого президента не должно вл иять на выбор
язы ка, однако на деле это не так. Попробуйте : выберите президента, измен ите
язы к, напри мер на испанский, а затем выберите другого президента. К сожале­
нию, язык страницы бол ьше не испански й .
Почему это происходит? П р и каждом вызове переход S how De t a i l создает
новый экзе м пляр контроллера детализированного представления . Это значит, что
выбор язы ка, который сохраняется как с войство контроллера детал изирован ного
п редставления, теряется каждый раз при выборе нового президента. Для того
чтобы исправить этот недостаток, необходимо добав ить нескол ько строк к код
контроллера главного представления . Откройте файл Ma s t e rVi ewContro l l e r .
swi f t и внесите в метод prepa re изменения, показанные в л исти н ге 1 1 . 1 3 .
Л и стинг 1 1 . 1 З . Модифицированный метод prepare
ove r r i de func p r e p a r e ( f o r s e g u e : U I S t o r yboa r d S e g u e , s e nde r : A n yOb j e c t ? )
i f segue . ident i fi e r
" s ho w D e t a i l " (
i f l e t i ndex P a t h = s e l f . t a Ы e V i e w . i nd e x P a t h Fo r S e l e c t e dRow
l e t ob j e c t
p r e s i de n t s [ i n dex P a t h . r ow ]
l e t c o n t r o l l e r = ( s e g u e . de s t i n a t i on V i e w C o n t r o l l e r a s !
U I N avi g a t i on C on t r o l l e r ) . t opVi ewCo n t r o l l e r a s !
De t a i l Vi ew C o n t r o l l e r
i f l e t o l dC o n t r o l l e r = de t a i l V i ew C o n t r o l l e r (
con t ro l l e r . l a nguage S t r i n g
o l dCo n t r o l l e r . l a n g u a g e S t r i n g
==
=
=
co n t ro l l e r . d e t a i l i t em
ob j e c t
c o n t r o l l e r . n a vi g a t i on l t em . l e f t B a r B u t t o n l t em
s e l f . s p l i tV i ewCon t r o l l e r ? . d i s p l a yMode B u t t o n l t em ( )
c o n t r o l l e r . n a vi g a t i on i t em . l e f t l t ems S u pp l eme n t B a c kB u t t o n = t r u e
=
=
ГЛАВА 1 1
РАЗДЕЛ Е Н Н Ы Е П Р ЕДСТАВЛЕН И Я И ВСПЛ Ы ВАЮЩИ Е М ЕН Ю
de t a i l V i e wCo n t r o l l e r
=
429
co n t r o l l e r
Р е зю ме
В этой главе вы ознаком ил ись с контроллером разделенного представления и
его рол ью в создании приложений Master- Detai l . В ы также увидел и, как может
быть настроено полностью в пределах програм м ы l nterface Bui lder сложное при­
ложение с нескол ьки м и взаимосвязан н ы м и контроллерам и . Хотя разделенные
представления теперь досту п н ы на всех устройствах, пожалуй, все же наиболее
полезны они в устройствах с большим экраном, а именно - в i Phone 6/6s Plus
и iPad .
ГЛ АВА 1 2
• • •
Н ас т р о й к и п р ил о ж е н и й
и п о л ьз о в а т е л ь ски е
н ас т р о й к и п о ум о л ч а н и ю
Практически во всех современ�1ых ком пьютерн ы х програм мах, за искл юче­
н ием, быть может, сам ых простых, предусмотрено окно, в котором пол ьзовател ь
может устанавл и вать глобал ьные параметры, отражающие особенности работы
конкретного приложения. В операционной системе maxOS практически каждое
приложение имеет команду Preferences
После ее выбора откры вается окно, в
котором пользовател ь может ввести значения различных параметров и измен ить
их. В i Phone и других мобил ьных устройствах под управлением системы IOS
и меется специал ьное приложение Setti ngs, которым вы, без сом нения, пол ьзо­
вал ись неоднократно. В этой главе будет показано, как добавить пол ьзовател ь­
ские настройки в стандартное приложение Settings и получ ить доступ к ним из
своего приложения.
. . . .
З на к ом ств о с п акетом н а с тро ек
Приложение Setti11gs дает пользователю возможность вводить и изменять гло­
бальные параметры любого приложения, имеющего пакет настроек. Пакет настро­
ек (setting bu11dle) представляет собой группу встроенных в приложение файлов,
из которых приложение Settings может выяснить, какие именно глобальные пара­
метры настройки данное приложение должно получить от пользоваrеля (рис. 1 2. 1 )
В приложении IOS фун кции стандартных пол ьзовател ьских настроек реали­
зуют класс N S U s e r D e f au l t s . Если вам приходилось программировать в среде
Сосоа под управлением систем ы macOS, то вы, вероятно, уже знакомы с классом
NSU s e r De fa u l t s , поскольку именно этот класс используется для зап иси и счи­
тывания данных глобальных параметров настройки . В своих приложениях вы мо­
жете пользоваться классом N S U s e r De faul t s для доступа к данным глобальных
.
432
ГЛАВА 1 2 &' НАСТРО Й К И П РИ Л ОЖЕН И Й И П О Л Ь З О ВАТ ЕЛ Ь С К И Е НАСТРО Й К И ПО УМОЛЧАН И Ю
параметров настройки с помощью пар кл ючей и значений аналогично досrупу
к данн ы м по ключу в словаре. Отличие состоит лишь в том, что дан ные типа
NSUserDe faul ts хранятся в файловой системе, а не в экзем пляре объекта, нахо­
дящегося в операти вной памяти. В этой главе мы разработаем приложение, сфор­
мируем пакет настроек, а затем отредактируем глобальные параметры настройки,
обратившись к ним в приложении Settings непосредственно из данного приложения .
н••• Vertzon LТf
14:00
Settlngs
а Airplane Mode
а Wi-Fi
о Bluetooth
-f W Hii1!H
О!' )
()i \
Cellular
Personal Hotspot
Off
NotHications
fВ Control Center
CJ
Do Not Disturb
ф) General
• Display & Вrightness
g Wallpaper
Рис . 1 2 . 1 . П р иложе н и е Settings н а
т и п и ч н о м устройстве i P h o n e
Поскол ьку приложение Settings п редоставляет стандартны й и нтерфейс, у вас
нет необходимости разрабатывать собствен н ы й пол ьзовател ьский интерфейс для
настрой ки глобал ьных параметров приложения. Нужно л и ш ь составить сп исок
свойств. о пределя ющих досrу п н ы е параметры настройки приложения, а соот­
ветствующий и нтерфейс п риложение Settings построит автоматически. В прило­
жен иях с эффектом присутствия, таких как игры, должно б ыть предусмотрено
собственное п редставление глобальных параметров настройки, чтобы пользова­
телю не нужно было выходить из п риложения для внесения изменений. Даже
ГЛАВА 1 2 �." НАСТРО Й К И П Р ИЛОЖЕ Н И Й И ПОЛ ЬЗОВАТЕЛ ЬС К И Е НАСТ Р О Й К И П О УМОЛЧАН И Ю
433
некоторые утил иты и приложения, повы шающие производител ьность труда, мо­
гут иметь глобал ьные параметры настройки, к которым пол ьзовател ь должен
иметь досrуп, а знач ит, и возможность изменить их, не выходя из приложения.
В этой главе м ы также покажем, как получ ить глобал ьные параметры настройки
от пол ьзователя непосредственно в с воем приложении, а затем сохран ить их в
механизме U ser Defau lts системы iOS.
Пол ьзовател ь может перейти к приложению Settings, изменить значение па­
раметра, а затем вернуться в с вое приложение. В кон це главы м ы покажем, как
это сделать.
П риложен ие Bridge Control
В этой главе нам п редстоит написать п ростое п риложение Bridge Coпtro l ,
отслеживающее некоторые особенности управления мостиком косм ического ко­
рабля. Сначала м ы создадим пакет настроек, чтобы предоставить пользовател ю
досrуп к приложению Bridge Control из приложения Settings (рис. 1 2 .2).
Cмritf •
� News
•:10 РМ
Setting1
-
• Safaгi
Photos & Саmега
Game Center
С1 Twitter
11 FaceЬook
••
Flickr
(!J Vimeo
g Developeг
Рис. 1 2 . 2 . Доступ к п р иложе н и ю B r i d g e Contro l
и з п риложе н и я Sett i n g s на с и м ул яторе
434
ГЛАВА 1 2 51! НАСТРО Й К И П Р ИЛОЖ Е Н И Й И П ОЛ ЬЗОВАТЕЛ ЬС К И Е НАСТРОЙ К И П О УМОЛЧАНИ Ю
Если пользователь выберет приложение Bridge Control, в приложении Settings
откроется представление с глобал ьн ы м и параметрами настройки, относящим ися
к данному приложению. Дпя получения от пол ьзователя значений этих парамет­
ров в приложении Settings испол ьзуются поля редактирован ия, защищенные
поля редактирования, переключател и и ползу н ки (рис. 1 2 . 3 ) .
Обратите в этом п редставлении вни мание на два элемента с индикатQрами
продолжения, раскры вающим и следующее представление. Так, при выборе эле­
мента R a n k поя вится другое табл и ч ное представление, отображающее доступ­
ные для этого элемента параметры . Из этого табл и чного представления пол ьзо­
вател ь может выбрать только одно значение (рис. 1 2.4).
4 В.сk to 8rld9f Controt
( Sett1n..3s
-
1:11 РМ
Bridge Control
GENERЛL IN�O
( Вridge Control
t:17 РМ
Rank
-
Ensign
Commandlng Officer Kirk
Lieutenant
Authorizatlon Code • • • • ••
Rank
4 8eck to Bridge ContrOI
CaptatP
Warp Drive
Wд�р FACTOR
N -
Lleutenant Commander
Commander
Captain
Commodore
AODITIONAL INFO
Моrе Settings
Рис . 1 2 . З . Глобал ь н ы е параметры
настро й к и н а ш е го п р иложе н и я
Рис . 1 2 . 4 . В ы бо р одного от­
дел ь н о го парам етра настро й ­
ки и з с п и с ка
Элемент с и нди катором рас крытия Маге Sett i n g s дает пол ьзовател ю воз­
можность перейти еще к одному набору глобал ь н ы х параметров настрой ки
ГЛАВА 1 2 '«t НАСТРО Й К И П РИ Л ОЖЕН И Й И ПОЛЬЗО ВАТЕЛ Ь С К И Е НАСТРОЙ К И П О У М ОЛ ЧАНИ Ю
435
(рис. 1 2 . 5 ) . Это дочернее представление может и м еть такие же элементы уп­
равления, как и родител ьское, а также собствен ное дочернее п редставление.
В приложе н и и Settings испол ьзуется навигацио н н ы й контроллер, поддержи­
вающий построение иерархических п редставлений глобал ьных параметров на­
стройки.
После запуска дан ного приложения пол ьзователь увидит список глобал ьных
параметров настройки, собранн ы й в приложении Setti ngs (рис. 1 2 .6).
4 Sкk to 8fldg8 Conttol
8�1 РМ
-
< Bridge Control Моrе Settings
Officer:
Authorlzatlon Code:
Rank:
FдVORlrES
-
Kirk
scotty
Captain
Warp Oriye: Eлgagod
Warp Factor: 5.660142
Favorite Теа Earl Grey
Favorlte Теа:
Favorite Captain Plcard
Favorlte Captaln:
Favorite Gadget:
Favorlte Gadget Phaser
Favorite Alien
t:20 PM
CartW •
Vulca1>
Favorlte Alien:
1
Earl Grey
Picard
Phaser
Vulcan
.2
Рис. 1 2 . 5 . Доч е р н е е п р едста в ­
Рис . 1 2 . 6 . Главное п р едста вл е ­
л е н и е гл обал ь н ы х п а р а м ет р о в
н и е п риложе н и я Bridge C ontrol
настро й к и в п риложе н и и B r i d g e
Control
Для того чтобы продемонстрировать процесс обновления глобал ьных пара­
метров настройки в данном приложении, м ы предоставим второе представление,
в котором пол ьзователи смогут изменять допол нител ьные параметры настройки,
не покидая приложение (рис. 1 2 . 7).
436
ГЛАВА 1 2 1r. НАСТ Р О Й К И П РИЛОЖЕН И Й И П О Л Ь З О ВАТЕЛ ЬСКИЕ НАСТРО Й К И ПО УМОЛЧАН И Ю
1
2
Рис . 1 2 . 7 . Н астр о й ка н е кото р ы х гл обал ь н ы х
п а ра м етров в сам о м п р и л ожен и и
Создание проекта Bridge Control
Н аходяс ь в среде Xcode, нажм ите комбинаци ю клавиш <Sh ift+X +N> ил и
вы пол ните команду F i l e c:::> N ew c:::> P roject . Н а левой панел и в окне помощн ика
нового п роекта в ыберите элемент Appl ication под заголовком IOS, щел кните на
п и ктограм ме Tabbed Application, а затем на кноп ке N ext. В следующем окне при­
свойте новому проекту имя B r idge Cont r o l и выберите пун кт U n iversal в сп ис­
ке Devices, а затем щелкните на кноп ке N ext. В закл ючение выберите место для
хранения дан ного проекта и щел кн ите на кнопке C reate .
П р иложе н ие Bridge Control разрабаты вается на основе кл асса U I T a bBa r
C o n t ro l l e r, упом и навшегося в главе 7 . По выбранному шаблону создаются
две вкладки . Каждую вкладку необходи мо снабдить пиктограм мой. Файл ы изоб­
ражений этих п и ктограмм можно найти в папке 1 2 Ima g e s с исходным кодом
примеров, прилагае м ы м к этой книге. В ыберите в среде Xcode папку As s e t s .
xca s s e t s и удал ите из нее первое и второе изображения, добавленные шабло. . .
-
ГЛАВА 1 2 " НАСТРО Й К И П РИ Л ОЖЕН И Й И П О Л Ь З О ВАТЕЛ Ь С К И Е НАСТРО Й К И П О УМОЛЧАНИ Ю
437
ном Xcode. Затем перетащите пап ки s i ng l e i con . imag e s e t и douЫ e i co n .
ima g e s e t из папки 1 2 - I ma g e s в область редактирован ия, чтобы добавить
новые изображения.
Далее нужно назначить п и ктограм м ы для элементов вкладок. Выберите файл
раскадровки Ma i n . s t o ryboard. На экране появятся контроллер панел и вкладок
и два дочерних контроллера отдел ь н ы х вкл адок, обозначенные метками F i r s t
Vi ew и S e cond View. Выберите первы й контроллер, а затем щел кн ите н а его
панел и вкладок, содержащей квадрат и заглавие F i r s t . В ведите в поле Title из
раздела Ваг l tem и нспектора атрибутов строку Ma i n и выберите значение поля
l mage равн ы м s i ng l e i con, как показано на рис. 1 2 . 8 . Затем выберите панел ь
вкладок для второго дочернего контроллера, измен ите в поле Title строку Se cond
на S e t t ings и выберите значение поля l mage рав н ы м douЫ e i con. Этого пока
достаточно. Для того чтобы рас ш и рить свои возможности, в дал ьнейшем м ы
создадим пакет настроек.
Aaln.storyЬo1rd \ а Maln.storyЬo1rd (Ваое) ) С!/ Flrot Sctne )
Firat ) .* Мeln
l-� Гj:����:
Тab S.r ltem
Bodge
Cu1tom
6y1tem 1tem
elкted 1magt
Tltlt Po1Jtlon
&ar lttm
First View
loeded Ьу Fln:1VitwCon1roller
\
��о
Oeftult Posi1ion
1
Titlt M1/n
lmage tl
tlcoll
т�; douЫeicon
,
flrst
second
1
·-'-"-----·- - --
Рис ., 1 2 .8. Назнач е н и е п и ктогра м м ы для п е р вого элеме нта панел и в кл адок
Подготовка пакета настроек
Содержимое пакета настроек каждого приложения испол ьзуется в приложе­
нии Settings для построения представления, предн азначенного для настрой ки
отдельного приложения. Есл и же у приложения отсутствует пакет настроек, то
последние в приложении Settings вообще не отображаются . У каждого пакета
настроек должен быть сп исок свойств, храни м ых в файле Root . p l i s t , который
438
ГЛАВА 1 2 \\ НАСТР О Й К И П РИЛОЖЕ Н И Й И ПОЛ ЬЗОВАТЕЛ Ь С К И Е НАСТРО Й К И ПО УМОЛЧАНИ Ю
определяет представлен ие глобальных параметров настройки корневого уровня .
Этот список свойств должен очень точно соответствовать формату, который мы
обсудим при создан и и с писка свойств для пакета настроек рассматри ваемого
здесь приложени я .
После запуска приложения Settiпgs каждое приложение проверяется в нем
на наличие подготовлен ного пакета настроек, и есл и таковой существует, 'ТО до­
бавляется группа параметров для отдел ьного приложения . Есл и требуется, что­
бы представление глобальных параметров настрой ки включало в себя какие-ни­
будь дочерние представления, то в пакет настроек нужно ввести списки свойств
и отдель ную запись в файл Root . p l i s t для каждого дочернего представления .
Именно этим м ы и займемся далее.
Ввод пакета настроек в проект
Щел кните на папке B r i dge Cont r o l в окне навигатора проекта и вы пол ните
команду меню FileQNewqFile. " ил и нажм ите комбинацию клавиш <Sh ift+3t:+N>.
Затем выберите строку Resource под заголовком IOS слева, а сп рава - пикто­
грамму Settings Bundle (рис. 1 2 .9). Щелкните на кноп ке Next, оставьте без изме­
нения исходное имя S e t t i ng s . bund l e и щелкн ите на кнопке Create.
�--- ----- ....
Choose а template for your new flJe:
r10
S
1 ·�:u:-·---
"
�
User tnterface
GeoJSON File
Core Data
Apple Watch
Resouroe
Other
watchOS
·----------·--- -----
�
GPX File
....,.
Sticker Catalog
Property List
е
�
Asset Catelog
lil
User tnterfacc
"'"
Resource
Sceneкtt Scen e
Other
Flle
f.'IOS
Source
User tnter1ace
Core Data
_
SprlteКlt Action
"',..
�
Rich Text File
Scenet<it
Particle System
�
�
SpriteKlt
SprlteKlt Scene
Source
Core Data
'
f Y. J Т(f<
Particte File
Settlngs Bundle
,
8\lndle for specilying an IOS Appllcation·s settlngs.
Resource
=:..-_
__
_
_
Cancet
Рис . 1 2 . 9 . Созда н и е п акета настроек в среде Xcode
В окне п роекта должен поя в иться н о в ы й элемент под именем S e t t i ng s .
bund l e . Раскры в его, вы у видите два элемента: папку e n . l p ro j , содержа­
щую файл ы Ro o t . s t r i n g s , и файл Ro o t . p l i s t . Папку e n . l p r o j м ы рас­
смотри м позже, когда будем обсуждать локал изацию приложения, т.е. перевода
ГЛАВА 1 2 �i НАСТРОЙ К И П РИЛОЖЕН И Й И ПОЛЬЗОВАТЕЛ ЬС К И Е НАСТРО Й К И П О УМОЛЧАНИ Ю
439
их пол ьзовател ьского и нтерфейса на другие языки . Здесь мы остановимся на
файле Root . p l i s t .
Выберите файл Root . p l i s t и посмотрите н а панел ь редактора. В ы увидите
доступный в среде Xcode редактор списка свойств (рис. 1 2 . 1 О).
88 <
>
Bridge Contro l
)
_
Bridge Control
Кеу
Stri ngs Filename
•
...
Settings.bu ndle
Ту ре
Value
Stri ng
Root
Dictionary
" iPhone Settings Schema
� Preference ltems
)
Array
) �11 Root.plist ) No Selection
(2 items)
(4 items)
Рис. 1 2 . 1 0 . С п и со к и з файла Ro o t . p l i s t в о к н е редактора с п и ска с в о й ств .
Есл и вид окна редактора отл ич ается от п р и веде н н ого на это м р и сун ке, н ажм и ­
те клавишу < Contro l > в этом окне и в ы п ол н ите команду Show Raw KeysNalues
из конте кстн ого м е н ю
Обратите в н и мание на организацию элементов в сп иске свойств . С п иски
свойств, по существу, представля ют собой словари, в которых хранятся ти п ы
и значения элементов с п иска, а для доступа к эти м значен и я м испол ьзуются
ключ и, подобно тому, как это делается в словаре типа D i c t i onary. В с п исок
свойств можно ввести разноти п н ые узл ы . Узл ы типа B o o l e a n, D a t a , D a t e ,
NumЬer и S t r i ng служат для хранения отдел ьных элементов данных, но, пом и­
мо этого, имеется возможность оперировать цел ы м и коллекция м и узлов. Кроме
узлов типа D i c t i ona ry, в которых можно хран ить допол н ител ьные словари,
имеются узл ы ти па Array, в которых можно хран ить упорядочен н ы й сп исок
дополн ител ьных узлов. Тол ько узл ы типа D i c t i onary и Array могут содержать
допол нител ьные узлы в списке свойств.
ЗАМЕЧАНИЕ. Несмотря на то что в качестве кл ючей в словаре ти па D i c t i o n a r y можно
использовать больши нство типов объектов , ключами к словарю, образующему список
свойств , должн ы служить только с и м вольные строки . Однако для значений можно ис­
пользовать л юбой тип узл а .
Создавая сп исок свойств для настроек, нужно строго собл юдать кон кретны й
формат. К счастью, с п исок свойств Roo t . p l i s t, сопровождающий пакет на­
строек, тол ько что добавлен н ы й в проект, точ но соответствует этому формату.
Расс м отрим el'O подробнее.
Имена ключей на панел и редактора списка свойств Root . p l i s t могут вы во­
диться в исходном или более понятном для людей виде. Мы считаем, что вещи
следует восприни мать такими, каким и они я вляются, поэтому щелкн ите правой
кнопкой м ы ш и на любом участке дан ного редактора и установите флажок слева
от пункта Show Raw KeysNal u es всплы вающего меню (рис. 1 2 . 1 1 ). В дал ьней­
шем мы будем пол ьзоваться настоя щим и именами всех ключей, поэтому очень
важно установить дан н ы й режим работы .
440
ГЛАВА 1 2 �; НАСТРОЙ К И П Р ИЛОЖЕ Н И Й И ПОЛ ЬЗОВАТЕЛ ЬС К И Е НАСТРОЙ К И П О УМОЛЧАНИ Ю
1
j
1
Cut
Серу
Paste
Shift Row Rigl1t
St1ift Row Left
1
j
·M·MФNf#Шtfj!i@.
Value Туре
111-
Add Row
Property List Туре
111-
Property List Editor Help
1
t
!
1
�������- �----'
Рис . 1 2 . 1 1 . Щел кн ите м ы ш ью на л юбом уч астке ре ­
да кто ра с п и с ка с в о й ств , уде рживая н ажато й кла в и шу
< Co n t ro l > . Уста н о в ите флажок с л е в а от пун кта S h ow
Raw KeysNalues. Благодаря это м у в редакто ре с п и ска
с в о й ств будут и с п ол ьзо ваться насто я щ и е и м е н а кл ю ­
ч е й , обеспеч и вая бол ее точ ное редакти рован и е
ПРЕДУП РЕЖДЕН И Е . Есл и вы йти из с писка свойств, чтобы отредактировать другой
файл или поки нуть среду Xcode , флажок слева от пун кта S h ow Raw KeysNal ues
всплывающего м е н ю будет сброшен . Есл и текст н еожиданно изменился , п роверьте
меню и убедитесь, что дан н ы й флажок установлен .
Одн и м и з элементов словаря я вляется табл и ца с и м вол ь н ы х строк типа
S t r i ngsTaЬle, которая испол ьзуется при переводе пол ьзовател ьского и нтерфей­
са приложения н а другой язы к, как поясняется в главе 22, посвя щенной локали­
заци и приложени й . В данном случае табл и ца символ ьных строк не применяется,
поэтому ее можно удал ить, щел кнув на ней и нажав клави шу <Delete>. Но ее
можно и не удалять, поскол ьку она ничем не повредит. Кроме S t r ingsTaЬle,
список свойств содержит узел Pre ferenceSpe c i f i e r s . Он представляет собой
масс ив, п редназначен н ы й для хранения ряда узлов словаря, где каждый узел
представляет оди н параметр, который может ввести пол ьзовател ь, ил и одно до­
чернее представлен ие, к которому может перейти пол ьзовател ь.
Щел кните на треугол ьнике раскрытия слева от элемента P r e f e renceSpec i ­
f i e r s , чтобы раскрыть этот узел . Как видите, шаблон Xcode л юбезно 11редоста­
вил нам четыре дочерн их узла (рис. 1 2 . 1 2). Эти узл ы не отражают параметры
настройки, необходимые в данном примере, поэтому удал ите элементы I t em 1,
I t em 2 и I t em 3, щел кнув по очереди на каждом из них и нажав клавишу
<De lete>, но оставив на месте элемент I t em О .
ГЛАВА 1 2 н НАСТ Р О Й К И П РИЛОЖЕН И Й И П О Л Ь З О ВАТЕЛ ЬС К И Е НАСТРОЙ КИ П О УМОЛЧАНИ Ю
Кеу
"' i Phoпe Settings Schema
Stri пgsTa Ы e
"' PreferenceSpe cifiers
11> ltem О (Grou p - Group)
11> ltem 1 ( Техt Field - Name)
11> ltem 2 (Toggle Switch - E n a Ы ed )
11> ltem 3 (Slider)
...
•
...
•
Туре
Va l u e
String
Root
Dict i oпary
(2 items)
Dictioпary
Arra y
Dictioпary
Dictioпary
Dictioпary
441
(2 ite m s )
(4 items)
(8 items)
(4 items)
(7 item s )
Рис. 1 2 . 1 2 . В ид с п и с к а R o o t . p l i s t н а п а н е л и р еда кто р а с п и с ка
свойств - на этот раз с раскр ы т ы м эл е м е нтом P r e fe r e n c e S pe c i f i e r s
ЗАМЕЧАНИЕ. Что бы выбрать элемент из списка свойств , лучше всего щелкнуть на одной
или другой стороне стол б ца Кеу и те м сам ы м избежать появлен и я мен ю , всплываю·
щего в этом столбце .
Щел кн ите на элементе I t em О , но не раскры вайте его . Редактор с писка
свойств в среде Xcode позволяет добавлять строки нажатием клави ш и <Return>.
Место вставки новой строки о пределяется тем, какая строка выбрана и рас­
крыта ли она. Так, есл и выбран нерас крыты й масси в ил и словарь, то нажатием
клавиши <Return> н иже выбранной строки добавляется еще оди н узел на том
же самом уровне иерархии . Если вы нажмете клавишу <Return> (пока что не де­
лайте этого), н иже элемента I t em О сразу же поя вится новая строка с элементом
I t em 1 . На рис. 1 2 . 1 3 при веден при мер вставки новой строки нажатием кла­
виши <Return> . Обратите в н и мание на выпадающее меню, где можно в ыбрать
вид специфи катора глобал ьных параметров настрой ки, которые п редставляет
дан ный элемент, как поясняется далее.
Раскройте элемент I t em О и посмотрите на его содержимое (рис. 1 2 . 1 4 ) . Ре­
дактор готов добавить дочерние узлы к выбранному элементу. Если вы нажмете
клавишу <Return> (пока что не делайте этого), н иже элемента I tem О сразу же
поя вится новая строка с первым дочерн и м эле ментом .
Один из элементов из иерархии элемента I t em О имеет ключ Туре. Каждый
узел списка свойств в масси ве Pre fe rence Spe c i f i e r s должен и м еть элемент с
таким ,кл ючом . Ключ Туре сообщает приложению Settings тип данных, связанн ы й
с элементом . Кл юч Туре в элементе I tem О и м еет значение PSGroupSpe c i f i e r .
Это означает, что рассматри вае м ы й элемент представляет начало новой гру п п ы .
Каждый последующий элемент будет оставаться частью данной гру п п ы в плоть
до очередного кл юча Туре со значением P S GroupSpe c i f i e r . Если вернуться
к рис. 1 2 . 1 3 , то можно заметить, что в приложе н и и Sett ings настройки при­
ложения представлены в в иде сгру п п и рованной табл и цы . Элемент I t em О из
массива Prefe rence Spe c i f i e r s с писка свойств, подготавл и ваемого для пакета
442
ГЛАВА 1 2 r& НАСТРО Й КИ П РИЛОЖЕ Н И Й И ПОЛЬЗО ВАТЕЛ ЬСКИ Е НАСТРО Й К И ПО УМОЛЧАН И Ю
настроек, должен всегда и меть значен ие PSGroupSpec i f i e r своего ключа Ту ре ,
чтобы настройки начинались с новой гру п п ы . Это важно потому, что в каждой
таблице настроек должна быть хотя бы одна группа.
Туре
Кеу
--
Dictiona ry
У iPhone Settings Schema
StringsTaЫe
•
"
•
"
v
Value
(2 items)
String
Root
Arra;•
(2 it ems}
Dictionary
Dic
Group
МultJ Value
Slider
./ Text Field
Тitt
Toggf SWitch
Рис . 1 2 . 1 3 . Н а это м р исун ке п о каз а н о , что мы в ы б рал и эл емент I tem О и на­
жал и кла в и ш у < Retu rn > , чтобы добавить н о вую строку того же уровня . Об рати ­
те в н и м а н и е на в ы пада ю щее м е н ю , в кото ром м ожно задать вид специфи като ­
ра глобал ь н ы х параметров настро й ки , кото р ы е п редставл я ет дан н ы й эл емент
квv
Туре
" iPhone Settings Schcma
StringsTaЫe
" PreferenceSpeciflers
lttm О (Group " Group)
Туре
Тitfe
: оо
Dict ionary
String
Value
(2 itoms)
Root
•
""
•
•
•
Stri ng
String
Group
Рис. 1 2 . 1 4 . П р и рас ш и р е н и и эл е м е нта I t em о появляется одна стро ка с кл ю ­
чом Туре и другая строка с кл ю ч о м Title . О н и п редставл я ют груп пу под загла­
в и е м G ro u p
Еще толь ко оди н элемент из иерарх и и элемента I t em О имеет кл юч Title,
который служит для установки допол нител ьного, хотя и не обязательного заго­
ловка в начале гру п п ы . Присмотревшись внимател ьнее к самой строке I t em О,
вы заметите, что на самом деле она обозначается как I t em О ( Group - Group ) .
ГЛАВА 1 2 � НАСТРО Й К И П РИЛОЖЕ Н И Й И ПОЛЬЗОВАТЕЛ Ь С К И Е НАСТР О Й К И П О У М ОЛЧА Н И Ю
443
Обозначения в скобках представля ют элемент Туре (первое обозначение Group)
и элемент Title ( второе обозн ачение Group). Такое сокращение делает более
удобн ы м просмотр пакетов настроек.
Как следует из рис. 1 2 . 3 , первая гру п па глобал ьных параметров настрой ки
получила назван ие Genera l l nfo. Дважды щел кните в столбце Val u e на значении,
соответствующем ключу Title, а затем измен ите его с Group на Gene r a l I n fo
(рис. 1 2 . 1 5). Как тол ько вы введете новый заголовок, вы обнаружите небол ьшое
изменение в элементе I t em О. Теперь он обозначается как I t emO ( G roup Gene ral I n fo ) . Заглавие группы отображается в приложении Settings пропис­
ными буквам и, и поэтому пол ьзователь увидит обозначение GENERAL I N FO, как
и показано на рис. 1 2 .3 .
Кеу
'f' iPhone Sett i n g s Sch e m a
Stri ngsTaЫe
'f' PreferenceSpecifiers
'f' ltem О ( Group - General lnfo )
Туре
Tltl43
Тур е
Value
String
Root
Dictionary
(2 items)
Dictionary
•
"
•
"
•
(2 items)
(1 item)
Array
String
· оо StrJng
PSGroupSpecifier
л
General lnfo
Рис. 1 2 . 1 5 . З а гл а в и е груп п ы эл е м е нта I t em О и з м е н е н о с Group на Gene r a l
I n fo
Добавление поля редактирования для настройки
Теперь в дан н ы й масс и в нужно ввести второй элемент, который будет
представл ять первое кон кретное п оле глобал ь н ы х параметров н астрой ки .
Это будет простое поле редакти рован и я . Есл и щел к нуть сначал а н а строке
Pre fe renceSpe c i f i e r s непосредственно на панел и редактора (пока что не де­
лайте этого), а затем нажать клавишу <Return>, чтобы ввести дочерни й элемент,
то в начале списка будет вставлена новая строка, которая нам не нужна. Нам же
нужно добавить строку в конце масси ва.
Для этого щел кн ите на раскры вающем треугол ь н и ке слева от элемента
I t em О, чтобы свернуть его, а затем выберите элемент I t em О и нажм ите кла­
вишу <Return>, вставив ниже текущей строки новую строку того же уровня
(рис. 1 2 . 1 6 ). Как обы чно, при добавлении элемента появляется вспл ы вающее
меню со значением атрибута Text Field по умолчанию.
Щел кн ите сначала на л юбом участке за предел а м и в ы п адающего меню,
чтобы оно исчезло, а затем на раскрывающем треугол ь н и ке рядом с элемен­
том I t em 1 , чтобы раскрыть его иерархию. Как видите, он содержит атрибут
Туре row с установлен н ы м значением P S F i e l dSpec i f i e r . Это значение сооб­
щает приложению Settings, что пользователю следует разрешить редактировать
444
ГЛАВА 1 2 111 НАСТРО Й К И П Р ИЛОЖ Е Н И Й И П ОЛ ЬЗОВАТЕЛ ЬС К И Е НАСТРО Й К И П О УМОЛЧАНИ Ю
дан н ы й параметр настройки в поле редактировани я . Элемент I t em 1 содержит
также две пустые строки для атрибутов Title и Кеу (рис. 1 2 . 1 7 ).
Bridge Control
�
• iPhone Settings Schema
Stri ngsTaЫ e
У PreferenceSpecifiers
� ltem О (Group - General l nfo)
о
Settln g s . bundle
Туре
��
Stri n g
Root
"
•
"
•
��������-
1 te m 1 (Text Fietd - )
)'
v
(2 items)
Dictioпary
Array
( 2 item s)
Dictionary
Dii:tiмary
) 1 Root .pllst ) No Sele
(2 items)
л
('З ftems)
Group
Multi Va lue
Slider
../ Text Field
Title
Toggle Switch
Рис. 1 2 . 1 6 . Добавл е н и е н овой стро к и того же уров н я в и е рархи и эл е м е н ­
т а I t em О
Кеу
• iPhone Set1ings Schema
StringsTaЫe
•
•
У PreferenceSpecifiers
• ltem О (Group - General lnfo)
-... ltem 1 (Text Field - Commanding
Туре
Тlt
Кеу
•
•
•
Туре
Value
String
Root
D1ction ary
(2 items)
Dict ioмry
(2 items)
Array
(2 items)
Diction ary
•
•
о
•
•
(3 itoms}
String
$tfing
String
PSTextFieldSpecifier
�
C<>mmlndlng Officer
Рис . 1 2 . 1 7 . Раскрытая и е рархия эле м е нта поля редакти рова н и я , де м о н ­
стри рующая ти п , за гол овок и кл юч
В ыберите строку Title, а затем дважды щел кните на столбце Va l u e . В ведите
значение Commanding Of f i ce r атрибута Title. Именно этот текст и поя вится в
приложении Settings.
Сделайте то же самое в строке Кеу, но на этот раз введите значение o f f i ce r
строч н ы м и буквам и в столбце Va l u e . В этой строке приложению Settings со­
общается, каки м и м е нном кл ючом следует воспол ьзоваться, чтобы сохранить
значение, введенное в дан ном поле редактирован ия.
ГЛАВА 1 2 !lii! НАСТР О Й К И П РИЛОЖЕ Н И Й И П О Л Ь З О ВАТЕЛ ЬС К И Е НАСТРОЙ К И П О УМОЛЧАН И Ю
445
Пом н ите, что мы говорил и о классе N S U s e rDe faul t s ? Он позволяет сохра­
нять значения по некоторому кл ючу, п одобно тому, как это делается в классе
D i c t i onary. То же самое будет сделано в приложении Settings с кажды м гло­
бал ьным параметром настройки, сохраняем ы м от вашего имен и . Так, если задать
для кл юча значение foo, а затем запросить в приложении кон кретное значен ие
по ключу foo, оно возвратит значен ие, введен ное пол ьзователем для дан ного
глобал ьного параметра настройки. М ы воспол ьзуемся этим же значен ием кл юча
в дал ьнейшем, чтобы извлечь соответствующую настрой ку из пол ьзовател ьских
настроек по умолчан и ю в рассматри ваемом здесь приложе н и и .
ЗАМЕЧАН ИЕ. Обратите внимание на то , ч т о кл ючу Title соответствует значение C om­
man d i n g O f f i c e r , а кл ючу Кеу
значение o f f i c e r . Такое отличие в написан и и
пропис н ы м и и строч н ы м и буквам и встречается очень часто , а в данном случае о н о
становится еще более заметн ы м благодаря двум словам в отображаемом заглавии и
одному слову в значении кл юча. Значение ключа Title отображается на экране , поэ­
тому имеет см ысл использовать в нем прописные буквы с и о . А значение кл юча Кеу
представлено текстовой строко й , которой мы будем пользоваться дл я извлечения
глобал ьных параметров настройки из пол ьзовател ьских настроек по умолчанию, по­
этому в данном случае логи ч н ы м будет написание тол ько строч н ы м и буквам и . Могли
бы м ы написать значение ключа Title только строчн ы м и буквам и ? Конеч н о . Можно л и
написать значение кл юча Кеу только пропис н ы м и буквам и ? Безусловно! Дело в том ,
что при сохранении и извлечении глобал ьных параметров настройки пишутся пропис­
ными буквами , поэтому не и м еет значен ия , каким образом обозначаются ключ и .
-
Выберите последнюю из трех строк в иерархии элемента I t em 1 (с кл ю­
чом Кеу в столбце Кеу). Нажм ите клавишу <Return>, чтобы добавить в словарь
I tem 1 еще одну зап ись, задав кл юч Au tocapi ta l i z a t i onTyp e . Как тол ько вы
начнете вводить кл юч Au t o c ap i t a l i z a t i onType, в среде Xcode будет пред­
ставлен сп исок подходя щих вариантов, так что вы можете просто выбрать его
из списка, а не набирать пол ностью. В ведя ключ Aut o c a p i t a l i z a t i onType,
нажм ите клавишу <ТаЬ> ил и щелкните на маленькой п и ктограмме со стрел кам и
вниз и вверх справа от столбца Value, чтобы раскрыть список, и з которого мож­
но выбрать и меющиеся варианты. В ы берите вари ант Word s, которы й означа­
ет, что каждое слово, введен ное пол ьзователем в поле редактирования, должно
быть автоматически написано прописн ы м и буквам и .
Создайте еще одну, последнюю строку и задайте в ней кл юч Aut ocorrec­
t i onType и значение No. Тем сам ы м приложению Settings дается команда не
корректировать автоматически значения, в водимые в дан ном поле редактирования. В тех случаях, когда для поля редактирования потребуется автоматическая
коррекция, измен ите значение в этой строке на Yes . Опять же, как толь ко вы
начнете вводить слово Autoco r r e c t i onType, в среде Xcode будет представлен
список подходя щих вариантов, поэтому вы можете просто выбрать его из сп ис­
ка, а не набирать пол ностью.
По завершении оп исанных выше действи й сп исок свойств должен выглядеть
так, как показано на рис. 1 2 . 1 8 .
'
446
ГЛАВА 1 2 • Н АСТРО Й К И П Р И Л ОЖЕ Н И Й И ПОЛЬЗОВАТЕЛ Ь С К И Е НАСТРОЙ К И ПО УМОЛЧАН И Ю
Ту�ю
Кеу
Diction ary
.,. iPhone Settings Schema
...
•
StringsTaЫe
"
•
.,. PreferenceSpecifiers
t> ltem О (Group • General lnfo)
• ltem 1 (Text Field - Commandlng
Ту�ю
Tltle
Кеу
AutocepftallzatlonType
AutocorrectionType
...
•
...
•
"
•
Stri11g
(2 items)
Root
Array
(9 items)
D1ctiona ry
(б items)
String
Commandlng Off ic er
D ictionary
String
Stri ng
: оо Strfng
...
.
Value
String
(2 items)
PSTextFieldSpecifier
officer
с Word•
No
Рис . 1 2 . 1 8 . З а в е р ш е н н о е поле редакти рова н и я в с п и с ке Roo t . p l i s t
До бавление пиктограммы приложения
Прежде чем перейти к следующему п араметру настройки, добавьте в проект
пиктограмму приложения . Вам уже приходилось делать это ран ьше.
Сохраните только что отредактированн ы й файл свойств Root . p l i s t . Перей­
дите к навигатору проекта и выберите пап ку As s e t s . xca s s e t s , а в ней - эле­
мент App i con. Там вы найдете пару целей, предназначен ных для размещения
п и ктограм м .
Откройте в окне F i nder сначала архи в с исходн ы м кодом примеров, прила­
гаем ы м к этой книге, а затем папку 1 2 - Ima ge s . Проходя по элементам окна
редактирован ия папки As s e t s . x ca s s e t s сверху в н из, перетащите из папки
12 - Ima g e s следующие папки.
llf
Файлы S e t t i ng s - i Phone @ 2 x . png и S e t t i ng s - i Phone @ З x . png - на
позиции 2х и З х в левой верхней группе.
и
Файлы Spo t l i g ht - i Phone @ 2 x . png и Spot l i ght - i Phone @ З x . png - на
позиции 2 х и Зх в правой верхней группе.
�
Файлы App i co n - i Phone @ 2 x . png и App i con- i Phone @ З x . png - на по­
зиции 2х и Зх в гру п пе во второй строке.
�
Файл ы S e t t i ng s - i Pad . png и S e t t i ng s - i Pa d @ 2 x . png - на позиции
l x и 2 х в левой гру п пе в третьей строке.
1m
Файлы Spot l i ght- i Pad . png и Spo t l ight - i Pad @ 2 x . png - на позиции
l x и 2х в правой гру п пе в третьей строке.
#11
Файлы App i con- i Pad . png и App i con- i Pad@ 2 x . png - на позиции l x
и 2 х в группе в нижней строке.
·!!11
Файл ы App i con- i PadPro . png - на позицию I Pad Pro в правом н иж­
нем углу.
ГЛАВА 1 2 'К' НАСТРОЙКИ П Р ИЛОЖЕ Н И Й И ПОЛЬЗО ВАТЕЛ ЬСКИ Е НАСТРО Й К И П О УМОЛЧАН И Ю
447
Обратите вни мание на п редставление Activ ity. Если вы перетащите файл в
неправил ьную позицию, на экране поя вится треугольник предупреждения. Есл и
это произойдет, исправьте ошибку и продолжайте работу. По завершении редак­
тор ресурсов должен выглядеть так, как показано на рис. 1 2 . 1 9.
ApplCOf\
лpress-
:Apress-
2х
Зх
Эх
2х
IPhone
iPhone Spotlight
Spotllght • IOS 5,6
IOS 7 · 9
Settlngs • IOS 5-9
40pt
29pt
,(\J)resS'
лpress·
2х
Эх
IPhone Арр
IOS 7.9
60pt
Apl'eSS'
J\pf8lt
2х
1х
1х
IOS 5-9
iPad Spotllght
29pt
40pt
iPad Settings
2х
105 7-9
лpresS"
1-Press·
лpreSS'
1Х
2х
2х
iPad Дрр
IOS 7·9
IPad Pro Арр
76pt
83.5pt
IOS 9
Рис. 1 2 . 1 9 . В вод в п р иложе н и е п и ктогр а м м настроек и самого п р иложе н и я
Вот и все. Осталось лишь ском пилировать и запустить приложение на вы­
пол нение по команде Product q R u n . Мы еще не создал и н икакого графического
пользовател ьского и нтерфейса дл я данного приложения, поэтому в ы увидите
тол ько первую вкладку из панел и вкладок. Щелкните сначала на кнопке Home,
а затем на п и ктограм ме приложения Settings. Найдите элемент, соответствую­
щий рассматри ваемому здесь приложению с добавленной раньше п и ктограммой
(см . рис. 1 2 .2). Щел кн ите на строке Bridge Control, чтобы увидеть п ростое пред­
ставление настроек с одним полем редактирования (рис. 1 2 .20).
448
ГЛАВА 1 2 >'i НАСТРО Й К И П Р И Л ОЖЕН И Й И П О Л Ь З О ВАТЕЛ Ь С К И Е НАСТРОЙ КИ П О УМОЛЧАНИ Ю
( Settings
Bridge Control
-
GENERAL INFO
Commanding Off icer
Рис. 1 2 . 20 . Ко р н е вое п р едста вл е н и е н а ­
строе к в п риложе н и и Setti пgs после добав ­
л е н и я груп п ы и п о л я редакти рован и я
В ы йдите из си мулятора и верн итесь в среду Xcode. М ы еще не закончили,
но вы, вероятно, уже почувствовал и , наскол ько п росто можно ввести глобаль­
ные параметры настройки в с вое приложение. Теперь добавим остал ьные поля
в корневое представление настроек, начав с защи щен ного поля редактирован ия,
предназначенного для ввода кода пол номоч и й пол ьзователя .
До бавление за щ и щенного поля редактирования
Откройте среду Xcode и щелкните на элементе Root . pl i s t, чтобы вернуться
к спецификаторам настроек (не забудьте установить флажок Show Raw KeysNal­
ues). С верните элементы I tem О и I t em 1 . Выберите элемент I t em 1 . Нажм ите
комби нацию клавиш < Х +С>, чтобы скопировать выбран н ы й элемент в буфер
обмена, а затем комбинацию клавиш <X+V>, чтобы вставить его. В итоге будет
создан новы й элемент I t em 2 , идентич н ы й элементу I t em 1 . Раскройте новый
элемент и измените з начение ключа Title на Aut ho r i z a t i o n Code, а значение
ключа Кеу - на autho r i z a t ionCode. Напомним, что значение кл юча Title отоб­
ражается на экране в виде метки, а ключ Кеу служит дл я сохранения значения.
ГЛАВА 1 2 !!' НАСТРОЙ К И П РИЛОЖЕН И Й И ПОЛ ЬЗОВАТЕЛ ЬС К И Е НАСТРОЙ К И П О УМОЛЧАНИ Ю
449
Затем добавьте к новому элементу I t em 2 еще оди н дочерний элемент. На­
nомним, что nорядок следования элементов не имеет значен ия, nоэтому дочер­
ний элемент можно разместить неnосредствен но nод тол ько что отредактирован­
н ы м элементом Кеу . Для этого выберите строку Key/a uthorizationCode и нажм ите
клавишу <Return>.
Замен ите кл юч в столбце Кеу дл я нового элемента на I s S e c u r e , а тиn в
столбце Туре - на Bool ean. Измен ите его значение NO в столбце Val u e на YE S .
Этим nриложению Settings сообщается, что дан ное nоле будет служить дл я
скрытого ввода аналогично nарол ю, а не открытого, как обы ч но, текста. В за­
кл ючение измен ите для кл юча Autocapital izationType значение в столбце Val u e на
None. В завершенном виде элемент I t em 2 nоказан на рис. 1 2 .2 1 .
i 88 <
1
Ке у
>
Bridge Control
)
Bridge Control
Str i n g sTa Ыe
• ltem 1 (Те хt Field - Commandlng
Кеу
l sSecure
Autoca pltalizationType
AutocorrectlonType
Root
Dictionary
Dictionгry
ltem 2 (Text Fleld - Authorlzation
Title
String
Dictioпary
111> ltem О (Group - General lnfo)
Туре
Va lue
Array
• PreferenceSpecifiers
"
•
"
•
"
•
"
•
"
•
"
•
Settings. bundle
Тур е
Dictio nary
• i P ho ne Settings Schema
•
)
Stri ng
String
String
Boolean
String
String
)
Root .plist
) No Selection
(2 items)
(3 items)
(2 ltems)
(5 items)
(6 items)
PSTextFieldSpecifier
Authorlzation Code
authorizationCode
YES
None
No
Рис . 1 2 . 2 1 . Завершен н ы й вид эл е м е нта I t em 2 , п редставл я ю ще го поле ре ­
дакти рова н и я дл я ввода кода пол н о м о ч и й пол ьзователя
Добавление многозначного поля
Следующи й элемент, который нам nредстоит ввести, назы вается мно<'оз1ючnоля nозвол яет автоматически форм ировать строку с ин­
дикатором раскрытия. Щелкнув на нем, nол ьзовател ь nерейдет к еще одной таб­
лице, в которой он сможет выбрать одну из нескол ьких строк.
С верн ите элемент I t em 2 , выберите строку этого элемента, а затем нажм ите
клавишу <Return>, чтобы добавить элемент I t em 3 . Затем выберите из раскры­
вающегося сnиска, с вязанного с nолем Кеу, вариант M u lti Va l u e и разверн ите
элемент I tem 3, щел кнув на раскры вающем треугольнике.
Развернутый элемент I t em 3 уже содержит нескол ько строк. В одной из них
(с кл ючом Туре) находится значение PSMu l t i Va lueSpe c i f i e r . Найдите строку
11ым полем . Этот тиn
450
ГЛАВА 1 2 � НАСТРО Й К И П Р ИЛОЖЕ Н И Й И П ОЛ Ь З О ВАТЕЛ Ь С К И Е НАСТРОЙКИ ПО УМОЛЧАН И Ю
с кл ючом Title и задайте в ней значение Rank. Затем найдите строку с кл ючом
Кеу и задайте в ней значение rank. Следующий этап нескол ько сложнее преды­
дущих, поэтому стоит остановиться на нем подробнее.
Нам требуется добавить еще две дочерние строки к элементу I t em 3, но это
будут узл ы типа Ar ray, а не S t r ing.
�
Первый масси в под названием T i t l e s должен содержать список значе­
ний, из которого пол ьзователь может выбрать нужный вариант.
·�
Второй масси в под названием V a l u e s должен содержать сп исок значе­
н и й , которые фактически хранятся в п ол ьзовател ьских настрой ках по
умолчанию.
Есл и пол ьзовател ь выберет из списка первый элемент, соответствующий пер­
вому элементу в массиве Т i t l e s , приложение Settings фактически сохран ит
первое з начение из масси ва Va l ue s . Такое с парен ное при менение масси вов
Ti t l e s и Va lue s позволяет предоставить пол ьзователю дан ные в удобоч ита­
емом текстовом виде, но в то же время сохран ить совсем дру гое содержи мое,
напри мер ч исло, дату ил и другую с и м вол ьную строку. Оба эти массива обя­
зател ь н ы . Есл и требуется, чтобы эти массивы были оди наковы, создайте один
массив, скопируйте его и вставьте обратно, но измените кл юч, чтобы получ ить в
конеч ном итоге два масси ва с оди наковым содержимым, но с раз н ы м и ключам и.
Именно так м ы теперь и посту п и м .
В ы бер ите эле мент I t em 3 (оста в и в его раскрыты м ) и нажм ите клавишу
<Return>, чтоб ы добавить новую дочернюю стро ку к этому эл еме нту. При
этом вы с м ожете еще раз убедиться , что в с реде Xcode заранее из весте н
ти п файла, кото р ы й в ы редакти руете, и поэтому, п редв идя ваш и действ ия,
в поле Кеу новой дочерней строки уже установлено з н ачение Ti t l e s , а в
поле Туре
тип A r r a y, т. е. и ме н н о то, что нам и нужно ! Н ажм ите кл ави­
шу <Return>, чтобы п рекратить редактирован ие пол я Кеу, а затем раскройте
строку T i t l e s и нажм ите кл авишу <Return>, чтобы добав ить дочерн и й узел .
Повторите эту п роцедуру еще пять раз, чтобы в итоге добавить шесть дочер­
н и х узлов. Все о н и должны быть узлам и ти па S t r i n g и содержать следую­
щие значен и я : E n s i g n, L i e u t e n a n t , L i e u t e n a n t C omma nde r, C omma nder,
Capt a i n и C ommodo r e .
В ведя все эти узл ы , с верн ите элемент Т i t l e s и выберите его . Нажм ите
комбинацию клав и ш <Х +С>, чтобы скоп ировать в ыбран н ы й элемент в буфер
обмена, а затем комбинацию клавиш <Х +У>, чтобы вставить его. В итоге бу­
дет создан новый элемент с ключом T i t l e s
2 . Дважды щел кн ите на ключе
T i t l e s 2 и измените его на Va lue s .
М ы почти завершили создание м ногозначного пол я . В словаре есть еще одно
обязател ьное значен ие, которое предоставляется по умолчанию. М ногозначные
поля должны иметь одну и только одну выбранную строку. Поэтому нужно ука­
зать такое значение, которое будет испол ьзоваться по умолчанию, есл и ни одно
-
-
-
ГЛАВА 1 2 ·.;i;: НАСТРО Й К И П РИЛОЖЕН И Й И П ОЛ ЬЗОВАТЕЛ ЬС К И Е НАСТРОЙ К И ПО УМ ОЛ ЧАНИ Ю
45 1
из предложенных для выбора з начени й не будет в ыбрано, причем это значение
должно быть связано с одн и м из элементов масси ва Va l u e s (но не массива
T i t l e s , есл и эти массивы разные). При создан и и этого элемента средствам и
среды Xcode к нему была автоматически добавлена строка De faul tVa lue, по­
этому вам остается тол ько задать в ней з начение E n s i gn. Сделайте это теперь.
В завершен ном виде элемент I t em 3 показан на рис. 1 2.22.
Кеу
т iPhone Sett i n g s Schema
"
"
"
"
Strings Filename
т Preference ltems
11> l te m О ( Group - General l nfo )
11> ltem 1 (Text Field - Commanding
т Titl e s
ltem О
"
"
ltem 2
ltem 3
ltem 5
т Va l ue s
ltem О
Defa u l t Va lue
( 2 items)
(5 i tem s )
(6 items)
(6 items)
(6 ite ms)
Stri n g
Ensign
St r i ng
Lieutenant
Stri n g
Lieutenant Commander
St r i ng
Commander
"
"
Array
(6 items)
ltem 4
l dentifier
Dicti o n a ry
Array
(4 item s )
� Captain
ltem 3
Title
Diction ary
Strlng
ltem 2
ltem 5
Root
Array
(2 items)
00
ltem 1
Туре
String
Dictionary
Dictionary
ltem 1
ltem 4
Va lue
Dictionary
11> l te m 2 (Text Field - Authorization
т ltem 3 (Multi Va lue - Rank)
Туре
S t ring
Stri ng
E nsign
Str i ng
Li eu t enant
Stri n g
Lieutenant Commander
Stri n g
Commande r
Strin g
"
•
"
•
"
•
"
•
Commodore
Stri n g
String
Stri ng
Ca pta i n
Commodo re
M u l t i Va lue
Rank
String
rank
String
Ensign
Рис . 1 2 . 2 2 . Заверше н н ы й вид эле м ента I tem з , п редста вл я ю щего м н о ­
го З н а ч н ое п о л е дл я в ы бора одн ого и з ш ести воз м ожн ых з н ач е н и й
Проверим резул ьтаты наших трудов . Сохраните список свойств, а затем по­
стройте и запустите дан ное приложе н ие на в ы пол нение. П осле этого нажм ите
главную кнопку и запустите приложение Settings на в ыпол нение. В ыбрав эле­
мент Bridge Contro l в корневом п редставлен и и , вы должны у видеть три поля
(рис. 1 2 .23). Поэкспериментируйте с ними, и двинемся дальше.
452
ГЛАВА 1 2 i.� НАСТР О Й К И П РИЛОЖЕН И Й И П О Л Ь З О ВАТ ЕЛ ЬС К И Е НАСТРОЙ К И ПО УМОЛЧАНИ Ю
( Settings
-
Brldge Control
OENERAL INFO
Commandlng Officer Kirk
Authorization Code
Rank
Captain
>
Рис. 1 2 . 23 . Тр и гото в ы х к уп отре бл е ­
н и ю п ол я . Совсем н е пл охо !
Добавление переключателя
Следующий элемент для получения дан н ы х от пол ьзователя п редоставля­
ет логическое значение типа Boo l e a n, которое означает, подкл ючены л и дви­
гател и искривления пространства. Дпя того чтоб ы зафи ксировать логическое
значение типа Boo l e a n в глобал ь н ы х параметрах настройки, дадим приложе­
н и ю Settings команду воспол ьзоваться классом U I Sw i t ch, добави в в массив
P r e f e renceSpe c i f iers еще оди н элемент типа PSTogg l e Sw i t chSpe c i f i e r .
С верните элемент I t em 3 , есл и он все еще развернут, а затем щел кн ите н а
н е м , чтобы выбрать его. Нажм ите клавишу <Return>, чтобы создать элемент
I t em 4 . В ы берите из раскры вающегося с п иска вариант Toggle Switch, а затем
щел кн ите на рас кры вающем треу гол ь н и ке, чтобы раз вернуть элемент I t em 4 .
В итоге в ы увидите в нем дочернюю строку, в которой поле Кеу содержит значе­
ние Туре, а поле Value - значение P P S t og g l e Swi t chSpec i f i e r . Добавьте еще
одну дочернюю строку с ключом Title и значением Warp Dr ive, а затем третью
дочернюю строку с кл ючом Кеу и значением warp.
В этом словаре должен б ыть еще оди н обязательный элемент, предоставляю­
щий значение параметра по умолчанию. Как и при настройке элемента Multi Value,
ГЛАВА 1 2 1111 НАСТРО Й К И П Р И Л ОЖ Е Н И Й И ПОЛ ЬЗОВАТЕЛ ЬС К И Е НАСТРОЙ К И П О УМОЛ Ч А Н И Ю
453
в Xcode уже создана строка с ключом Defau ltVa l u e . Пусть дви гатели искривле­
ния пространства будут по умолчани ю включе н ы ; присвойте в строке Defa u lt­
Value значение YE S . В завершен ном виде элемент I tem 4 показан на рис. 1 2 .24.
- - ------
Кеу
т Preference lte m s
..,. l t e m О (Gro u p - General l nfo)
...
•
...
•
..,. ltem 1 (Text Fleld - Commanding
..,. ltem
2 (Text Field - Authorization
Туре
Title
l dentlfier
Default Va lue
String
Root
Агrау
(5 items)
Dictionary
(2 items)
v
...
•
...
•
...
•
...
(2 items)
Dictionary
(5 items )
Dlctionary
(6 items)
Dictionary
� (4 lt�s.J
Dictio nary
..,. ltem З (Multi Value - Rank)
ltem 4 JToggle SW1tch - Warp
Value
Dictionary
т iPhone S ettings Schema
Stri ngs Filename
Туре
Stri ng
String
Stri ng
Boolean
( 6 ite ms)
Toggle Switch
Warp Drlve
warp
YES
Рис. 1 2 . 24 . Завершен н ы й вид эл е м е нта I tem 4 , п редставл я ю ще го п е ­
рекл ючател ь , управл я ю щ и й дви гател я м и и с к р и вл е н и я простран ства
Добавление ползунка
Теперь нужно добавить ползунок. В приложе н и и Settings ползунок может
иметь небол ьшие изображения на кон цах, но не может и м еть метку. Размести м
ползунок в отдел ьной группе с заголовком, чтобы пользователь знал назначение
ползунка. Для начала сверн ите элемент I t em 4. Щелкните на элементе I t em 4 и
нажм ите клавишу <Retum>, чтобы вставить новый элемент в груп пу. Выберите
из рас кры вающегося с п иска вариант G ro u p, чтобы превратить новый элемент
в группу, а затем раскройте его. Как видите, в поле Туре уже установлено зна­
чение PSGroupSpe c i f i e r . Эти м приложе нию Settings предписывается начать
здесь новую груп пу. Дважды щел кн ите на значе н и и в строке Title и измен ите
его на Warp Factor.
Сверните элемент I t em 5 и выберите его. Нажм ите клавишу <Return>, чтобы
добавить новую строку того же уровня. Выберите из раскрывающегося с п иска
элемент Sl ider, указав приложению Settings воспользоваться классом U I S l i de r,
чтобьl получить дан ные от пол ьзователя . Раскройте элемент I t em 6 и задайте в
строке Кеу значение warpFa c t o r, чтобы приложению Settings стало известно,
какой именно ключ следует испол ьзовать для хранения этого значения.
Нам требуется разреш ить пол ьзовател ю регул ировать коэффи циент искрив­
ления п ространства в пределах от 1 до 1 О , а по умолчан и ю установить его
равным 5 . Ползунки должн ы иметь м и н и мал ьное значение, максимал ьное и на­
чальное (по умол чанию) значен ие, и все эти значения нужно сохран ить в списке
свойств как ч исла, но не как с и м вол ьные строки. Правда, в среде Xcode уже
454
ГЛАВА 1 2 &'! НАСТР О Й К И П РИЛОЖЕН И Й И ПОЛЬЗОВАТЕЛ ЬС К И Е НАСТР О Й К И ПО УМОЛЧАН И Ю
создан ы строки для установки всех этих значен и й . Поэтому установите в строке
DefaultValue значение 5, в строке MinimumValue - значение 1 , а в строке Maxi­
mumValue - значение 1 0 .
При желан и и можете прямо сейчас п роверить правильность фун кцион ирова­
ния ползунка. Тем временем м ы сделаем еще кое-что для его настройки.
Как отмечалось ранее, ползунки могут иметь изображения на кон цах: Вос­
пол ьзуемся мел к и м и п и ктограммами, чтобы показать, что смещение ползунка
влево дает эффект замедления, а смещение вправо - эффект ускорения.
Добавление пиктограм м в пакет настроек
В папке 1 2 Ima g e s с исходны м кодом примеров, прилагае м ы м к этой кни­
ге, вы найдете две п и ктограмм ы в файлах изображений rabbi t . png и turt l e .
png. Нам нужно добавить их в пакет настроек рассматриваемого здесь приложе­
ния. Эти изображен и я будут испол ьзоваться в приложении Settings, и поэтому
нел ьзя просто переместить их в папку B r idge Cont r o l , но придется ввести в
пакет настроек, чтобы обеспечить доступ к ним из приложения Settings. С этой
цел ью найдите в нави гаторе проекта пап ку S e t t i ng s . bund l e и откройте ее
в окне Finder. Щел кните п равой кнопкой м ы ш и на п и ктограм ме S e t t i n g s .
bund l e в окне навигатора проекта. Выпол ните команду Show in Finder из вспл ы­
вающего меню (рис. 1 2 .25).
-
"' ltem 2 (Text F
8" ltem З (Multi
Open with External Editor
Open As
Show File lnspector
New File
Add Files to "Settings.bundle"".
l ider
ltVal1
umV1
umV
Delete
New Folder
New Group from Selection
Sort Ьу Nэme
Sort Ьу Туре
Рис. 1 2 . 2 5 . Вид контекстного м е н ю эле м е н та S e t t ings . bundle
Напом ним, что пакеты на самом деле я вля ются папкам и, хотя в окне Find­
er они в ы глядят, как файл ы . Чтобы посмотреть содержимое папки S e t t ings .
bund l e в окне Finder, щел кн ите на ней правой кнопкой м ы ш и и выберите
пункт Show Package Contents из вспл ы вающего меню. В итоге пакет настроек
ГЛАВА 1 2 "' НАСТРО Й К И П Р ИЛОЖЕН И Й И П ОЛ ЬЗ ОВАТЕЛ Ь С К И Е НАСТРОЙ К И П О УМОЛЧАН И Ю
455
откроется в новом окне Finder, в котором вы должны обнаружить те же два эле­
мента, которые видел и и в Xcode, раскр ы в пап ку S e t t i ng s . bund l e . С копируй­
те два файла п и ктограм м rabЬi t . png и t u r t l e . png из папки 12 - Images в
папку S e t t i n g s . bundl e непосредственно в окне Finder, расположив их рядом
с файлам и e n . p r o j и Root . pl i s t. Можете оставить это окно Finder откры­
ты м, поскол ьку нам придется вскоре скоп ировать в нем еще оди н файл . Тем
временем вернемся в среду Xcode, чтобы испол ьзовать эти два изображения на
концах ползунка.
Итак, вернувшись в Xcode, обратитесь снова к с п иску Root . p l i s t и вве­
дите в нем еще две дочерн ие строки под элементом I t em 6: одну - с кл ючом
MinimumValuel mage и значением t u rt l e . png, а другую - с ключом Maximum
Valuel mage и значением rabЬi t . png. В завершенном виде элемент I t em 6 по­
казан на рис. 1 2 .26.
г
1
Кеу
Туре
'У i Phone Sett ings Schema
Va l u e
Dictio n a гy
(2 items)
Str i n g
Root
Array
(7 items)
D i c t i o n ary
( 2 items)
"" ltem 1 (Text Field - Comm a n d i n g
Diction ary
( 5 items)
"" ltem
D i c t i o n a ry
JiJ>. ltem З ( M u lti Va \ue - R a n k)
(6 items)
Dict i o n a ry
(6 ite m s )
"" lte m 5 (Group - Warp Factor)
Dictionary
Stri ngsTa Ыe
'У PreferenceSpecifiers
JiJ>. ltem О ( Group - Genera l l nfo)
...
•
...
•
2 (Text Field - Authorization
"" ltem 4 (Toggl e Switch - Warp
Dictionary
'У ltem 6 ( S l ider)
Туре
Кеу
Defau ltVa l u e
M i n i m u mVa lue
MaximumVa l u e
M i n i m u mVa l u e l mage
M a x i m u mVal uelmage
D i c t i o n ary
...
•
...
•
...
•
...
•
...
•
...
•
...
"
(4 items)
( 2 items)
(7 items)
Stri n g
PSSliderSpecifier
String
warpFactor
N u m ber
Number
N u m be r
5
10
Stri n g
turtle
String
rabblt
Рис . 1 2 . 2 6 . З а в е р ш е н н ы й в и д эл е м е нта I t em 6 , п редста вл я ю щ и й
Ползун о к с п и ктогра м м а м и ч е р е п ахи и крол и ка н а кон цах дл я обозна­
ч е н и я замедл е н и я и ускорен и я соответстве н н о
Сохран ите с п исок свойств, а затем постройте и запустите дан ное п р ило­
жен и е на в ы пол не н ие, чтобы убедиться , что оно фу н кцион и рует должн ы м
образом . В таком случае в ы сможете войти в приложе н и е Sett i ngs и найти
ползунок со с пя щей черепахой и счастл и в ы м крол и ком на разных его кон цах
(рис. 1 2 .27).
456
ГЛАВА 1 2 ;i• НАСТР О Й К И П Р ИЛОЖЕ Н И Й И ПОЛ ЬЗО ВАТЕЛ ЬСКИ Е НАСТРО Й К И ПО УМОЛЧАНИ Ю
carrlor .
il'hol111 8• - JOS 10.Q (14Щ97с).
< Settings
10:58 АМ
Brldge Control
-
GENERAL !Nro
Commanding Officer Кirk
Authorization Code
Rank
Сар1а111
Wзrp Drive
Wд!IP FACТOR
Рис . 1 2 . 2 7 . Те п е р ь у н а с есть поля реда к ­
тирова н и я и м н огознач н ы е пол я , перекл ю ч а ­
тел ь и ползун о к , и м ы бл и з к и к заве р ш е н и ю
Добавление дочернего представления настроек
Добави м еще один с пецифи катор глобал ьных параметров настройки, чтобы
дать приложению Settings команду отобразить дочернее представление настроек.
Этот спецификатор будет п редставлять строку с раскры вающим инди катором
продолжения, после касания которого откроется совершенно новое представле­
ние с глобал ьн ы м и параметрами настройки.
Поскол ьку этот новый глобал ь н ы й параметр настройки не должен находить­
ся в одной группе с ползун ком, скопируем сначала груп повой спецификатор из
элемента I t em О и вставим его в кон це массива P r e f e renceSpe c i f i e r s , что­
бы создать новую группу для дочернего представления настроек. С верн ите все
открытые элементы в списке Roo t . p l i s t, а затем щел кн ите на элементе I t em
О, чтобы выбрать его. Нажм ите комби нацию клавиш <Х+С>, чтобы скоп ировать
его в буфер обмена. Выберите элемент I t em 6 и наж м ите комби нацию клавиш
<X +V>, чтобы вставить нов ы й элемент I t em 7 . Раскройте элемент I t em 7 и
дважды щел кн ите на поле в столбце Value рядом с ключом Title, изменив в этом
поле значение Gene r a l I n f o на Addi t i onal I n fo.
ГЛАВА 1 2 .,_ НАСТ Р О Й К И П РИЛОЖЕ Н И Й И ПОЛ ЬЗО ВАТ ЕЛ ЬС К И Е НАСТРОЙ КИ П О У М ОЛЧАН И Ю
457
С верн ите элемент I t em 7 . Выберите его и н ажм ите клавишу <Retum>, чтобы
добавить элемент I t em 8 , я вл яющи йся дочерни м п редставлением . Разверните
элемент I t em 8 , щел кнув на раскры вающем треугол ь н и ке. Найдите строку с
кл ючом Ту ре и задайте в ней значен ие P S Ch i l d Pa n e S p e c i f i e r, а в строке
с ключом Title - значение Mo re S e t t i n g s . Осталось добавить в элементе I t em
8 последнюю строку, чтобы сообщить приложению Settings, какой именно с п и­
сок свойств следует загрузить дл я представления Mo re S e t t i n g s . Итак, добавь­
те еще одну дочернюю строку с кл ючом File и значен ием More (для этого можно
изменить последнюю в группе строку с Кеу на File; рис. 1 2 .28). Для файла со
списком свойств предполагается расширение . р 1 i s t, и поэтому у казы вать его
не нужно (есл и вы укажете расширение, п риложение Settings не найдет файл
со списком свойств).
Кеу
У i Phone Settings Schema
StringsTaЫ e
• PreferenceSpecifiers
..,. ltem О (Group - General lnfoJ
"
"
"
"
Тур е
Va lue
Stri ng
Root
Dictionary
( 2 itemsJ
Dictionary
Array
Dictionary
..,. ltem 1 (Техt Field - Commanding
Dictionary
"" ltem 2 (Техt Fleld - Authorization
"" ltem З (Multi Va lue - Rank)
Dictionaгy
..,. ltem 5 ( G roup - Warp Factor)
Dictionary
D ictio nary
"" ltem 4 (Тogg l e Switch - Warp
..,. ltem 6 (Sl ider)
lt e m 8 ( C h i l d Рапе - Маге
Туре
Title
Кеу
File
"
•
(4 items}
(2 ltems)
String
More Settings
String
"
(6 ite m s )
(4 items)
"
•
(6 itemsJ
Dictionary
Stri ng
•
(5 items}
(7 items)
"
•
(9 itemsJ
Dictionary
Dictionary
"" ltem 7 (Gro u p - Additional l nfo)
•
(2 itemsJ
String
(2 items)
PSC h i l d Pa neSpecifier
More
Рис. 1 2 . 28. З а в е р ш е н н ы й в и д эл е м е нтов I t em 7 и I t em 8 , п ред­
ставл я ю щих группу п а р а м ет р о в н астр о й к и Add i t i o n a l I n f o и
с с ы л ку на доч е р н е е о к н о , с в я з а н н о е с файл о м Mo r e . p l i s t соот­
ветстве н н о
Добавим дочернее представление к главному представлению глобал ьных па­
раметров настройки. Параметры настрой ки в этом дочернем представлени и оп­
ределяются в файле Mo re . p l i s t , поэтому мы дол жн ы с ко п ировать его в пакет
настроек. Но м ы не можем добав ить в пакет новые файл ы в среде Xcode, а
диалоговое окно Save редактора списка свойств не позволяет сохранить файл в
пакете. Поэтому придется создать новый сп исок свойств, сохранить его в какой­
нибудь папке, а затем перетащить ее в папку S e t t i n g s . bund l e непосредственно
в окне Fi nder. Чтобы упростить создание дочернего представления, скопируйте
458
ГЛАВА 1 2 111!. НАСТРО Й КИ П Р ИЛОЖЕН И Й И П ОЛЬЗО ВАТЕЛ ЬС К И Е НАСТРОЙ К И ПО УМОЛЧАН И Ю
файл Root . p l i s t , присвойте ему новое имя, удал ите все существующие на­
стройки, за исключением первой, и добавьте в него те настройки, которые не­
обходим ы для вашего приложения . Для того чтобы сэконом ить усил ия, можете
просто перетащить файл Mo re . p l i s t из папки 1 2 - Image s с исходны м кодом
примеров, в папку S e t t i ng s . bund l e непосредственно в окне Finder, которое
было оставлено открытым, и оставить его рядом с файлом Root . p l i s t . ,
М ы заверш ил и форми рован ие пакета настроек. С ком п илируйте, запустите на
в ыпол нение дан ное приложение и проверьте досrуп ность его глобал ьных пара­
метров настройки в приложе н и и Settings. В конечном итоге м ы должны доб­
раться до дочернего п редставления и установить з начения для всех остал ьных
полей . Поэкспериментируйте с этим представлением и по желанию внесите из­
менения в список свойств .
ПОДСКАЗКА. М ы рассмотрели почти все возможн ые варианты поле й . П ол ное о п исан ие
форм ата с п и ска свойств дл я хра н е н и я настроек можно н айти в руководстве Settings
App/ication Schema Reference , доступном на са йте IOS Dev Center. П олуч ить э тот доку­
мент ( и немало других пол езных с п равочн ых до кументо в ) можно по адресу h t t p : / /
deve lope r . app l e . com/ l ibra r y / i o s / n a v i ga t i on / .
Прежде чем п родолжить рабоrу, выберите папку As s e t s . xca s s e t s в окне
навигатора проекта и скопируйте файл ы изображений rabЬ i t . png и t u r t l e .
png из пап ки 1 2 - Ima g e s с исходн ы м кодом при меров, прилагаемым к этой
книге, в левую часть области редактирован ия. В итоге эти изображения пиктог­
рам м будут введе н ы в дан н ы й проект как новые, готовые к употреблению ре­
сурсы . М ы еще воспол ьзуемся и м и в рассматри ваемом здесь приложении, чтобы
отобразить значения текущих настроек.
Вероятно, в ы заметил и, что две п и ктограм м ы , которые вы тол ько что до­
бавил и, точ но такие же, как и те, которые был и добавлен ы в пакет настроек
раньше. Возн и кает вопрос: а зачем их дубл ировать? Напомним, что приложения
под управлением системы iOS не могут сч иты вать файл ы из "песоч н и ц" других
приложе н и й . Дело в том , что пакет настроек становится частью "песоч н и цы"
приложения Settings, а не рассматри ваемого здесь п риложения. Но поскол ьку
эти п и ктограм м ы требуется испол ьзовать и в дан ном п риложен ии, их нужно
отдел ьно добавить в пап ку B r idge Cont r o l , чтобы скопировать их и в "песоч­
н и цу" дан ного приложения .
Чтение настроек из приложения
Для чтения пол ьзовательских настроек воспол ьзуемся классом Use rDe faul t s
(N SU s e r D e f a u l t s ), реал изованн ы м как одноэлементн ы й класс. Это означает,
что в данном приложе н и и будет существовать тол ько оди н экзе м пляр класса
U s e rDefaul t s . Чтобы получ ить досrуп к этому единственному экзем пляру, не­
обходи мо вызвать из этого класса метод s t andard ( ) следующим образом :
l e t de f a u l t s = U s e r De f a u l t s . s t a n d a r d ( )
ГЛАВА 1 2 111 НАСТРОЙ К И П РИЛОЖЕ Н И Й И ПОЛЬЗОВАТЕЛ Ь С К И Е НАСТР О Й К И П О УМОЛЧАНИ Ю
459
И мея указател ь на стандартные пол ьзовател ьские настройки, воспол ьзуемся
им таким же образом, как это делается в словаре типа D i c t i onary. Чтобы про­
читать из него значение, достаточно вызвать метод obj ect ( forKey : ) , возвра­
щающий объект типа S t r i ng ил и Founda t i on, например Date (NSDa te ) ил и
Numbe r ( N SNumbe r ) . Есл и же требуется извлечь с калярное значение наподо­
бие int, f l o a t ил и Boo l ean, то достаточно вызвать соответствующи й метод:
i nt ( forKey : ) , f l oa t ( fo rKey : ) или bool ( forKey : ) .
При составлении списка свойств для данного приложения в файл с рас шире­
нием . p l i s t был введен масси в спецификаторов типа P r e f e rence Spec i f i e r s .
Одни спецификаторы были использованы в приложении Settings дл я составле­
ния групп, а другие - для создания и нтерфейс н ы х объектов для орган изаци и
взаи модействия с пол ьзователем . Н ас и нтересуют именно эти последние спе­
цифи каторы, поскол ьку именно они обеспечи вают хранение реальных дан н ы х
настроек. Кажды й спецификатор, которы й был связан с каким-н ибудь парамет­
ром пол ьзовател я, и м еет кл юч под названием Кеу . Например, кл юч Кеу для
ползунка имеет значение wa rpfactor, ключ Кеу для поля Authorization Code
autho r i z a t i onCode . М ы воспол ьзуемся этим и кл ючами для извлечения пол ь­
зовател ьских настроек.
В место того чтобы воспол ьзоваться с и м вол ь н ы м и строками для каждого
кл юча в рассматри ваем ых далее методах, м ы определи м для их значен и й ряд
констант. Этим и константами м ы м ожем воспол ьзоваться в коде данного при­
ложения вместо встраи ваемых с и м вольных строк, чтобы исключить опечатки
при их вводе. Эти константы должны б ыть установлены в отдел ьном исходном
коде на языке Swift, поскол ьку мы собираемся воспол ьзоваться и м и еще не в
одном классе. Перейдите в среду Xcode, нажм ите комбинацию клавиш <X+N>
и выберите в окне создан ия файлов сначала подраздел Source в разделе IOS, а
затем шаблон Swi ft F i l e и щелкните на кнопке Next. Присвойте новому файлу
имя Con s t a nt s . swi f t и щелкните на кнопке Create. Откройте вновь создан­
ный исходный файл и в ведите в нем строки кода, приведенные в л истин ге 1 2 . 1 .
-
Л исти нг 1 2 . 1 . К онстанты
let officerKey = 11 officer 11
let authori zationCodeKey = 11 authorizationCode 11
let rankKey = 11 rank 11
let warpDriveKey = 11warp 11
let �arpFactorKey = 11 warpFacto r "
l e t favori teTeaKey = 11 favori teTea 11
let favori teCaptainКey = " favori teCaptai n "
l e t favori teGadgetкey = " favori teGadget "
let favoriteAl ienKey = 11 favoriteAl ien "
Эти константы служат ключам и для доступа к различным полям глобал ьных
параметров настройки в файле с расширением . p l i s t . Теперь, когда есть место
для отображения настроек, быстро установим главное представление с рядом ме­
ток. Прежде чем переходить в I nterface Bui lder, создадим выходы для всех нужных
460
ГЛАВА 1 2 '"* НАСТРО Й К И П РИЛОЖ Е Н И Й И П ОЛ ЬЗОВАТЕЛ ЬС К И Е НАСТРОЙ К И ПО УМОЛЧАНИ Ю
нам меток. С этой цел ью щелкн ите на исходном файле F i r s tViewContro l ler .
swi f t и внесите в него изменения, показанн ые в л истин ге 1 2 .2.
Л исти нг 1 2 . 2 . Добавление выходов в файл F i r s tVi e wCont r o l l e r . swi ft
c l a s s Fi r s t V i ew C o n t r o l l e r : U I V i e wCon t r o l l e r {
@ IBOutlet var officerLaЬel : UI LaЬel !
@ IBOutlet var authori zationCodeLaЬel : UI LaЬel !
@ IBOutlet var rankLaЬel : UILaЬel !
@ IBOutlet var warpDriveLaЬel : UI LaЬel !
@ IBOutlet var warpFactorLaЬel : UI LaЬel !
@ IBOutlet var favori teTeaLaЬel : UI LaЬel !
@ IBOutlet var favori teCaptainLaЬel : UI LaЬel !
@ IBOutlet var favori teGadgetLaЬel : UI LaЬel !
@ IBOutlet var favori teAl ienLaЬel : UI LaЬel !
Как видите, в этом коде нет для нас ничего нового. М ы л и ш ь объя вил и де­
вять свойств с помощью кл ючевого слова @ I BOut l e t, чтобы связать их метка­
м и в l nterface Builder. Сохран ите внесенные изменен и я . Теперь, когда выходы
объявлены, можно перейти к файлу рас кадровки дл я создания графического
пол ьзовател ьского и нтерфейса данного приложения .
Создание главного представления
Выберите файл раскадровки Ma i n S t o rybo a r d . s t o ryboard, чтобы отредак­
тировать его в l nterface B u i lder. Таки м образом, слева появится контроллер пред­
ставления панел и вкладок, а справа один за други м - контроллеры представлений
двух вкладок. Верхний контроллер служит для п редставления первой вкладки и
реализуется в классе Fi r s tVi ewCont ro l l e r, а нижний контроллер - для пред­
ставления второй вкладки и реал изуется в классе S e condVi ewCont ro l l e r.
В ведем сначала ряд меток в представление типа F i r s tViewCont ro l l e r, как
показано на рис . 1 2 .29. В общем, их должно быть 1 8 . Первая их половина слева
на экране должна быть в ы ровнена по п равому краю и в ыделена полужирны м
шрифтом , а вторая половина справа на э кране должна служить для отображе­
н и я кон кретных значений, извлекае м ы х из пол ьзовател ьских настроек, и поэ­
тому они дол жн ы быть связаны с соответствующи м и входам и . Все вносимые
здесь изменен ия будут сделаны в контроллере п редставления первой вкл адки,
расположенном справа вверху на раскадровке.
Разверните сначала узел главной сцены (Ma in Scene) в окне Document Outline,
а затем элемент Vi ew. В итоге вы обнаружите три дочерних представления, уже
находящихся на своих местах. Удал ите все эти представления. Затем переименуй­
те элемент View на Ma i n Vi ew. Далее перетащите объект Label из библиотеки
объектов, о пустив его у левого верхнего края данного представления. Перетащи­
те метку к левому краю о кна (ил и хотя бы к голубой направля ющей линии сле­
ва), а затем расширьте ее прав ы й край по направлению к центру представления,
как показано на при мере метки O f f i ce r на рис. 1 2 .29. Перейдите к инспектору
атрибутов, выровня йте текст метки по правому краю и выберите для него шрифт
ГЛАВА 1 2 1< НАСТР О Й К И П Р ИЛОЖ Е Н И Й И ПОЛЬЗОВАТЕЛ ЬСКИ Е НАСТРО Й К И П О УМОЛЧАН И Ю
461
System Bold 1 5 . Нажм ите клавишу <Option> и перетащите метку вниз, чтобы
создать еще восемь ее коп и й . А ккуратно выровняйте метки, чтобы образовать из
них левый столбец. Измените текст меток в соответствии с рис. 1 2 .29.
Maln
Oft1cw:
L1Ье1
Author1atlon Code:
UЬе1
Wlll"P Drhr8:
1.8Ьеt
Aenk:
W8rp Factor:
FIVOflte Тм:
1.аЬеl
UЬе1
UЬе1
Fevonte C8pt81n:
1.аЬе1
Fwortte Ahn:
UЬе1
Fevortte 08dget:
-
1.аЬе1
1
Рис. 1 2 . 2 9 . В и д к о н т р ол л е ра п р едстав ­
л е н и я п е р в о й в кл адки в о к н е п р о г ра м м ы
l nte rface B u i l d e r с 1 8 введе н н ы м и м етка м и
Построить прав ы й столбец немного проще. Перетащите еще одну метку из
библиотеки объектов в текущее представлен ие, расположив ее с права от м ет­
ки O f f i cer и остави в между н и м и небол ьшой промежуток. В ыберите для тек­
ста этой метки шрифт System 1 5 в и нспекторе атрибутов. Н ажм ите клавишу
<Opt�on> и перетащите метку вн из, чтобы создать еще восем ь ее коп и й . Акку­
ратно выровня йте их по меткам в левом столбце.
Теперь нам нужно задать огран и чения A uto Layout. С этой цел ью свяжи­
те вместе две верхние метки, нажав клавишу <Contro l> и перетащи в метку
O f f i c e r к метке справа. Отпустите кноп ку м ы ш и и нажм ите клавишу <Shift>.
Выберите команды Horizontal Spacing и Baseline из вспл ы вающего меню, а затем
щел кн ите за пределами этого меню. Сделайте то же самое в остальных восьми
рядах меток, попарно связав их вместе.
462
ГЛАВА 1 2 111 НАСТРОЙ К И П Р И Л ОЖ Е Н И Й И ПОЛЬЗОВАТЕЛ ЬС К И Е НАСТР О Й К И ПО УМОЛЧАН И Ю
Далее нужно зафиксировать расположение меток в левом столбце относительно
левого и верхнего краев представления. С этой цел ью перейдите в окно Docu ment
Outline, нажмите клавишу <Control> и перетащите указатель от метки O f f i cer к
представлению Ma i n View. Отпустите кнопку мыши, нажмите клавишу <Shift> и
выберите команды Leading Space to Container Marg i n и Vertical Spacing to Тор Lay ­
out Guide из вспл ывающего меню, а затем нажмите клавишу <Retum>. СдеJ/аЙте
то же самое с остальн ы м и восемью метками в левом столбце.
В закл ючение нужно зафиксировать ширину меток в левом столбце. Для это­
го выберите метку O f f i c e r и щел кните на кнопке P i n , расположенной ниже ре­
дактора раскадровки. Установите флажок Width в откры вшемся окне и щел кните
на кноп ке Add 1 Constra i nt. Повторите эту же процедуру для всех остал ьных
меток в левом столбце.
Теперь огран ичения должн ы быть правил ьно наложены на все метки . Вы­
берите контроллер представления Ma i n в окне Docu ment O u tl i n e и вы пол н ите
команду Ed itorq Resolve Auto Layout l ssues q U pdate F rames из меню Xcode (есл и
этот режим не активизирован, знач ит, все метки уже находятся на своих местах
в раскадровке). Если все пройдет нормал ьно, то все метки займут свое оконча­
тел ьное положение.
Далее метки в правом столбце нужно связать с их выходам и . С этой цел ью
откройте исходный файл F i r s tVi ewCont r o l l e r . s w i f t в окне помощн и ка ре­
дактора, нажм ите клавишу <Control> и перетащите указател ь от верхней мет­
ки в правом столбце к выходу o f f i ce rLabe l , чтобы связать их вместе. Снова
нажм ите клавишу <Control> и перетащите указател ь от второй метки в правом
столбце к выходу a u t ho r i z a t i onLab e l , повторяя эти действия до тех пор,
пока все метки в п равом столбце не окажутся связан н ы м и со свои м и выходам и .
Сохран ите внесенные изменения в файле раскадровки Ma i n . s t oryboard.
Обновление контроллера представления первой вкладки
Выберите в среде Xcode файл F i r s tViewCont r o l l e r . s w i f t и введите в
кон це его класса код из л истинга 1 2 .3 .
Листин г 1 2 . З . Демонстрация дан н ых в полях меток
func r e f r e s h Fi e l d s ( ) (
l e t de f a u l t s = U s e r De f a u l t s . s t a n d a r d
o f f i c e r La b e l . t e x t
d e f a u l t s . s t r i n g ( f o r K e y : o f f i c e r Ke y )
a u t h o r i z a t i o n C o d e L a b e l . t e x t = d e f a u l t s . s t r i n g ( fo r K e y :
a u t h o r i z a t i o n C o d e Ke y )
r a n kLabe l . t e x t
de f a u l t s . s t r i ng ( f o r Ke y : r a n k Ke y )
w a r p D r i v e L a be l . t e x t
de f a u l t s . b o o l ( f o r Ke y : w a r p D r i v e Ke y )
? " E n g a g e d " : " Di s a Ы e d "
w a r p Fa c t o r La be l . t e x t = de f a u l t s . ob j e c t ( f o r Ke y : w a r p F a c t o r Ke y ) ? .
s t r i ngVa l u e
favo r i t e T e a Lab e l . t e x t = d e f a u l t s . s t r i n g ( f o r Ke y : f a vo r i t e T e a Ke y )
favo r i t e Capt a i nLabe l . t e x t = de f a u l t s . s t r in g ( f o rKey : favo r i teCap t a i n Ke y )
f a vo r i t eGadg e t Lab e l . t e x t = de f a u l t s . s t r i n g ( f o r Ke y : favo r i t eGadge t Ke y )
f a vo r i t eAl i e n L a b e l . t e x t = de f a u l t s . s t r i ng ( f o r Ke y : f a vo r i t eAl i e n Ke y )
=
=
=
ГЛАВА 1 2 % НАСТРО Й КИ П РИЛОЖЕ Н И Й И ПОЛЬЗО ВАТЕЛ Ь С К И Е НАСТРО Й К И П О УМОЛЧАН И Ю
463
ove r r i d e f u n c v i e wW i l lApp e a r ( _ a n ima t e d : Bo o l ) {
s up e r . v i e wW i l lAppea r ( a n i ma t e d )
r e f r e s h F' i e l d s ( )
Вряд л и в этом коде есть что-н ибудь для вас непонятное. Н о в ы й метод,
re fre s h F i e l d s ( ) , лишь собирает пол ьзовательские настройки по умолчанию и
устанавли вает в свойстве text всех меток соответствующий объект из пол ьзова­
тел ьских настроек по умолчанию, используя значения ключей, введенные нам и
ранее в файл списка свойств с расширен ием . p l i s t . Обратите вни ман ие, что
дл я ссыл ки warpFacto rLabe l вызы вается метод s t r i ngVa lue ( ) из возвраща­
емого объекта. Все остал ьные глобальные параметры настройки представлен ы
символ ь н ы м и строками, которые возвращаются из пол ьзовател ьских настроек
по умолчанию в виде объектов типа S t r ing. Но глобал ьный параметр настрой­
ки, сохраняем ы й ползун ком, возвращается в в иде объекта типа NSNumber, по­
этому для него вызы вается метод s t r i ngVa l u e ( ) , чтобы получ ить строковое
представление числового значения, которое он содержит.
После этого переопределяется метод viewDidApp ea r ( ) из суперкласса, а в
нем вызы вается метод r e f r e s h F i e l d s ( ) . Благодаря этому значения, отобража­
емые для пол ьзователя, обновл я ются вся кий раз, когда поя вляется представле­
ние. Это происходит при запуске данного приложения на вы пол нение и возврате
пользователя из второй вкладки к первой.
Запустив теперь дан ное п р иложения на в ы пол нен ие, вы должны увидеть
пол ьзовательский интерфейс, созданн ы й вам и для первой вкладки, хотя некото­
рые ил и все поля в нем окажутся пусты м и . Не волнуйтесь, это не програм мная
ошибка, а правил ьное поведение. П р и ч и н ы и порядок устранения этого недо­
статка обсуждаются ниже, в разделе "Регистрация значен и й по умолчанию".
Изменение пользовательских настроек
по у м олчанию непосредственно из п риложения
Поскол ьку главное представление находится в рабочем состоя нии, займемся
построением пол ьзовател ьского интерфейса для второй вкладки. Как показано на
рис. 1 2 .30, на второй вкладке находятся переключател ь Warp Engi nes и ползунок
Warp Factor. Воспол ьзуемся тем и же сам ы м и элементам и управления, что и в
приложении Settings, для построения перекл ючателя и ползунка. Пом имо вхо­
дов, мы должны объя вить метод r e f r e s h F i e l ds ( ) таким же образом, как это
уже было сделано в классе F i r s tVi ewCont rol l e r, а также два метода, которые
будут вызываться при касани и этих элементов пол ьзовател ьского и нтерфейса.
Выберите исходн ы й файл S e condVi ewCont r o l l e r . swi f t и внесите в него
изменения, выделенные н иже полужирным шрифтом .
c l a s s S e condV i ewCo n t r o l l e r : U I V i e w C o n t r o l l e r
@ IBOutlet var engineSwi tch : UI Swi tch !
@ IBOutlet var warpFactorSl ider : UI Sl ider !
464
ГЛАВА 1 2 wi НАСТРО Й К И П Р И Л ОЖ Е Н И Й И П О Л Ь З О ВАТЕЛ Ь С К И Е НАСТРОЙ КИ П О УМОЛЧАН И Ю
о
•
11
Рис . 1 2 . 30. П острое н и е контроллера п р едста вл е ­
н и я вто рой в кладки в п рогра м м е l nterface B u i ld e r
Сохран ите внесе н н ые вам и изменения и выберите файл рас кадровки Ma i n
S t o ryboa r d . s tor yboa rd, чтобы отредактировать графический пол ьзователь­
ский и нтерфейс в программе I nterface B u i lder. На этот раз м ы удел им основное
внимание сцене настроек (Settings Scene) в окне Document Outline. Нажм ите кла­
вишу <Option> и щел кните на раскры вающем треуголь н и ке, чтобы развернуть
элемент Settings Scene и все расположенные ниже элементы . Найдите элемент
View и удал ите все его дочерние узл ы . В ы берите элемент View и откройте окно
инспектора атрибутов . Измените цвет фона, выбрав вариант Light Gray Color из
раскры вающегося с п иска Background.
Далее перетащите две метки из библиотеки стандартн ых объектов в раскад­
ровку. Перетащите их на контроллер сце н ы S e t t i ng s S cene, расположенный
справа внизу на раскадровке. Дважды щел кн ите сначал а на одной из меток, из­
менив ее текст на Warp E n g i n e s : , а затем на другой метке, измен ив ее текст на
Warp Fact o r : . В качестве образца можете пользоваться рис. 1 2 . 3 0 .
Перетащите перекл ючател ь из библиотеки стандартн ы х объектов в правую
часть текущего представления, размести в его напротив метки Warp En g in es : .
ГЛАВА 1 2 1.1! НАСТРОЙ К И П РИ Л ОЖЕ Н И Й И ПОЛ ЬЗОВАТЕЛ Ь С К И Е НАСТРОЙ К И П О УМОЛЧА Н И Ю
465
Нажав клавишу <Control>, перетащите указател ь от п иктограм м ы View Control­
ler в верхней части сцены Settings S ce n e к новому перекл ючател ю, а затем
соеди н ите его с выходом eng i n e Swi t ch. После этого откройте исходный файл
S e c o n dV i e w C o n t r o l l e r . s w i f t в помощн и ке редактора, н ажм ите клавишу
<Control> и перетащите указатель от перекл ючател я в точ ку, расположе н ную
чуть выше строки кода @ end в кон це дан ного файла. Отпустите кнопку мыши и
создайте действие e n g i neSwi t chTapped, оставив без изменения все остальные
значения, выбираемые в откры вшемся окне по умолчанию.
Перетащите ползунок из библ иотеки стандартны х объектов, расположив его
ниже метки Wa rp F a c t o r : . Измените размеры ползун ка таки м образом, что­
бы он занял весь промежуток между двумя голубы м и направляющи м и л и н и я м и
слева и с права. Нажав клавишу <Control>, перетащите указател ь о т п и ктограм­
мы View Controller в верхней части сцены Scene приложения Settings к ползун­
ку, а затем соеди н ите его с выходом warpFa c t o r S l i d e r . С нова нажм ите кла­
вишу <Control> и перетащите указател ь от ползунка в конец исходного файла
S e condVi ewCon t r o l l e r . swi f t . Отпустите кнопку м ы ш и и создайте действие
warpS l ide rTouched, оставив без изменения все остал ьные значения, выбирае­
м ые в откры вшемся окне по умолчан ию.
Щелкн ите на ползунке, есл и он еще не выбран, и откройте окно и нспектора
атрибутов. Установите в поле Minimum значение 1 . 0 0, в поле Maxi mum - значе­
ние 1 0 . 0 0 , а в поле Current - значение 5 . 0 0 . Затем выберите вариант turt l e
из раскры вающегося с п иска Min l mage и вариант rabЬi t из раскры вающегося
списка Мах l mage. Есл и эти варианты отсутствуют в соответствующих раскры ва­
ющихся списках, перетащите файлы изображений в папку As s e t s . xcas s e t s .
Для того чтобы заверш ить пол ьзовател ьский и нтерфейс второй в кл адки, пе­
ретащите кноп ку из библ иотеки стандартн ы х объектов, опустив ее у нижнего
края текущего п редставления, а затем пере и менуйте ее на Open Settings Appli­
cation . Нажм ите клавишу <Control>, перетащите указател ь от новой кнопки к
строке кода, следующей сразу за определением метода onWwa rpS l iderTouched
в исходном файле S e c o ndVi ewCon t r o l l e r . s w i f t , а затем создайте действ ие
o n S e t t i n g Bu t t onTapped. Мы еще вернемся к дан ной кнопке в кон це этой
главы .
Настало время установить огран ичения Auto Layout. Сначал а выберите файл
раскадровки Ma i n . s t o r yboa rd, затем перейдите в окно Docu ment Outline, на­
жм ите клавишу <Control>, перетащите указател ь от метки Wa rp E n g i n e s к ее
роди тел ьскому п редставлению и отпустите кнопку м ы ш и . Н ажм ите клавишу
<Shift> и выберите команды Leading Space to Container Margin и Ver1ical Spacing
to Тор Layout Gu ide из вспл ы вающего меню, а затем нажм ите клавишу <Return>,
чтобы наложить выбран ные ограничения. Повторите эту же процедуру для мет­
ки Warp Fac t o r .
Нажм ите клавишу <Contro\>, перетащите указател ь от перекл ючател я к пред­
ставлен и ю Ma i n V ie w и отпустите кнопку м ы ш и . Н ажм ите клави шу <Sh ift>
466
ГЛАВА 1 2 111. НАСТРО Й К И П РИЛОЖЕ Н И Й И П ОЛ ЬЗ О ВАТЕЛ Ь С К И Е НАСТРО Й К И ПО УМОЛЧАН И Ю
и выберите ком анды Trailing Space to Container Margin и Vertical Spacing to Тор
Layout Guide из вспл ы вающего меню, а затем нажм ите клавишу <Return> . Еще
раз нажм ите клавишу <Contro\>, перетащите указател ь от ползунка к представ­
лению Ma i n View и отпустите кнопку м ы ш и . Нажм ите клавишу <Shift> и выбе­
рите команды Leading Space to Container Margin, Trailing Space to Container Margin
и Vertical Spacing to Тор Layout G uide, а затем нажм ите клавишу <Return>. ,
Наконец нужно зафиксировать положение кнопки в н ижней части представ­
ления. С этой цел ью нажм ите клавишу <Contro\>, перетащите указател ь от
кноп ки к п редставлению Ma i n View и отпустите кноп ку м ы ш и . Нажм ите клави­
шу <Shift> и выберите команды Vertical Spacing to Bottom Layout Gu ide и Center
Horizontally i n Container, а затем нажм ите клавишу <Return>. На этом процесс
создания ограничений Auto Layout заканчивается . Теперь выберите контроллер
п редставления в окне Document Outline и выпол н ите команду Editorc:> Resolve
Auto Layout l ssues c:> U pdate Frames в меню Xcode. Убедитесь, что представление
содержит все необходимое элементы .
Теперь заверш и м создание контроллера представления настроек. Откройте
файл S e condVi ewCont ro l l e r . s w i f t и в ведите в нем код представленный в
листин ге 1 2 .4.
Л истинг 1 2 . 4 . Методы r e f r e s h Fi e l ds и v i e wWi l lAppear
для контроллера S e condViewCont ro l l e r
ove r r ide f u n c v i e wW i l l App e a r ( _ a n im a t e d : B o o l ) {
s u p e r . v i e wW i l lApp e a r ( a n i ma t e d )
refreshFields ( )
func r e f r e s h F i e l ds ( ) {
l e t de f a u l t s = U s e r De f a u l t s . s t a n d a r d
e n g i n e S w i t c h . i s O n = de f a u l t s . b o o l ( f o r Ke y : w a r p D r i ve K e y )
w a r p Fa c t o r S l i de r . va l u e = d e f a u l t s . f l o a t ( f o r K e y : w a r p F a c t o r Ke y )
Далее в ведите следующие строки кода в методы onEng i n e Sw i t chTapped ( )
и onWa rp S l i de rTouched ( ) .
@ I BAc t i o n f u n c o n E n g i ne S w i t ch T a p p e d ( _ s e n de r : AnyOb j e c t )
l e t d e f a u l t s = U s e r De f a u l t s . s t a nd a r d
de f a u l t s . s e t ( e n g i n e S w i t c h . i s O n , f o r Ke y : w a r p D r i v e Ke y )
@ I BAc t i on f u n c onWa r p S l i d e r D r a g g e d ( _ s e nde r : AnyOb j e c t ) {
l e t d e f a u l t s = U s e r De f a u l t s . s t a n d a r d
de f a u l t s . s e t ( wa r p F a c t o r S l i d e r . va l u e , f o r Ke y : w a r p Fa c t o r Ke y )
Как только поя вляется представление данного контроллера (например, после
выбора вкладки), вызы вается метод r e f r e s h F i e l d s ( ) . В трех строках кода из
тела этого метода сначала получается ссыл ка на пол ьзовател ьские настройки
по умолчанию, а затем выходы к перекл ючателю и ползунку испол ьзуются для
ГЛАВА 1 2 � НАСТР О Й К И П РИЛОЖЕН И Й И П ОЛ ЬЗ О ВАТЕЛ Ь С К И Е НАСТР О Й К И П О УМОЛЧАНИ Ю
467
отображения в этих элементах управления значен и й, сохраняемых в пол ьзова­
тел ьских настрой ках по умолчанию. М ы также реал изовал и методы действия
onEng ineSwi t chTapped ( ) и onWa rpS l ide rTouched ( ) , чтобы заполнить пол ь­
зовател ьские настройки значениями из этих элементов управления после того,
как пользовател ь изменит их.
Запусти в теперь данное п риложение на в ы пол нение, перейдите на вторую
вкладку, откорректируйте значения представленных на ней параметров настрой­
ки и понаблюдайте за тем, как внесенные вам и корректив ы отразятся на содер­
жимом первой вкладки после возврата к ней.
Регистрация значени й по ум олчанию
Мы создал и ранее пакет настроек, вкл ючая настройки по умол чанию для
некоторых значе н и й, чтобы п редоставить приложе н и ю Settings досту п к гло­
бал ьным параметрам настройки рассматри ваемого здесь приложения . Мы также
настроил и приложение Bridge Contro l на доступ к этой же и нформации через
графический пользовател ьский и нтерфейс, чтобы пол ьзователь мог ее видеть и
править. Но м ы упустил и из виду следующее обстоятел ьство: дан ному приложе­
нию н ичего неизвестно о значениях, задаваемых в пакете настроек по умолча­
нию. В этом можно убедиться, удал и в приложение Bridge Control из с и мулятора
или мобильного устройства iOS, на котором оно выпол нялось, а следовател ьно,
и хранящиеся там глобал ьные параметры настройки данного приложения, после
чего запусти в его снова в среде Xcode. При повторном запуске для всех настро­
ек приложение вы ведет на экран пустые пол я . Исчезнут даже значения, зада­
ваем ые по умолчанию для дви гателя искривления пространства, которые м ы
определ ил и в пакете настроек. Перейдя к приложению Settings, вы обнаружите
значения по умолчанию, но есл и вы не измените эти значения в приложении
Setti11gs, то н и когда не увидите их в приложении Bridge Contro l .
Причина, по которой настро й ки п о умолчан и ю исчезают, закл ючается в
том, что дан ному приложению н ичего неизвестно о пакете настроек, который
их содержит. Именно поэтому, когда приложение п ытается прочитать значение
по кл ючу warpFa c t o r из объекта типа U s e r De f a u l ts и не находит по это­
му ключу н икакой сохраненной информации, оно ничего не вы водит на экран .
П равда, в классе U s e r D e f a u l t s и м еется метод r e g i s t e r ( ) , позвол я ющий
указать значения по умолчанию, которые должны быть обнаружены, есл и пара
"ключ-значен ие" не была задана. С этой цел ью дан н ы й метод лучше всего вы­
зы вать при запуске приложения на выполнен ие. Итак, выберите исходный файл
AppDe l e gate . swi ft и внесите в тело метода app l i ca t i on ( : didFini shLau
nchi ngWi thOp t i o n s : ) изменения, выделенные ниже полужирным шрифтом .
f u n c app l i c a t i on ( a pp l i ca t i o n : U I App l i c a t i o n ,
d i d F i n i s h L a u n c h i n gW i t hOp t i o n s l a u n c h Op t i o n s : [ N S Ob j e c t : AnyOb j e c t ] ? ) - >
Bool {
1 1 Т оч ка замеще н и я дл я н а с т р о й ки приложе ния п о сл е запуска
l e t defaults = [ warpDriveKey : true , warpFactorKey : 5 ,
favori teAl ienКey : "Vulcan " ]
468
ГЛАВА 1 2 t:!. НАСТРО Й К И П Р ИЛОЖЕН И Й И П ОЛ ЬЗ О ВАТЕЛ ЬС К И Е НАСТРО Й К И ПО УМОЛЧА Н И Ю
UserDefaul ts . s tandard . reqi s ter ( defaults )
return t rue
С начала в дан ном методе создается словарь, содержащий три пары "кл юч­
значе н ие": по одной на кажд ы й кл юч, досту п н ы й в приложе н и и Settings и
требующи й значение по умол чанию. Определен н ы е ран ьше имена кл ючей ис­
пол ьзуются здесь для того, чтобы искл юч ить опечатки . Затем весь словарь пе­
редается методу r e g i s t e r ( ) стандартного э кзем пляра класса U s e rDe faul t s .
С этого момента дан н ы й э кзем пля р будет предоставлять значения, заданные
здесь по умолчанию, при условии, что другие значения не были заданы ни в
дан ном приложении, ни в приложении Settings.
На этом разработка рассматри ваемого здесь п риложения завершается. С ком­
пилируйте и запустите его на в ыпол нение. Оно должно в ы глядеть так, как по­
казано на рис. 1 2 .6, за искл ючением, разумеется, значений, которые вы ввели в
приложени и Settings.
ЗАМ ЕЧАНИЕ. Дл я того ч то б ы удал ит ь п рил оже н и е , щ ел к н и те на его п и ктогр а м м е на
главном экране устро й ства и удерживайте , пока п и ктограм м а на начнет покачиваться .
З атем отпустите к н о п ку м ы ш и и щ ел к н ите на крестике в л е во м верхне м углу п и кто­
грам м ы п р ил ожен и я .
Суровая действительность
Запустите дан ное приложение на вы полнение, просмотрите его настройки, а
затем нажм ите главную кнопку и откройте приложение Settings, чтобы настро­
ить значения некоторых параметров. Еще раз нажм ите главную кнопку, снова за­
пустите дан ное приложение на в ыполнение, и здесь, возможно, вас ждет непри­
ятн ы й сюрприз. Вернувшись в дан ное приложение, вы не увидите измененных
настроек. Они остались такими, каким и и были, отражая прежние значения.
Дело в том, что в системе iOS нажатие кнопки Home при активном приложе­
н и и не означает завершение этого приложения. Операцион ная система в таком
случае переводит п р иложение в фоновый режи м, оставляя его готовым к новой
активизаци и . Эта особенность систе м ы iOS отл и ч но подходит для перекл ю­
чения между приложе н и я м и , поскол ьку время, требующееся для акти визаци и
приостановленного приложения, намного короче по сравнению с тем временем,
которое понадобилось бы для его запуска с самого начала. Н о в дан ном слу­
чае нам нужно вы пол н ить доработки, чтобы после "пробуждения" приложение
получало "встряску", перезагружало пол ьзовател ьские настройки и отображало
содержащиеся в них значения.
Подробнее о п р иложен иях, работающих в фоновом режиме, речь пойдет в
главе 1 5, а пока рассмотрим л и ш ь самые основы того, как уведом ить приложе­
ние, что оно снова активизировано. Для этого зарегистрируем все классы конт­
роллеров на получение уведомления, которое посылается приложен ием при его
выходе из состоя ния приостановлен ного в ы полнен и я .
469
ГЛАВА 1 2 v.ц НАСТРО Й К И П Р И Л ОЖ Е Н И Й И П О Л Ь З ОВАТЕЛ Ь С К И Е НАСТРО Й К И ПО УМОЛЧАН И Ю
Уведомление педставляет собой упрощенн ы й механизм, которым могут пол ь­
зоваться объекты для общения. Л юбой объект может определить одно или не­
сколько уведомлений, которые он будет передавать в центр уведомлени й дан ного
приложения. Этот центр представляет собой объект, существующий л и ш ь в одном
экземпляре и тол ько для того, чтобы передавать уведомления между объектам и .
Уведомление можно рассматривать как признак того, что произошло некоторое
событие. Объекты, публ и кующие уведомления, в кл ючают в свою документа­
цию с писок возможных уведомлени й . Например, объект типа U I App l i ca t i on
публи кует разные уведомления (их можно найти внизу страницы из документа­
ции на Xcode, где описывается класс U IApp l i ca t i on). Назначение большинс­
тва уведомлени й можно, как правило, определить по их и менам, а за допол­
н ител ьн ы м и сведен иями можно обратиться к соответствующей документаци и .
Рассматри ваемое здесь приложение должно обновлять изображение перед
своей активизацией, поэтому нас и нтересует уведомлен ие U IApp l i c a t i onW i
l l Ente r Fo r e g roundNo t i f i ca t i on . М ы изменим метод vi ewWi l lAppe a r ( ) ,
чтобы зарегистрироваться на получение дан ного уведомления и указать центру
уведомлений на необходимость вызвать дру гой метод, когда данное уведомле­
ние поступит. Итак, введите в исходные файл ы F i r s tViewCont r o l l e r . swi f t
и SecondVi ewCont ro l l e r . swi f t следующий код.
f u n c app l i c a t i onWi l l E n t e r Fo r e g r o u n d ( n o t i f i c a t i o n : N S N o t i f i c a t i on )
l e t de f a u l t s = U s e r De f a u l t s . s t a n da rd
de f a u l t s . s yn c h r o n i z e ( )
re f r e s h F i e l d s ( )
Сам по себе этот метод довольно прост. Он получает ссыл ку на объект пол ь­
зовател ьских настроек по умол чанию и вызы вает метод s ynchron i z e ( ) вы­
нуждающий механизм U ser Defau lts сохранять любые несохранен ные изменения
и перезагружать любые неизмененные настройки из оперативной памяти . По су­
ществу, мы вы нуждаем эту систему повторно считы вать сохранен н ые настрой­
ки , чтобы иметь возможность собрать все изменения, внесенные в приложении
Settings. Затем вызы вается метод r e f r e s h F i e l d s ( ) , испол ьзуе м ы й в каждом
классе для обновления изображения.
Теперь нам нужно орган изовать регистрацию каждого контроллера для по­
лучения интересующего нас уведомления. С этой целью в ведите в ыделенные
ниже полужирн ы м строки кода в теле метода vi ewWi l lAppe a r : в файлах
Firs t ViewContro l l e r . sw i f t и S e c o ndVi ewCon t r o l l e r . swi f t .
,
let арр = UIApplica tion . shared ( )
Noti ficationCenter . defaul t . addObserver ( self , selector :
# selector ( self . appl icationWi l lEn terForeground ( notificati on : ) ) ,
name : Noti fication . Name . UIApplicationWi llEnterForeground ,
obj ect : арр)
С начала м ы получаем ссыл ку на экзе м пл я р рассматри ваемого здес ь при­
ложения, а затем испол ьзуем ее для регистраци и на получение уведомления
470
ГЛАВА 1 2 .i\jf. НАСТР О Й К И П РИЛОЖЕ Н И Й И ПОЛЬЗО ВАТЕЛ Ь С К И Е НАСТРО Й К И П О УМОЛЧАН И Ю
UIApp l i ca t i onWi l l EnterForegroundNot i f i cat ion с помощью стандартного
экзем пляра класса NSNot i f i ca t i onCe n t e r и метода addOb s e rve r ( _ : s e lec­
tor : name : obj e c t : ) . Этому методу передаются следующие дан н ые.
№
В качестве первого аргумента (observer) передается ссылка s e l f, обозна­
чающая, что класс контроллера сам я вляется объектом, который должен быть
уведомлен (для каждого класса контроллера это делается в отдельн о сти).
?/
В качестве второго аргумента ( s e l ector) передается селектор только что на­
писанного метода appl icationWi l lEnterForeground ( ) , предписывая цен­
тру уведомлений вызвать этот метод, когда уведомление будет отправлено.
ii�
В качестве третьего параметра (app l i ca t i o nWi l l E n t e r Fo r e g round )
передается и м я уведомления, в получении которого м ы заи нтересованы .
&3
В закл ючение в качестве последнего аргумента (арр ) , передается объект,
от которого ожидается уведомление. В качестве этого аргумента передает­
ся ссылка на данное приложение. Есл и же в качестве четвертого аргумен­
та передать пустое значение n i l , то уведомление U IApp l i ca t i onWi l l En
t e r For e g roundNot i f i ca t i o n будет поступать вся кий раз, когда любой
метод отправляет его .
Итак, м ы позаботил ись о б обновлении изображения, но нам нужно подумать
и о значениях, которы м и запол н я ются пользовател ьские настрой ки по умолча­
н и ю, когда пол ьзовател ь манипул и рует элементам и управления в дан ном при­
ложении. М ы должны обеспечить надежное сохранение этих значений в храни­
лище, прежде чем управление будет передано другому приложению. Для этого
проще всего вызвать метод s ynchron i z e, как только настрой ки изменятся, вве­
дя в ыделен ную н иже полужирны м шрифтом строку кода в каждом из новых
методов действия в исходном файле S e c o ndVi ewCont ro l l e r . swi f t .
@ I BAct i o n f u n c o n E n g i n e Sw i t chTapped ( _ s e n de r : AnyOb j e c t )
l e t de f a u l t s = U s e r De f a u l t s . s t a n d a r d
de f a u l t s . s e t ( e n g i n e S w i t c h . i s O n , f o r Ke y : wa rp D r i ve Ke y )
defaul ts . synchroni ze ( )
@ I BAc t i o n f u n c onWa rp S l ide r D r a g g e d ( _ s e nde r : AnyOb j e c t ) {
l e t de f a u l t s = U s e r D e f a u l t s . s t a n d a r d
d e f a u l t s . s e t ( w a rp Fa c t o r S l i de r . va l ue , f o r Ke y : w a rp Fa c t o r Ke y )
defaul ts . synchroni ze ( )
ЗАМЕЧАНИЕ. В ыз ов метода s ynchron i z e ( ) - п отенциал ьно затратная оп ерация , по ­
скол ьку пол ное содержи мое пол ьзовател ьс ких настроек в оперативной памяти подле­
жит сравнени ю с тем , что записано в хранили ще . Когда п риходится и меть дело сразу
с бол ь ш и м кол ичество м парам етров и требуется гарантировать, что их изменение и
запоми н а н и е будут п рои сходить синхрон но , то лучш е все г о постараться свести к м и ­
н имуму обращен и я к методу s ynchron i z e ( ) , чтобы пол ное сравнение вы пол н ялось
снова и с нова . Но вызо в этого метода в ответ на каждое действие пол ьзовател я , как
это делается в да н ном случае, заметно н е скажется н а п роизводител ьности .
ГЛАВА 1 2 н НАСТРОЙ К И П Р ИЛОЖ Е Н И Й И П ОЛ ЬЗОВАТЕЛ Ь С К И Е НАСТРО Й К И П О УМОЛЧА Н И Ю
47 1
Нужно обратить вни мание на еще оди н момент, чтобы данное приложение
работало как следует. Как вам должно быть уже известно, следует освободить
оперативную пам ять, выделяемую для перемен ны х, есл и они бол ьше не нужны ,
а также выпол н ить ряд других служебн ы х о пераций по оч истке. Система уве­
домлений - еще одна область, в которой нужно "после себя убрать". Для этого
достаточ но сообщить стандартному экзем пляру класса Not i f i c a t i onCent e r,
что получать уведомления бол ьше не требуется . Есл и в дан ном случае м ы за­
регистрировал и каждый контроллер п редставления, чтобы наблюдать за кон­
кретн ы м уведомлением в его методе v i e wW i l lApp e a r ( ) то должны снять
контроллер с регистрации в соответствующем методе v i e w D i d D i s appe a r ( ) .
Поэтому введите в обоих исходн ых файлах, F i r s tViewCont r o l l e r . s w i f t и
SecondVi ewCont ro l l e r . swi ft, следующий метод:
,
ove r r i de f u n c v i e w D i d D i s appe a r ( a n im a t e d : Bo o l ) {
_
s upe r . v i e w D i d D i s a p p e a r ( a n ima t e d )
No t i f i c a t i o n C e n t e r . de f a u l t . r emoveOb s e r ve r ( s e l f )
Обратите в н и мание н а то, что снять контроллер с регистраци и для по­
луч е н и я ко н кретн ы х уведомлен и й можно с п о м о щ ь ю метода r e m o v e
Ob s e rve r ( : name : o b j e c t : ) , передав ему те же значен ия, которые испол ьзо­
вались для регистрации наблюдателя за уведомлен и я м и . И все же приведенный
выше метод удобен : он может гарантировать, что центр уведомлений совершен­
но забудет о набл юдателе, причем независимо от того, для получения скол ьких
уведомлений он был зарегистрирован .
Соберите и запустите дан ное приложение на вы пол нение и понабл юдайте
за тем, что произойдет при переходе из него в приложение Settings и обратно.
Изменения, внесен ные вам и в приложении Settings, должны теперь сразу отра­
зиться в данном приложении, как тол ько вы к нему вернетесь.
П ереключение в приложение Settings
Для того чтобы перейти из приложения Bridge Contro l к его настройкам в
приложении Settings, нужно вернуться к начальному экрану, запустить приложе­
ние Settings на вы пол нен ие, найти элемент Bridge Control и выбрать его. Это на­
стол ько дл ител ьная и неудобная процедура, что во м ногих приложениях предо­
ставляется свой экран настроек, чтобы пол ьзовател ь не проходил все эти этапы .
Н е луч ше л и направить пол ьзователя сразу н а экран настроек в самом п рило­
жении Setti ngs? Оказы вается, такая возможность существует. Пом ните о кноп­
ке Open Settings Application, введенной нам и в контроллере представления типа
Se condVi ewCont ro l l e r и показан ной на рис. 1 2 . 3 0? Мы связал и ее с методом
onS e t t i ngButtonC l i c ked ( ) в данном контроллере представления, но не ввел и
ни какого кода в тело этого метода. Добавьте в метод s e t t i ngBut tonC l i c ked ( )
следующий код.
472
ГЛАВА 1 2 �" НАСТР О Й К И П Р ИЛОЖЕ Н И Й И ПОЛ ЬЗОВАТЕЛ ЬС К И Е НАСТРО Й К И ПО УМОЛЧАН И Ю
@ I BAc t i o n f u n c o n S e t t i n g s B u t t onTapped ( _ s e n de r : AnyOb j e c t ) {
l e t app l i c a t i on = U I App l i c a t i o n . s h a r e d ( )
let url
URL ( s t r i n g : U I App l i c a t i o nOp e n S e t t i n g s U RL S t r i ng ) ! a s URL
i f app l i c a t i o n . c a n OpenURL ( u r l ) {
app l i c a t i o n . op e n ( u r l , op t i o n s : [ " " : " " ) , comp l e t i o n H a n d l e r : n i l )
=
В этом коде и с пол ьзуется с истем н ы й U R L, хран я щи йся в кон станте
UIApp l i ca t i onOpe n S et t i ng s URLS t r i ng (она фактически содержит значение
app- s e t t ings : ) для запуска приложения Settings на выпол нение непосредствен­
но из контроллера представления . Запустите рассматри ваемое здесь приложение
на вы пол нение, перейдите на вторую вкладку и щелкн ите на кнопке Open Set­
tings Application. Произойдет непосредствен н ы й переход к экрану настроек данно­
го приложения, как показано на рис. 1 2 .3 . Это значител ьное усовершенствование.
В системе iOS 9 существует еще более удобная возможность. На экране Settings
можно увидеть маленькую кнопку, позволяющую вернуться непосредственно в
ваше приложение (рис. 1 2 .3 1 ) . Теперь можно без п роблем переходить из прило­
жения Bridge Control в приложение Settings и обратно, изменяя значения и следя
за их воздействием на пол ьзовательский и нтерфейс приложения.
( Settings
Вrl dge Control
OENEIW. INFO
Commanding Officer .Jenny
Authorization Code • • • • •
Rank
Commander
Warp Orive
WАЯР fАСТОА
- ----'IOOITIONAL INf()
Моrе Settings
Рис . 1 2 . 3 1 . Ко гда п р ил оже н и е Sett i n g s отк р ы вается и з
п р иложе н и я B r i d g e Contro l , на п а н е л и состоя н и я появляется
к н о п ка , позвол я ю щая вернуться п р я м о в ваше п риложе н и е
ГЛАВА 1 2
.····
НАСТ Р О Й К И П РИЛОЖЕН И Й И ПОЛ ЬЗО ВАТЕЛ ЬС К И Е НАСТР О Й К И П О УМОЛЧАНИ Ю
473
Р е з ю ме
Надеемся, вы хорошо освоил и приложение Settings и механизм U ser Defau lts.
Теперь вы знаете, как добавить пакет настроек в свое приложение и как создать
иерархию представлени й . Из этой главы вы также узнали, как считы вать и за­
писы вать настройки средствам и класса U s e r De faul t s и как разреш ить пол ь­
зователю изменять значения параметров из своего приложения. В ы даже осво­
или шаблон нового п роекта в среде Xcode. Словом , с таким багажом знан и й
и нав ы ков вы должн ы справиться п рактически с л юбой задачей, связан ной с
настрой кам и приложения.
ГЛ АВА 1 З
О с н о в ы дол го в р е м е н н о го
х р ан е н и я д а н н ых
До сих пор м ы бол ьше уделял и внимания таким аспектам парадигм ы МУС
(Model-View-Co11troller), как контроллер и представление. Несмотря на то что не­
которые наши приложения считывали данные из специального пакета. только при­
ложение Bridge Co11trol из главы 1 2 сохраняло данные в постоянном хранилище.
Остальные наши приложения при каждом очередном запуске использовали одни и
те же данные. До поры до времени такой подход нас устраивал, но в реальном мире
приложения должны сохранять данные. Если пользователь внес изменения, то, как
правило, он хотел бы, чтобы они не исчезали при повторном запуске программ ы .
Для сохранения дан ных н а iОS-устройствах существуют разл ичные механиз­
м ы . Есл и вы програм м ировал и в объектно-ориентирован ной среде разработки
приложений Сосоа для систем ы macOS, то, вероятно, вам приходилось испол ь­
зовать некоторые из этих методов. В этой главе м ы рассмотри м четыре механиз­
ма, обеспеч ивающих долговременное хранение данных в файловой системе iOS:
11i
''�
it:
списки свойств;
архивы объектов (или архивирование);
SQL iteЗ (встроен ная реляцион ная база дан ных iOS);
Соге Data (и нструмент для обеспечения дол говременного хранения дан­
ных, разработан н ы й ком панией Apple).
Мы напишем приложения, которые реал изуют все четыре подхода.
ЗАМЕЧАНИЕ. С пис ки свойс тв , архивы о бъекто в , SQLiteЗ и Core Data - не единс твен н ы е
возможности сохранени я дан н ы х в Ю S -ус тро йс т вах. П росто о н и са м ы е по пул я р н ы е
и просты е . У вас все гда ес ть возможность и сп ол ьзовать дл я счи т ы в а н и я и з а п ис и
дан н ы х такие тради ционные С - функции в вода - в ы вода , как fopen ( ) . Можете также
п р и б егнут ь к н и з коуровневым и нструмен там управлени я файлам и , п редоставляе м ы м
технологие й Сосоа . Однако почти во всех случаях э то приведет к увел ичени ю о бъе ­
мов кодировани я , которое редко удается оправдать .
476
ГЛАВА 1 3 """ О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО ХРАН Е Н И Я ДАН Н ЫХ
" П есо ч н и ца " прил ожен и я
Все четыре механ изма обесnечения дол говремен ного хранения дан ных, рас­
сматри ваемые в этой главе, испол ьзуют оди н важн ы й общи й элемент: папку
Docume n t s вашего приложения . У каждого приложения есть собствен ная пап­
ка Docume n t s , которую приложениям разрешается испол ьзовать для чте1-1,ия и
записи.
Для более предметного разговора рассмотри м , как приложения орган изова­
н ы в системе iOS, изучив макет nапки в си муляторе i Phone. Откройте каталог
Libra ry, содержащийся в вашей домашней паnке. В системе OS Х 1 0.6 и более
ран них версиях это не было проблемой, но в верси и OS Х 1 О. 7 ком пания Apple
реш ила сделать пап ку Library скрытой по умолчанию, поэтому, для того что­
бы ее увидеть, nридется приложить немного допол нительных усилий. Откройте
окно Finder и перейдите к домаш ней папке. Есл и вы видите паn ку Library отл и чно. Есл и же нет, н ажм ите клавишу <Option> и в ы nол н ите команду
Go� Library. Команда Library остается скрытой, nока не нажата клавиша <Option>.
Откройте в n anкe L i b r a r y nодкатал о г D e ve l o p e r / C o r e S imu l a t o r /
Devi ce s . В этом каталоге в ы увидите nодкаталоги для каждой верс и и систе­
мы iOS, nоддержи ваемой текущей и нсталля цией среды Xcode. И мена этих nод­
каталогов nредставляют собой глобал ьно у н и кальные идентифи каторы (G U I D),
автоматически генерируемые системой Xcode, nоэтому no ним невозможно до­
гадаться, какому симулятору они соответствуют. Н айдите в каждом nодкаталоге
файл devi ce . pl i s t и откройте его. В нем вы найдете ключ, соответствующи й
назван ию си мулируемого устройства. На рис. 1 3 . 1 nоказано содержимое файла
devi c e . p l i s t, соответствующего си мулятору i Pad Pro.
�
_._OA
708FDF'
-.D
89Aь6o- • --d� _.._
Jll OA80Sl304- 0А91 7692 •
089350А0-. Е8764Е515 •
11 1 0 7 7D8Э2 !9FDF868A •
1 Е48АСАБ f683ЗЕЕ78
1 Е08018С 885ЕОЕСВ9
1 FOF9 1 A 7-. МS80СЕС
02А7\1Е 1 8· C01 H IF4f
2Е3С6871 Е3762А88А
ЗАЗСС84F" 4005СВЗ5
3EF8C865-
A068EFC5
4MD9F22. Е28С2 С 1 7 7
4АСб0264 3.M�F70438
48А.83342 F28C8F84A
4C261EDЗ.-B2De70CB1
•
•
----- -
-- -
- · • PP \ e . c•IOTD1/"rope r t v Lt s t • t . t . d t d " "
<ekey,..IJD JO«/ke�
<• t r
•
•
•
•
•
s t r ing-.
•
s t r!ng>
•
<e/dJ.c t -.
4EC2F388- •. 0gf18430 •
501A41EF·-ABaAOOAC •
бЕОS14080 D283380AO •
8ACC'ii1 В ACПЭSIFOB "
1t19>SOtM t(F�C911-i662 �at10�2МiaA88AIOot.C <е/ s t r 1F'IQ"'
<ekep-NvtceTypeco/ke�
< 1 t rtl\O»<O- . •рр\е. CoreS �\ator. Siм�v iceType. iP8d -fll r•<CJ
coke�Мlle"' /kep
c 1 t r1ng,.. 1Pad Pro-c/1trJ.f\O:>­
<ekepru11t U.ec/klfp
c1t r1t1Qкo-. tpp\1. Cor1S 1'111\1tor. S1-Ru11t iм . 1.0S-V-tc/
.r; keY"""S t atec/kep
«.integor> t c / t ntever>
•
•
- -
=��.;:;'��:;\��;L;��;�:;;���j��"PUSТ 1 . 1//04" '"ht tp://
:��:� vtrilon-" t . t"�
c/p\ilt"'
Рис . 1 3 . 1 . Соде рж и м ое файла de v i c e . p l i s t , уста н а вл и вающее соответств ие
между катал огом и с и м ул ятором
В ы берите устройство и откройте каталог da t a , чтоб ы найти nодкаталог
dat a / C o nt a i ne r s / Da t a /App l i ca t i on . Здесь в ы снова обнаружите nодката­
логи с глобал ьно у н и кал ьн ы м и идентиф и каторам и G U I D . В этом случае каж­
дое из них соответствует л ибо заранее и нсталл ированному nриложению, л ибо
ГЛАВА 1 3 О11 О С Н О В Ы ДОЛГО В Р Е М Е Н Н ОГО ХРАН Е Н И Я ДАН Н ЫХ
477
приложению, которое вы пол нялось на симуляторе. В ыберите оди н из подката­
логов и откройте его. Вы увидите то, что показано на рис. 1 3 .2.
con1a1n«t
Oocumtnt1
Llbrary
Medla
Root
1mo
ver
Вun�e
Datt
Shere<J
•
Ajlpll<:ttlOn
81 Plug1nKltPluotn
VPNPlugln
•
1 U;!lirlWZtfBhi!M-. oocu;fnt;-' ---;
•
• Шirtry
3АС2СЗFА "АСЭВ22978 •
• 4Fll1 7 1 70-."1 2409ABF • • 1mp
4FE5F943· "83Е592725
О&А654Е9· ... 890СОО92
68829974·".A8FC5488
•
•
•
•
11 7ЕВ70АО9-. . ЭF77ЕЕВ60 •
111 8ВЕ45А6В-. .92бА68ЗА •
• 9CDB7400 . . C9F 1 2АЗС •
111 9FЗ381 В7- "OOA08F02 •
11 1 8Е52ВА8- OF7114E038 •
7C8DEBF8."03039CЭBF
11 88Е•О27Е - ." Е 1 E9CF7C •
tl 59CDF26F- F898FFFA2 •
• 06788229- ... С2ЕАО 1 ВО •
• 7'E8AODF .llB80887BC '
11 86С8АЕ88 .2D6BF5 6 1 7 •
2 1 А569 1 3 .-В72Е-9879А
"
1 3509Е28 б284Е874D
•
3 7 2A4Cf8. 6F1045058
•
Рис. 1 З . 2 . " П есоч н и ца " дл я п р и л оже н и я на с и м ул яторе
ЗАМЕЧАНИЕ. Поиск вложенно й папки Con t a i ne r s , начиная с пап ки De v i c e s , показан ­
н ой на р и с . 1 3 . 1 , может занять н е кото рое в ре м я . Есл и в ы не видите ее с разу, п ро ­
должа й те п росматри вать список подкатал огов с и м е н а м и G U I D сверху в н и з , и в кон це
концов вы на йде те п а п ку Con t a i ne r s .
Несмотря н а то что этот сп исок п редставляет симулятор, файловая структура
подобна той, которая реал изована в реал ьном устройстве. Для того чтобы уви­
деть песочн и цу для приложения на устройстве, подкл ючите его к вашему ком­
пьютеру Мае и откройте окно Devices в среде Xcode (Window Q Devices). На бо­
ковой панел и окна вы увидите свое устройство. Выберите его и приложение в
табл ице l nstalled Apps. Под табл ицей в ы увидите п и ктограмму в виде шестерен­
ки. Щел кн ите на ней и вы пол н ите команду Show Container из вспл ы вающего
меню, чтобы увидеть содержимое песоч н и цы для приложения (рис. 1 3 . 3 ) . Все
содержимое песоч н и цы можно загрузить на свой ком пьютер Мае. На рис. 1 3 .4
показана песоч ница для приложения townslot2 из книги Молли Маскри (Mol ly
Maskrey) Арр Development Recipes for IOS and watchOS (Apress, 20 1 6).
"Песочница" каждого приложения содержит три вспомогател ьные папки .
.".:!
Document s . Ваше приложение может сохранять свои дан н ые в папке Docu­
me nt s . Есл и вы позволяете своему приложению испол ьзовать файл меди­
, аплеера iTunes, то пол ьзователь сможет увидеть содержимое этой папки
(а также вложенных папок, созданных вашим приложением) в медиаплеере
iTunes и загружать туда свои файл ы .
ПОДС КАЗ КА. Дл я того чтобы сдел ать свое приложение сов местно испол ьзуем ы м , от­
кройте его файл I n fo . p l i s t и добавьте кл юч Application supports iTunes file sha­
ring со значением YES .
478
ГЛАВА 1 3 u О С Н О В Ы ДОЛ ГО В Р Е М Е Н НО ГО Х РА Н Е Н И Я ДАН Н Ы Х
DEVICES
Devlce tnform1tlon
№lme
МollyslPhone 65
Сарас�у
11.18
Model
IPhone 6s
Bettery
SIMULA10RS
App t. тv 1080р
1().0 (l�'r621iЗq)
1P8d Air
1М 114A�Z!J1U)
IPld AJr Z
1\1.О.<tщ�ам
99!1
10.О (14A5261vJ
IOS
ldentlfler
View Oevlce Logs
iPfld Pro (D.7Jncn)
1 .С>/14д5,6М
IPad Pro (12.0 lnch)
10.О 1!4M261ul
GB (2ЭЭ.4 МВ avallaЬlel
Take Screenshot
Pelr&d W1tcll11
Name
�.0{14 6281ul
IP� S
1М 114A\1281ul
IPllCI Retlnil
ln1talr.d Арр1
-·
С LlveRowing
+
-
$
Jdc11tifier
vcrsi(.in
Namn
t1i ATS Utlllty
• 10"1ns1ot2
com.ATS.ATSCompanlon.ATS".
73.О
w .S
1
com ......-.. 101,vnslo12
223
'"'' . : . . ... _ . ,, __ . .
1.0.303
-
Show Container
Oownload Contalner."
Replace Contalner. ..
Рис . 1 3 . 3 . " П есоч н и ца " дл я п р иложе н и я на реал ь н о м устрой стве
townslot2 1 contalner:
Name
"
Documents
Llbrery
Caches
т
Preferences
com.globelteklabs.townslot2.pllst
tmp
Кind
Folder
Folder
Folder
Folder
Flle
Foldtr
J
Done
Рис. 1 3 .4. " П есоч н и ца " дл я п р иложе н и я towns l ot2 на i Phone 6s
ГЛАВА 1 3 i!!t О С Н О В Ы ДОЛ ГО В Р Е М Е Н НОГО ХРАН Е Н И Я ДАН Н Ы Х
479
""' Libra ry. Это еще одно место, в котором ваше п риложение может хранить
свои файл ы . Здесь целесообразно хран ить файлы , которые вы не хоти­
те испол ьзовать совместно с пол ьзователем . Как показано на рис. 1 3 .4,
система создает подкаталоги C a s h и Pre ference s . В последнем каталоге
хран ится файл . p l i s t , содержащий настройки приложения, заданн ые с
помощью класса U s e rD e f au l t s , который м ы обсуждали в главе 1 2 .
;�'
tmp . Каталог tmp - это место, в котором ваше приложение может хра­
нить времен ные файл ы . Файлы, которые содержатся в пап ке tmp, не будут
подлежать резервному коп и рован и ю медиаплеером iTunes в режи ме с и н­
хрон изаци и, но ваше приложение должно нести ответстве н ность за уда­
ление уже ненужных файлов в каталоге tmp, чтобы избежать перегрузки
файловой систем ы .
Определение местоположения каталогов Documents и Library
Несмотря на то что наше приложение находится в папке, и м еющей, каза­
лось бы, произвол ьно выбранное имя, испол ьзуя метод u r l s ( f o r : i n : ) класса
F i l eManager, можно довол ьно легко найти пол н ы й путь к каталогу Document s
для чтения и зап иси своих файлов. Этот класс принадлежит каркасу Foundation,
поэтому его можно испол ьзовать в среде Сосоа для систе м ы OS Х. Сущест­
вуют его варианты , п редназначен н ые для систе м ы macO S . Некоторые из них
возвращают значения, которые не несут полезной информаци и для системы IOS,
потому что ваше приложение не имеет прав доступа к каталогу из-за механ из­
ма обеспечения безопасности, именуемого песочницей. В листи н ге 1 3 . 1 показан
пример кода на языке Swift 3 , обеспечивающего доступ к каталогу Documents.
Листинг 1 3 . 1 . Код для получения указателя NS URL,
ссылающегося на каталог Document s
let urls
F i l eMa n a g e r . de f a u l t . u r l s ( f o r :
. docume n t D i r e c t o r y , i n s : . u s e r Doma i nMa s k )
i f l e t docume n t U r l
urls . first {
p r i n t ( do c ume n t U r l )
=
=
Первый аргумент метода u r l s F o r D i r e c t o r y ( _ : i n : ) у казы вает, какой
каталог м ы и ще м . Все возможн ые знач е н и я определ я ются переч ислением
s e a r chPathD i r e c t o r y; в дан ном случае испол ьзуется значение S e a rchPath
Di rectory . docume n t D i r e c t o ry (сокращенно - . documentDi rectory ) . Это
значиr, что мы и щем каталог Do cume n t s . Второй аргумент определяет домен
или домены (в документаци и ком пан и и Apple они назы ваются doma i nMa s k) ,
которые используются в поиске. Все возможные значения доменов определяют­
ся в переч ислении S e a rchPathDoma i nMa s k. В дан ном случае м ы испол ьзуем
значение . u s e r Doma i nMa s k. В системе IOS этот домен соответствует песочн ице
запущен ного приложения. Метод u r l s ( for : i n : ) возвращает массив, содержа­
щий оди н ил и нескол ько указателей U RL, соответствующих искомы м каталогам
в указан ном домене. В системе iOS каждому п риложению назначается тол ько
480
ГЛАВА 1 3 и О С Н О В Ы ДОЛ ГО В Р Е М Е Н НО ГО ХРАН Е Н И Я ДАН Н ЫХ
оди н каталог Docume n t s , поэтому разум но предп оложить, что метод вернет
толь ко оди н объект класса N SURL, но для подстраховки м ы будем обращаться к
нему как к первому элеменrу масси ва указателей класса N SURL, чтобы распоз­
нать случай, есл и этот масс и в окажется пусты м . На реал ьном устройстве iOS
указатель U RL каталога Docume n t s может в ы глядеть примерно так: f i l e : / / /
va r /mob i l e /Conta i ne r s / D a t a /App l i ca t i on / 6 9BFDDB 0 - E 4A8 - 4 3 5 9 - 8 3 8 2 F 6 DDDF 0 3 1 4 8 1 / Document s / .
М ы можем создать и м я файла в каталоге D i r e c t ory, п рисоеди н и в другую
строку к кон цу пути, который тол ь ко что получ ил и . Воспол ьзуемся методом
appendingPathComponent ( ) из класса N SURL, разработан н ы м как раз для та­
ких целей .
l e t f i l e U r l = t r y d o c ume n t U r l . a p p e n d i n g P a t hComp o n e n t ( " t h e F i l e . t x t " )
ЗАМЕЧАНИЕ. Обработка ошибок в яз ы ке Swift 3 осуществляется так же , как и в других
язы ках, использующих кл ючевы е слова t r y , c a t ch и t hrow.
После этого вызова пере м е нная f i l e URL будет содержать пол н ы й путь
(см . л истин г 1 3 .2) к файлу t h e F i l e . t x t , расположенному в каталоге Docu­
men t s нашего приложения, и мы сможем испол ьзовать этот указатель для созда­
ния файла и в ыпол нения операций чтения и зап иси . Следует подчеркнуть, что
для получения объекта класса N SURL, соответствующего этому файлу, сущест­
вование самого файла не обязательно.
Листин г 1 3 . 2 . П редыдущий метод с первым аргументом
. l ibra ryDi r e c t o r y размещает п риложение в каталоге Library
let u r l s
F i l eM a n a g e r . de f a u l t . u r l s ( f o r :
. l i b r a r y D i r e c t o r y , i n : . u s e r Doma i nM a s k )
i f l e t l ibra ryUrl = url s . f i r s t {
p r i n t ( l i b r a r yU r l )
=
Этот код возвращает указател ь U RL, имеющий примерно такой вид:
i l e : / / / va r /moЬ i l e / Co n t a i n e r s / D a t a / App l i c a t i on / 6 9 B F D D B 0 - E 4 AB - 4 3 5 9 - 8 3 8 2 F 6 DDDF0 3 1 4 8 1 / Library/ .
Можно также задать не один , а нескол ь ко доменов поиска. В этом случае
класс F i l eManager и щет каталог во всех указанн ы х доменах и может возвра­
щать несколь ко объектов класса N SURL . По прич и нам, которые м ы уже объясня­
ли, в с истеме iOS это не очень полезная возможность, но для полноты картины
целесообразно рассмотреть пример, приведе н н ы й в л исти н ге 1 3 .3 .
Листинг 1 3 . 3 . Получение нескольких указателей URL
l e t u r l s = F i l eM a n a g e r . de f a u l t . u r l s ( f o r :
. l i b r a r y D i r e c t o r y , i n : [ . u s e r Doma i nM a s k , . s y s t em Doma i nM a s k ] )
print ( u rl s )
ГЛАВА 1 3 i'.I О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО ХРАН Е Н И Я ДАН Н Ы Х
48 1
В этом примере м ы проси м класс F i l eMa nage r найти каталог L ib r a r y в
пользовател ьском и систем ном доменах, а резул ьтат вернуть в виде масси ва,
содержащего два объекта класса NSURL:
:�
f i l e : / / / va r /moЬ i l e / Co nt a i n e r s / Da t a /App l i ca t i o n / 6 9 B F D DB O - E 4 A8 4 3 5 9 - 8 3 8 2 - F6 DDDF0 3 1 4 8 1 / Libra r y / ;
''' f i l e : / / / S y s t em/ Libra r y / .
Второй указател ь U RL ссылается на систе м н ы й каталог Libra ry, к которому
м ы , конечно, не и меем доступа. Есл и метод возвращает нескол ько указателей
U RL, порядок их следования в возвращаемом масси ве не определен.
Обратите в н и мание на то, как мы записал и значение аргумента i nDoma i n s
в л истин ге 1 3 .3 .
[ . u s e r Doma i nMa s k , . s y s t emDoma i nMa s k ]
Эта конструкция в ы глядит как и н ициал изация масси ва, н о н а самом деле м ы
создаем множество - синтаксические конструкции для и н и циал изации масси ва
и множества в языке Swift совпадают.
Определение местоположения каталога tmp
Получ ить ссыл ку на каталог tmp вашего приложе н ия даже п роще, чем найти
ссыл ку на каталог Document s . Для этого воспол ьзуемся методом NST empo rary
Di rectory ( ) и з каркаса Foundation, которы й возвращает строку, содержащую
пол н ы й путь к каталогу, предназначенному для хранения времен ных файлов в
вашем п риложении. Для того чтобы создать пол ное имя файла, намеченного для
хранения во временном каталоге, сначала оты щем путь к каталогу tmp:
l e t t emp D i r P a t h = N S T empo r a r y D i r e c t o r y ( )
Затем преобразуем строку в U RL и создадим путь к файлу во временном
каталоге, присоединив имя файла к кон цу найденного пути, как показано в л ис­
тинге 1 3 .4.
Л истинг 1 3 . 4 . Добавление пути к URL
l e t t emp D i r U r l = N S U R L ( f i l e U R LW i t h P a t h : t emp D i r P a t h )
l e t temp F i l e U r l = temp D i r U r l . append i n g P a t h C ompo n e n t ( " t emp F i l e . t x t " )
Получившийся указател ь U RL будет выглядеть при мерно так:
f i l e : / / / p r i va t e / va r /mob i l e / Co n t a i n e r s / Da t a / App l i ca t i o n / 2 9 2 3 3 8 8 4 - 2 3 E B 4 2 6 7 - 8 C C 9 - 8 6 D C D 5 0 7 D 8 4 C / tmp / temp F i l e . t x t
Страт еги и сохр а нен и я фа йл о в
Все четыре подхода, которые м ы рассмотри м в этой главе, испол ьзуют фай­
ловую систему iOS . При испол ьзован и и механизма SQLite3 создается один файл
базы дан ных SQLite3 , которой поручается хранен ие и поиск ваш их дан н ы х .
482
ГЛАВА 1 3 � ОС Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО ХРАН Е Н И Я ДАН Н Ы Х
В самой простой форме механизм Core Data берет на себя все фун кции управ­
ления файловой системой. Что касается двух остал ьных механизмов - списков
свойств и архивирован ия, - то в этом случае вам сначала придется решить, как
именно вы собираетесь хранить дан ные: в одном файле ил и в нескол ьких.
Долговременное хранение одн о го файла
Использование одного файла - сам ы й простой вариант, и для м ногих прило­
жен и й он вполне приемлем . Вы начинаете с создан ия корневого объекта - обыч­
но это объект типа Array или D i c t i onary (при испол ьзовани и архивирования
ваш корневой объект может также базироваться на некотором пользовател ьском
классе). Затем напол няете свой корневой объект всеми дан н ы м и, для которых
необходимо обеспечить дол говременное хранение. Всякий раз, когда вам нужно
что-л ибо сохран ить, ваш код перезап исы вает все содержимое этого корневого
объекта в оди н-еди нственный файл . При запуске приложение считывает пол ное
содержимое этого файла в память, а по завершении работы записывает из памя­
ти в файл . Такой подход мы и будем испол ьзовать в дан ной главе.
Недостаток испол ьзования одного файла состоит в том, что вам приходится
загружать все дан ные своего приложения в память и записы вать все эти дан ные
в файловую систему даже при небольших изменениях. Однако есл и ваше при­
ложение собирается управлять дан н ы м и в объеме, не превы шающем несколько
мегабайтов, то этот вариант п рекрасно работает, а его простота, определенно,
облегчит вам жизнь.
Долговременное хранение нескольких файл ов
Ал ьтернати в н ы й подход состоит в испол ьзовани и нескол ьких файлов для
хранения дан ных. Напри мер, приложение электронной почты может сохранять
каждое электрон ное сообщение в отдел ьном файле.
Этот вариант обладает явными преи муществам и . Он позволяет приложению
загружать тол ько те дан н ые, которые затребует пол ьзовател ь (еще одна форма
"лени вой" загрузки), и, есл и пол ьзовател ь внесет изменен ие, приложению при­
дется сохранять тол ько те файл ы, содержимое которых было изменено. Этот
метод также дает вам возможность освобождать память при получен ии уведом­
ления о нехватке памяти . Любой объем памяти, используем ы й дл я хранения
дан ных, с которы м и пол ьзователь в дан н ы й момент не работает, можно вы гру­
зить, а затем снова загрузить из файловой системы, когда поя вится такая не­
обходимость. К недостаткам механизма дол говремен ного хранения нескольких
файлов можно отнести существен ное повышение уровня сложности приложе­
ния. Поэтому пока огран ичимся однофайловым вариантом .
В дальнейшем м ы обязательно рассмотрим особенности всех упомя нутых выше
методов обеспечения долговременного хранения: списков свойств, архивирования
объектов, а также механизмов SQLiteЗ и Core Data. При изучении каждого ва­
рианта будем создавать приложение, испол ьзующее соответствующи й механ изм
сохранения данных в файловой системе устройства. Начнем со списков свойств.
ГЛАВА 1 3 � О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО ХРАН Е Н И Я ДАН Н Ы Х
483
И споль з о в а ние списко в с в о й с т в
В некоторых наш и х п р и мерах п р ил оже н и й уже испол ьзовал ис ь сп иски
свойств, напри мер для определения настроек пол ьзователя в главе 1 2 . С таки м и
сп искам и свойств очен ь удобно работать. И х можно отредактировать вручную
в среде Xcode ил и с помощью приложения Property L i st Ed itor. Для записи в
сп иски свойств и сч иты вания их оттуда можно испол ьзовать экземпляры клас­
сов D i c t i onary и Array, посколь ку словарь или масси в содержит тол ь ко cne­
цuar1ыm.w образом сериал изуемые объекты .
Сериализация списка свойств
это объект, преобразован­
ный в поток байтов, чтобы его можно было сохран ить в файле ил и передать
по сети . Несмотря на то что л юбой объект можно сделать сериал изован н ы м ,
тол ько определенные объекты можно поместить в такие классы коллекций, как
N S D i c t i onary ил и N SArray, а затем сохран ить в списке свойств с помощью
методов w r i t eToURL ( : a t orni ca l l y : ) ил и w r i t e T o F i l e ( : a t orni ca l l y : ) .
Таким способом можно сериал изовать объекты следующих классов :
Сериализован ный объект (serialized object)
-
'"' Array ил и N SAr ray ;
'1!
NSMutaЫeArray;
r.<
D i c t i onary или N S D i c t i ona ry;
1 1'1
NSMutaЬ l e D i c t i onary;
;,;; N S Data;
�
NSMutaЬ l e Da t a ;
:'{;;
S t r ing ил и N S S t r ing;
м�
NSMutaЫ e S t r ing;
"' NSNumЬer;
�
Da te ил и NSDate.
Есл и вы построите свою модель данн ых тол ько из таких объектов, то для
сохранения и загрузки своих данных сможете испол ьзовать сп иски свойств.
ЗАМЕЧАН ИЕ. Методы w r i t e T o U R L ( _ : a t omi ca l l y : ) и w r i t e T o F i l e ( _ : a t omi ­
ca l l y : ) делают одно и то же , тол ько первый м етод требует, чтобы местоположение
фаЙла задавалось объектом класса N SURL , в второй
S t r i n g . Раньше местополо­
жение файлов всегда задавалось в виде строки , но недавно компания Apple стала
отдавать предпочтение классу N S U R L , за искл ючением ситуаций , в которых интер­
фейс прикладного п рограммирования требует указания пути . В нашей книге м ы так и
поступаем . Путь к файлу, местоположение которого задано объектом класса N S URL ,
можно легко получить, обратившись к его свойству path ( с м . первый пример в этой
главе ) .
-
484
ГЛАВА 1 3 'л: О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО ХРАН Е Н И Я ДАН Н Ы Х
Если мя сохранения своих данных вы собираетесь использовать списки свойств,
то выбирайте между классами Array и Dict i onary. Предположим, все объекты,
которые вы помещаете в массив типа Array ил и D i c t i ona ry, я вляются сериали­
зованн ы м и объектами из приведен ного выше списка, тогда вы можете написать
список свойств, вызвав метод w r i t e ( to u r l : URL , atomi ca l l y : Bool ) -> Bool
из экземпляра словаря или массива, как показано в листи нге 1 3 . 5 .
Л истинг 1 3 . 5 . Добавление пути к U R L
l e t a r r a y : NSAr r a y = [ 1 , 2 , 3 ]
l e t ternp D i r P a t h = N S Ternp o r a r y D i r e c t o r y ( )
l e t ternp D i r U r l
N S URL ( f i l e URLW i t h Pa t h : t ernp D i r P a t h )
l e t t ernp F i l e U r l = t ernp D i r U r l . a p p e n d i n g P a t h C ornp o n e n t ( " t ernp F i l e . t x t " )
a r r a y . w r i t e ( t o : t ernp F i l e U r l ! , a t orn i c a l l y : t r u e )
=
ЗАМЕЧАНИЕ. Параметр a t omi c a l l y п редписы вает этому методу записывать да нные
во вспомогател ь н ы й файл , а не в задан н ы й . Есл и запись в этот файл вы пол н илась
успешно, вспомогател ьны й файл будет скопи рован по адресу, заданному первым па­
раметром . Это более безопасн ы й способ записи данных в файл , поскол ьку в случае ,
если п р иложение аварийно заверш ится во время сохра н е н и я , с уществующий файл
(есл и таковой был созда н ) не будет поврежде н . Конечно, такой подход увеличи вает
неп роизводител ьные расходы , но в больш инстве ситуаций такая игра стоит свеч .
П р и испол ьзован и и сп иска свойств воз н и кает одна проблема, связан ная с
тем, что пользовательские объекты невозможно сериал изовать мя сохранения
в списке с войств. Вы также не сможете испол ьзовать другие классы из Сосоа
Touch, которые не указан ы в при веденном выше списке сериал изованных объек­
тов, а это означает, что такие классы, как N S URL, U I Image и U I C o l o r, нельзя
испол ьзовать нап ря мую.
Помимо проблем ы с сериал изацией, хранение всей модел и дан ных в форме
списков свойств означает, что вы не сможете легко создавать производные ил и
вычисляемые свойства (как, например, свойство, представляющее собой сумму
двух других свойств), а некоторые части кода, которые вы предполагали включить
в классы моделей, необходимо перенести в ваши классы контроллеров. С этим и
ограничения м и можно было бы смириться п р и построении простых моделей дан­
ных и простых приложений. Однако в большинстве случаев вашим приложением
будет легче управлять, есл и вы создадите специал изированные классы моделей .
П ростые сп иски свойств могут б ыть полез н ы м и и в сложных приложен иях,
поскол ьку это прекрас н ы й способ вкл юч ить статические данные в свое п рило­
жен ие. Н апример, есл и ваше приложение содержит селектор, то зачастую на­
илучш и й способ в кл ючения мя него списка элементов - создать файл сп иска
свойств и поместить его в папку Re source s своего проекта, а это означает, что
файл будет скомп илирован в составе вашего приложения.
Теперь создадим простое приложен ие, которое для хранения дан ных испол ь­
зует с п иски свойств.
ГЛАВА 1 3 1i:. О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н ОГО ХРАН Е Н И Я ДАН Н ЫХ
485
Первая версия п риложения Persistence
Мы хотим написать програм му, которая позволяет вводить дан ные в четыре
поля редактирования, по завершен и и приложения сохраняет эти поля в файле
р l i s t, а затем перезагружает эти дан ные из файла свойств при следующем
запуске приложения (рис. 1 3 . 5 ) .
.
Line 1 :
Here's 10 the crazy ones.
Line 2 :
The misllts The reЬels.
Line 3:
The trouЫema'<ers
Line 4:
The round pegs in the square holes.
1
2
3
4
5
6
7
8
9
о
$ & @ "
Рис. 1 3 . 5 . П р и л оже н и е Persiste nce
ЗАМЕЧАНИЕ. В приложен иях этой главы м ы не будем тратить время на установку всех
мелочей пол ьзовател ьского и н терфе й с а , как делал и это раньше . Нажатие кнопки
Return , например, не освободит клавиатуру и не переведет вас к следующему пол ю .
Если ж е вы хотите добавить такой " шик" в свое приложение ( а это будет дл я вас хо­
рошей практико й ) , п редлагаем сделать это самостоятел ьно.
В среде Xcode создайте новый п роект с помощью шаблона Single View Ap­
pl ication и сохран ите его под и менем Pe r s i s t e n c e . Этот п роект содержит
все файл ы, которые нам понадобятся дл я написания п р ил оже н и я . Прежде
чем создавать представление с четы рьмя пол я м и редактирован ия, необходимо
486
ГЛАВА 1 3 i1i О С Н О В Ы ДОЛ ГО В Р Е М Е Н НО ГО ХРАН Е Н И Я ДАН Н ЫХ
создать оди н выход. Откройте окно нави гатора п роекта, щел кн ите на файле
Vi ewCont r o l l e r . swi ft и внесите в него следующие изменени я :
c l a s s V i ewCon t r o l l e r : U I V i ew Co n t r o l l e r {
@ IBOutlet var lineFields : [ U I TextField] !
Разра ботка представления для приложения Persistence
Откройте файл Ma i n . storyboard, чтобы отредактировать графический пол ь­
зовател ьский и нтерфейс. В окне редактора I nterface Bui lder вы увидите в окне
редактора сцену View Controiller. Перетащите из библиотеки элемент Text Field и
расположите его у верхней и правой голубы х л и н и й разметки. Откройте инспек­
тор атрибутов. Убедитесь, что флажок Clear When Editing Begins сброшен.
Затем перетащите в окно объект Label и разместите его слева от поля ре­
дактирован ия, испол ьзуя левую голубую л и н и ю разметки, а затем с помощью
горизонтальной голубой л и н и и разметки выровняйте его по пол ю редактирова­
ния. Дважды щел кните на метке и измените ее надпись, напри мер, на Line l : .
В закл ючение измен ите размер поля редактирован ия, испол ьзуя левый маркер
изменения размера, чтобы п рибл изить его к метке. Ориентируйтесь на рис. 1 3 .6.
В ыберите метку и поле редактирования, нажм ите клавишу <Option> и перета­
щите их вниз, чтобы сделать их коп и и . Выберите обе метки и оба поля редакти­
рования, нажм ите клавишу <Option> и перетащите их снова вниз. У вас должно
получиться четыре метки и четыре пол я редактирования. Дважды щел кн ите на
оставш ихся метках и измените их надписи на L i ne 2 : , L i ne 3 : и L i ne 4 : .
Сравн ите резул ьтат с рис. 1 3 .6.
Разместив все четыре поля редактирования и надп иси, перетащите указатель
м ы ш и при нажатой клавише <Control> с п и ктограм м ы View Controller на каждое
из четырех полей редактировани я . С вязав все четыре поля редактирования с
соответствующи м и выходами, сохраните изменения, внесенные в файл Ma in .
s t o ryboard.
Теперь добавим огран ичения Auto Layout, чтобы наш и нтерфейс работал
оди наково на всех устройствах. Проведите соеди н ител ьную л и н и ю от метки
Line 1 к правому краю поля редактирован ия, а затем отпустите кнопку м ы ш и .
Нажм ите клавишу <Sh ift> и выберите п у н кт Horizontal Spacing a n d Baseline, а
затем нажмите клавишу <Return>. Сделайте то же самое для остал ьных трех
меток и полей редактирования .
Затем м ы заф и ксируем позиции полей редакти рован и я . Перейдите в окно
Document Outline, нажм ите клавишу <Contro\>, перетащите указатель от верхне­
го поля редактирования к ее родител ьской п и ктограм ме View, отпустите кноп ку
м ы ш и , н ажм ите клавишу <Shift> и в ыпол н ите команды Trailing Space to Con­
tainer Margin и Vertical Spacing to Тор Layout Guide. Сделайте то же самое для
остал ьных трех полей редактирования .
Нам необходимо заф и ксировать ш и р и ну меток, чтобы о н и не изменялись
при вводе дл и нного текста. Выберите верхнюю метку и щел кн ите на кнопке Pin
ГЛАВА 1 3 i:!; О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО ХРАН Е Н И Я ДАН Н ЫХ
487
под окном редактора рас кадровок. Во вспл ы вающем окне установите флажок
Width и щел кн ите на кнопке Add 1 Constraint. Сделайте то же самое для осталь­
ных меток.
•
ш
-
Line 1 :
Line 2 :
Line 3:
Line 4 :
о
о
Рис . 1 3 . 6 . Разработка п р едста вл е н и я
дл я п р иложе н и я Pe rsi ste nce
В заключение вернитесь в окно Document Outline, нажм ите клавишу <Control>,
перетащите указател ь от метки Line 1 к ее родител ьской пиктограмме View, от­
пустите кнопку м ы ш и и выпол н ите команду Leading Space to Container Margin.
Сделайте то же самое для всех меток. Вот и все - требуемые ограничения Auto
Layщ1t установлены. Выберите п и ктограм му контроллера представления в окне
Document Outline и выпол ните команду Editorc:> Resolve Auto Layout lssues c:> U pdate
Frames в меню Xcode, чтобы удал ить предупреждения из представления Activity.
Соберите и вы пол ните приложение, а затем сравните резул ьтаты с рис. 1 3 .6.
Редактирование классов приложения Persistence
Выберите в навигаторе проекта файл ViewContro l l e r . swi ft и добавьте в
него код из л истинга 1 3 .6.
488
ГЛАВА 1 3 &1' О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н ОГО Х РА Н Е Н И Я ДАН Н ЫХ
Л истинг 1 3 . 6 . П о луч е н и е URL для файла dat a . p l i s t
f u n c da t a F i l e U R L ( ) - > N S U R L {
l e t u r l s = Fi l eM a n ag e r . de f a u l t . u r l s ( f o r :
. do curne n t D i r e c t o r y , i n : . u s e r Dorna i nMa s k )
v a r url : NSURL?
u r l = U R L ( f i l e URLWi t h P a t h : " " ) 1 1 с о з д а ем пустой путь
do {
t r y u r l = u r l s . f i r s t ! . a ppen d i n g P a t hCornp o n e n t ( " d a t a . p l i s t " )
catch {
p r i n t ( " E r r o r i s \ ( e r ro r ) " )
return url !
Метод d a t a F i l eURL ( ) возвращает пол н ы й путь к нашему файлу данных,
определяя местоположение каталога D o c ume n t s и присоеди няя к нему имя
файла. Этот метод должен вызы ваться из л юбого кода, который обеспеч ива­
ет загрузку и сохранение данных. В нем есть небол ьшой недостаток, связан­
н ы й с указателе м U RL . Обратите в н и мание на то, что мы поместил и метод
app e nd i ng P a t h C omp o n e n t в блок d o - c a t c h . М ы сделал и это потому, что
этот метод м ожет вызвать ошибку, которую необходимо перехватить. Однако,
поскол ьку нам известно, что наш пакет приложения должен содержать каталог
Document, и к тому же мы сам и создаем файл da t a . p l i s t, мы не планируем
обработку этой ошибки, потому что код написан правильно. В обычных услови­
ях необходимо уделять вопросам безопасности немного бол ьше внимания, что­
бы приложение не потерпело крах, но для краткости м ы не будем обрабатывать
ош ибки, поскол ьку они не относятся к теме нашего обсуждения.
ЗАМЕЧАНИЕ. В языке Swift для обработки и с кл юч е н и й (ош ибок) испол ьзуется блок
do - c a t ch (его м ожно найти в библ иотеке с н и ппетов Xcod e ) , который следит за вы­
полнением метода , генерирующе го исключение с помощью оператора t h r ow и пе­
рехватывает исключение с помощью оператора с а tch, чтобы п редотвратить крах
приложения .
Найдите метод viewDi dLoad ( ) и добавьте в него следующий код, а также
новы й метод, получающи й уведомление appl i c a t i onWi l l Re s i gnAc t i ve ( ) ,
как показано в л истин ге 1 3 . 7 .
Л истинг 1 3 . 7 . Методы v i ewDidLoad и appl i c a t i onWi l l Re s i gnAc t i ve
ove r r i de f u n c v i e w D i d L o a d ( ) {
s upe r . v i e w D i d Lo a d ( )
1 1 Дополнител ь н а я на с тр о й ка после з а гр у з ки предс т а вл е ни я ,
1 1 обыч но и з n i Ь - файл а .
l e t f i l eU R L = s e l f . da t a Fi l e U R L ( )
i f ( F i l eMa n a g e r . de f a u l t . f i l e E x i s t s ( a t Pa t h : f i l e U R L . p a t h ! ) ) {
i f l e t a r ra y
N SA r r a y ( co n t e n t s O f : f i l e U R L a s U R L ) a s ? [ S t r i n g ]
for i i n О . . < a r ra y . count {
l i n e Fi e l d s [ i ] . text
a r ray [ i ]
=
=
ГЛАВА 1 3 111 О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н ОГО Х РАН Е Н И Я ДАН Н ЫХ
489
l e t арр = U I App l i c a t i o n . s h a r e d ( )
N o t i f i c a t i o n C e n t e r . de f a u l t . a ddOb s e rve r ( s e l f , s e l e c t o r :
* s e l e c t o r ( s e l f . a pp l i c a t i onWi l l Re s i gnAc t i ve ( n o t i f i c a t i o n : ) ) ,
name : N o t i f i ca t i on . N ame . U I App l i c a t i o nWi l l Re s i gnAc t i ve ,
o b j e c t : арр )
f u n c app l i ca t i o nWi l l Re s i g nAc t i v e ( n o t i f i ca t i o n : N S N o t i f i c a t i o n )
l e t f i l eURL = s e l f . d a t a Fi l e U R L ( )
l e t a r r a y = ( s e l f . l i n e Fi e l d s a s N S A r r a y ) . va l u e ( f o r Ke y : " t e x t " ) a s !
NSA r r a y
a r ray . w r i t e ( to : f i l eURL a s URL , atomica l l y : t rue )
В методе v i e w D i dLoad ( ) м ы вы полняем нескол ько о пераций . Сначал а с
помощью метода f i l e E x i s t s ( a t Pa t h : ) класса F i l eManage r м ы проверяем,
существует л и зада н н ы й файл данн ы х, посколь ку приложение ранее могло уже
выпол няться . Метод запраш ивает и м я пути к файлу, который можно извлечь из
свойства path его U RL (к сожалению, для метода, требующего аргумент класса
URL, этот вариант не подходит). Есл и файла нет, то мы не п ытаемся его загру­
зить. Есл и же файл существует, то м ы создаем экзе м пляр массива, запол ня я его
содержим ы м этого файла, а затем коп ируем объекты из этого масси ва в наши
четыре поля редактировани я . Посколь ку массивы - это упорядоченные с писки,
мы копируем их в том же порядке, в каком сохраняли .
Дл я того чтобы прочитать этот файл, м ы испол ьзуем и н и циализатор объектов
класса Array, который создает объект класса N SAr ray на основе содержания
файла. И нициал изатор объектов кл асса Array требует, чтобы содержание фай­
ла имело формат списка свойств. Это хорошо, потому что именно в этом виде
мы и будем его хран ить.
Наше приложение должно сохран ять с вои дан н ы е до того, как оно завер­
шится, или до перехода в фонов ы й режим , поэтому мы заинтересованы в уве­
домлении типа app l i ca t i o nWi l l Re s i g nAc t ive . Это уведомление посылается
тогда, когда пол ьзовател ь больше не собирается взаимодействовать с п риложе­
нием, например если пол ьзовател ь нажал кнопку Home ил и приложение пере­
шло в фонов ы й режим с последующей потенциальной возможностью возврата
в активное состоя н ие, нап р и мер п р и поступлении входящего звон ка. Именно
это пр'оисходит при регистрации уведомлений, поступающих от центра уведом­
лен ий iOS. Этот центр посылает уведомление, вызы вая метод, который заре­
гистрирован для его получения и передавая ему аргумент типа Not i f i c a t i on,
содержащий подробное описание события, вызы вавшего поя вление уведомле­
ния. Для того чтобы зарегистри ровать это уведомление, м ы получаем ссыл ку
на э кзе м пл я р нашего приложения и испол ьзуем ее для п одп иски на объект
класса U I App l i c a t i o nWi l l Re s i g nAc t i v e , испол ьзуя стандарт н ы й э кзем­
пляр класса No t i f i ca t ionCenter и метод addOb s e rve r ( : s e l e ct o r : name :
490
ГЛАВА 1 З t� О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО ХРАН Е Н И Я ДАН Н ЫХ
obj e c t : ) . В качестве первого аргумента передается указател ь s e l f, который
означает, что наш экземпляр класса V i e w C o n t r o l l e r я вляется набл юдате­
лем, ожидающим у ведомление. Второй параметр я вляется селектором метода
app l i ca t i onWi l l Re s i gnAct ive ( ) , которы й при казы вает центру уведомлений
вызвать дан н ы й метод, когда будет опубл и ковано уведомление. Третий пара­
метр, объект класса UIApp l i ca t i onWi l l Re s i gnAct ive, я вляется именем уве­
домления, которое м ы хотим получить. Это строковая константа, определен ная
в классе U I App l i ca t i on.
В закл ючение м ы добавили реал изацию метода app l i c a t i o nW i l l Re s ign
Act i ve ( ) , которы й будет вызываться центром уведомлен и й .
f u n c app l i c a t i onWi l l Re s i g nAc t i ve ( n o t i f i ca t i o n : N S N o t i f i c a t i on )
l e t f i l eURL
s e l f . d a t a Fi l e U R L ( )
let array = ( s e l f . l i ne Fields a s NSAr ray ) . va l ue ( forKe y : " text " ) a s ! NSAr ray
a r r a y . w r i t e ( t o : f i l eURL as U R L , a t omi c a l l y : t r ue )
=
Этот метод довольно простой, но выпол няет большую работу с помощью все­
го нескол ьких вызовов методов. Мы создаем массив строк, вызы вая метод text
для полей редактирования, содержащихся в масси ве l i ne F i e l d s . Для этого мы
испол ьзуем остроумный прием : вместо я вного перебора полей редактирования
в масси ве, запроса их значений и добавления этих значен и й в новый массив
мы приводи м масси в l i ne F i e l d s языка Swift (состоящий из объектов класса
U I Text F i e l d s ) к типу NSAr ray и вызы ваем его метод va lue ( forKey : ) , пере­
давая в качестве параметра строку " t ext " . Реал изация метода va l ue ( forKey : )
в классе NSArray автоматически в ыпол няет перебор элементов массива, запра­
ш ивает у объектов класса U I T e x t F i e l d содержащееся в них значение и возвра­
щает новы й объект класса NSAr r a y, состоящий из всех этих значени й . После
этого зап исываем содержимое этого массива в файл с расш ирен ием . p l i s t .
Осталось толь ко сохранить содержание масси ва в формате списка свойств, ис­
пол ьзуя метод w r i t e (_ to : a t omi c a l l y ) . На этом процедура сохранения дан­
н ы х в формате списка свойств заканчивается .
Подведем итоги . После загрузки основного представления м ы пытаемся най­
ти файл с п иска свойств . Есл и он существует, то копируем из него дан н ые в
поля редактировани я . Затем регистрируемся на получение уведомления о пере­
ходе приложения в неактив ное состоян ие (в резул ьтате л ибо завершения работы,
л ибо перевода в фоновый режим). Когда это происходит, собираем значения из
четы рех полей редактирования, сохраняя их в изменяемом масси ве, и записы ва­
ем этот масси в в список свойств.
С компилируйте и в ыпол н ите прил ожение в симуляторе . После запуска вы
должн ы иметь возможность в водить данн ые в л юбое из четырех полей редак­
тировани я . После ввода тестовой информаци и нажм ите клавиши <X+Shift+H>,
чтобы вернуться на главн ы й экран . Это очень важно. Если просто выйти из симу­
л ятора, это будет эквивалентно принудительному выходу из приложения. В этом
ГЛАВА 1 3 'ti О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО ХРАН Е Н И Я ДАН Н Ы Х
49 1
случае вы никогда не получите уведомление о том, что приложение завершилось,
и ваш и данные не будут сохранен ы . После возвращения на главный экран мож­
но выйти из симулятора ил и остановить приложение из среды Xcode и снова
запустить его. При повторном запуске приложения текст будет восстановлен.
ЗАМЕЧАНИЕ. Важно пом н ить, что возвращение на главны й экран обычно не завершает
п риложение, по крайней мере не сразу. П р иложение переводится в фоновое состо­
яние и готово немедленно повторно активизироваться в случае , есл и пользовател ь
снова вернется к нему. М ы углубимся в детал и этих состояний и их и м пл и каций дл я
выполнения и завершения приложений в главе 1 5 .
Упорядоченные сп иски свойств легко испол ьзовать, но в них может хранить­
ся тол ько огран ичен н ы й круг объектов, поэтому стоит рассмотреть более уни­
версал ьный подход.
А рхивирование об ъ ектов моделей
В среде Сосоа термин архи в и рова н и е (arch iv ing) относится к другой форме
сериал изаци и, но это уже более обобще н н ы й ти п, которы й может реал изовать
любой объект. Кажд ы й объект модели , специал ьно написанн ы й для хранения
дан ных, должен поддерживать архивирование. Метод архивировани я объектов
модел и поз воляет легко записы вать сложные объекты в файл, а затем ч итать
их оттуда. Поскол ьку каждое свойство, которое вы реал изуете в своем классе,
я вляется либо скаляром (как I n t ил и F l o a t), л ибо экзем пля ром класса, кото­
рый соответствует протоколу NSCodi ng, можете архивировать все свои объекты.
Так как больши нство классов из кар касов Foundation и Сосоа Touch, допуска­
ющих возможность сохранения данн ых, действител ьно соответствует протоко­
лу NSCoding (хотя и не без таких заслуживающих внимания искл ючений, как
класс U I Image), архивирован ие и вправду относительно просто реализовать для
больши нства классов.
Несмотря на отсутствие строгого требования на выпол нение архивирования,
вместе с протоколом N S C od i ng должен б ыть реал изован другой протокол, а
именно - протокол NSCopyi ng, который позволяет с копировать ваш объект.
Возможность копирования объекта дает намного бол ьше гибкости при испол ь­
зован и и объектов моделей дан н ых.
П одр.ержка п ротокола NSCoding
Протокол NSCoding объя вляет два метода, и оба они обязател ьны. Один за­
шифровы вает ваш объект в виде архи ва, другой создает новый объект путем
дешифрирован ия архива. Обоим методам передается экзем пляр типа NSCode r,
который требует практически такой же обработки, как и экзе м пляр класса
N S U s e r De f a u l t s , оп исан н ы й в предыдущей главе. Вы можете ш ифровать и
расш ифровы вать как объекты, так и с каляры (переменные типа I nt и F lo a t),
используя коди рова н и е " кл юч-значение " .
492
ГЛАВА 1 3 � О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО ХРА Н Е Н И Я ДАН Н ЫХ
Для поддержки архивирования в вашем объекте необходимо, чтобы он отно­
сился к подклассу класса N SObj e c t ( ил и другого класса, производного от клас­
са NSObj e c t ), а также следует зашифровывать каждую перемен ную экземпляра
в методе e n code r с испол ьзован ием соответствующего метода ш ифрования.
Допустим, мы создали простой контейнерны й класс :
c l a s s MyOb j e c t : N S Ob j e c t , N S C od i n g , N S Cop y i n g {
va r numb e r
О;
va r s t r i n g = " "
va r ch i l d : MyOb j e c t ?
=
o ve r r i de i n i t ( ) {
Этот класс содержит целочисленное и строковое с войства и ссылку на другой
экземпляр того же самого класса. Он я вляется производным от класса NSObj ect
и поддерживает протокол ы NSCoding и N S Copy ing. Метод шифрования может
выглядеть примерно так:
f u n c e n c o d e ( w i t h a C o de r : N S Code r ) {
a C o de r . e n code ( s t r i ng , f o r Ke y : " s t r i n g K e y " )
a C o de r . e n code ( 3 2 , f o r K e y : " i n t K e y " )
i f l e t myCh i l d
chi ld {
a C o de r . e n code ( my C h i l d , f o r K e y : " c h i l dK e y " )
=
Есл и бы кл асс MyOb j e c t был подкл ассом класса, которы й также подде­
рживает протокол N S C o d i ng, нам пришлось бы вызвать метод encode ( wi th
aCode r : ) из его суперкласса, чтобы шифрование данн ы х вы пол нял суперкласс.
В этом случае метод выглядел бы следующим образом :
f u n c e n code ( w i t h a C o de r : N S C o de r ) {
s up e r . e n code ( w i t h a C o d e r : N S C o d e r )
a C o de r . e n code ( s t r i n g , f o r Ke y : " s t r i ng K e y " )
a C o de r . e n code ( 3 2 , f o r K e y : " i n t Ke y " )
i f l e t myCh i l d = c h i l d {
a C o de r . e n c o d e ( m yC h i l d , f o r Ke y : " c h i l dKe y " )
М ы также должн ы создать метод и н и циал изации объекта класса NSOb j ect,
чтобы можно было восстановить ранее заархивированн ы й объект. Этот метод
очень похож на метод encode ( w i t h aCode r : ) . Есл и вы создаете подкласс типа
NSObj ect напрямую или создаете подкласс от другого класса, который не соот­
ветствует протоколу NSCodi ng, ваш метод должен выглядеть так:
r e q u i r e d i n i t ? ( code r a De c o de r : N S Code r ) {
s t r i ng = a Decode r . decodeObj e c t ( f o r K e y : " s t r i ng K e y " ) a s ! S t r i n g
n umb e r
a De c o de r . d e c o de i n t e g e r ( fo r Ke y : " i n t Ke y " )
child
a D e code r . decodeObj e c t ( f o rKe y : " c h i l dKe y " ) a s ? MyOb j e c t
=
=
ГЛАВА 1 3 е< О С Н О В Ы ДОЛГО В Р Е М Е Н Н О ГО ХРАН Е Н И Я ДАН Н ЫХ
493
Этот метод устанавл и вает свойства путем дешифрирован ия значен и й пере­
дан ного методу экземпляра типа NSCoder. Поскол ьку свойство ch i l d исходно­
го объекта равно n i l, мы должн ы вы полн ить допол н ител ьное приведение типа
по время присваи ван ия свойства ch i l d расшифрован ному объекту, поскольку в
заархи вирован ном объекте может не оказаться дочернего объекта.
При реал изаци и протокола N S C o d i ng для класса, производного от класса,
который тоже поддержи вает этот протокол, мы должн ы добавить одну допол­
нительную строку.
r e qu i red i n i t ? ( code r a De c o de r : N S C o de r ) {
s t r i n g = a D e c ode r . decodeOb j e c t ( f o r Ke y : " s t r i n g K e y " ) a s ! S t r i n g
numb e r = a De c ode r . decode i n t e g e r ( f o r K e y : " i n t K e y " )
ch i l d = a De c o de r . d e c odeOb j e c t ( f o r K e y : " c h i l dK e y " ) a s ? MyOb j e c t
s u p e r . i n i t ( c ode : a De c o de r )
Вот в целом и все. Есл и в ы реал изуете эти два метода для ш ифрован ия и
дешифрования всех свойств своего объекта, ваш объект будет поддерживать ар­
хивирование и его можно будет записывать в арх!'l в ы и считы вать оттуда.
Р еализация протокола NSCopying
Как упом иналось в ы ше, соответствие протоколу NSCopying - прекрасная
идея для любых объектов моделей дан ных. Протокол NSCopying содержит ме­
тод с о р у ( w i th z o n e : ) , которы й позволяет коп и ро вать объекты. Реал изация
протокола N S C op y i n g очень напом и нает реал изацию метода i n i t ( code r : ) .
Вам просто необходимо создать новый экзем пляр того же самого класса, а за­
тем установить все свойства нового э кзем пляра рав н ы м и значениям свойств ко­
пируемого объекта. Даже есл и вы реал изуете метод сору ( w i t h z o ne : ) , код
приложения на самом деле будет вызывать метод сору ( ) , который переадресует
операцию методу сору ( wi th z o ne : ) .
l e t a n O b j e c t = M yOb j e c t ( )
l e t o b j e c t Copy = anOb j e c t . с о р у ( ) a s ! MyObj e c t
Н иже показано, как может выглядеть метод сору ( w i th z o n e : ) в классе
MyObj e c t .
n i l ) - > AnyOb j e c t {
func copy ( wi t h zone : NS Zone ?
l e t сору = MyObj e c t ( )
copy . numb e r = numb e r
copy . s t r i n g = s t r i n g
copy . c h i l d
c h i l d ? . copy ( ) a s ? M yOb j e c t
r e t u r n сору
=
Обратите внимание на то, что есл и бы существовала ссыл ка н а дочерний
объект, то нов ы й объект содержал бы коп и ю дочернего, а не базового объекта.
Есл и бы дочерн ий объект и мел неизменяем ы й тип ил и нам требовалась только
494
ГЛАВА 1 3 llil О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО Х РА Н Е Н И Я ДАН Н ЫХ
поверхностная копия объекта, то м ы могл и просто присвоить новому объекту
ссылку на дочерний объект.
ЗАМЕЧАНИЕ. Не стоит сл и ш ком беспокоиться о параметре N S Z one . Он указывает на
структуру, которая используется системой дл я уп равления памятью . Тол ько в редких
случаях разработчики действител ьно должны были заботиться о зонах или создавать
собствен н ы е зоны , а сейчас практически н икто и не слы шал о наличии нескольких
зон . Вызов метода сору дл я объекта эквивалентен вызову метода сору ( wi th zone : )
с испол ьзованием зоны по умолчанию, которая почти всегда именно та , которая вам
нужна . Факт, что класс NSCopying испол ьзует зоны , явл я ется историческим курье­
зом , сохранен н ы м дл я обеспечения обратной совместимости .
Архивирование и разархивирование объ ектов данных
Создать арх и в из объекта ил и объектов, которые соответствуют прото­
колу N S C o d i n g , относител ьно несложно. С н ачала создаем э кземпляр типа
NSMutaЫeData из каркаса Foundation для хранения зашифрован ных дан ных, а
затем экземпляр N S KeyedArc � i ve r, чтобы архивировать объекты в этот экзем­
пляр типа NSMu t aЫ e D a t a .
l e t da t a = N S M u t a Ы e Da t a ( )
l e t a r chiver
N S K e yedAr c h i ve r ( f o rW r i t i ngW i t h : da t a )
=
После создания обоих экземпляров испол ьзуем кодирован ие по принци пу
"кл юч-значение" для архивирования л юбых объектов, которые хоти м вкл ючить
в архив.
a r c h i ve r . e n code ( a nObj e c t , f o r Ke y : " ke yVa l u e S t r i n g " )
После шифрован ия всех нужных объектов достаточно уведом ить архи ватор
о завершен и и этой операци и и записать экземпляр типа NSMutaЬleData в фай­
ловую систему.
a r c h i ve r . f i n i s h E n co d i n g ( )
l e t s u c ce s s
d a t a . w r i t e ( t o : a r ch i ve U r l a s URL , a t omi ca l l y : t r u e )
=
Если вы чувствуете некоторы й дискомфорт от архивирован ия, не беспокой­
тесь. В действител ьности здесь нет ничего сложного. В следующем разделе мы
переориентируем приложение Persistence на испол ьзован ие метода архивирова­
ния данных, и вы увидите, как работает эта теория на практи ке. После несколь­
ких упражнений архивирование войдет у вас в привычку и станет вашей "вто­
рой натурой", поскольку на самом деле вы всего л и ш ь сохраняете и извлекаете
свойства своего объекта с испол ьзованием кодирования в стиле "кл юч-значение".
П риложение Archiving
Модифицируем приложение Persistence так, чтобы оно испол ьзовало вместо
списков свойств архивирован ие. Для этого необходимо внести в исходный код
ГЛАВА 1 3 li1 О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО ХРАН Е Н И Я ДАН Н ЫХ
495
приложения Persistence довол ьно существен н ые изменения, поэтому, прежде чем
продолжить, и меет см ысл сделать копию проекта, например заархивировав его с
помощью метода создания списка свойств в файл P e r s i s tencePL . z ip.
Реализация класса FourLines
Есл и вы готовы п родолжить работу, откройте коп и ю проекта Persi stence в
среде Xcode, выберите пап ку P e r s i s t e n c e и н аж мите комбинацию клавиш
< 3€ +N > ил и вы пол н ите команду Filec> New c> File " В открывшемся окне по­
мощн и ка для создан ия новых файлов выберите п и ктограмму Swift File в раз­
деле IOS и щел кн ите на кнопке Next. На следующей странице экрана назовите
класс FourL i ne s . swi ft, выберите для сохранен ия файлов папку P e r s i s tence
и щел кните на кнопке Create. Этот класс будет п редставлять нашу модель дан­
ных. Он будет хран ить дан н ые, которые пока содержатся в словаре в списке
свойств приложения .
Щел кните на файле FourLi ne s . swi ft и внесите в него код, представленный
в листинге 1 3 .8 .
..
Листинг 1 3 . 8 . Класс FourLines
c l a s s Fo u r L i n e s : N S Ob j e c t , N S C o d i n g , N S C o p y i n g
p r i v a t e s t a t i c l e t l i ne s Ke y = " l i n e s K e y "
va r l i n e s : [ S t r i n g ] ?
ove r r ide i n i t ( ) {
r e qu i r e d i n i t ? ( c ode r a De c o de r : N S C o de r ) {
l i nes
a De c o de r . decodeOb j e c t ( f o r K e y : Fo u r L i n e s . l i n e s K e y ) a s ?
[ S t r i ng ]
}
=
f u n c e n code ( w i t h aCode r : N S Code r ) {
i f l e t s a ve L i n e s = l i n e s {
aCode r . e n code ( s ave L i n e s , f o r K e y : Fou r L i n e s . l i n e s K e y )
f u n c copy ( w i t h z o n e : N S Z o n e ? = n i l ) - > AnyOb j e c t {
l e t сору = Fo u r L i n e s ( )
i f l e t l i n e s T oCopy = l i n e s {
v a r ne w L i n e s = Ar r a y < S t r i ng > ( )
, f o r l i n e i n l i n e s T oCopy {
n e w L i n e s . ap p e n d ( l i n e )
copy . l i n e s = new L i n e s
r e t u r n сору
496
ГЛАВА 1 3 i!f О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО ХРА Н Е Н И Я ДАН Н ЫХ
М ы реал и зовал и все методы, необход и м ы е для согл асования с протоко­
лами N S C o d i ng и N S Copy i n g . М ы ши ф руем все четыре свойства в методе
encode ( w i t h aCode r : ) и расши ф ровываем их с испол ьзованием тех же са­
м ы х четырех ключевых значений в методе i n i t ( w i t h aCode r : ) . В методе
сору ( w i th z one : ) создаем новы й объект типа FourLine s и копируем в него
все четыре строки с помощью глубокого коп ирования, чтобы изменени,я ори­
гинала не коснулись нового объекта. Как видите, это несложно. Просто будьте
внимательны, выпол няя многочисленные операции копирован ия и вставки.
Реализация класса ViewController
Теперь, когда у нас есть объект архивируе м ы х дан н ых, воспол ьзуемся и м
дл я сохранения данных нашего п риложени я . В ыберите файл Vi ewCont ro l l er .
swi ft и внесите в него изменения, у казанные в листинге 1 3 .9.
Л истин г 1 3 . 9 . Код для сохранения и извлечения заархивированного
объекта в файле Vi ewCont r o l l e r . s w i f t
ove r r i de f u n c v i e w D i dLoad ( ) {
s up e r . v i e w D i dL o a d ( )
1 1 Допол н и т ел ь н а я н а с т р о й ка после з а груз ки предст а вл е ния ,
1 1 о быч н о и з n i Ь -файла .
l e t f i l e URL = s e l f . da t a F i l e URL ( )
i f ( Fi l eM a n a g e r . de f a u l t . f i l e E x i s t s ( a t P a t h : f i l eURL . p a t h ! ) ) {
i f let array
NSAr r a y ( co n t e n t s O f : f i l e UR L a s URL ) a s ? [ S t r i n g ]
for i i n О . . < a r ra y . count {
l i ne F i e l d s [ i ] . text
array [ i ]
=
=
l e t d a t a = N S M u t aЬ l e Da t a ( co n t e n t s O f : f i l eURL a s URL )
l e t u n a r c h i v e r = N S K e yedUna r c h i ve r ( f o r R e a d i n gW i t h : d a t a a s ! Da t a )
let fourLines
u n a r c h i ve r . decodeObj e c t ( f o r K e y : V i ewC o n t r o l l e r .
r o o t Ke y )
a s ! Fo u r L i n e s
u n a r c h i ve r . f i n i s h De c o d i n g ( )
i f l e t newL i n e s = f o u r L i n e s . l i n e s
for i i n О . . <newL i ne s . count {
l i ne F i e l d s [ i ] . t e x t
n e w L i ne s [ i ]
=
=
l e t арр
U I App l i c a t i on . s h a r e d ( )
N o t i f i c a t i on C e п t e r . de f a u l t . addOb s e r ve r ( s e l f , s e l e c t o r :
# s e l e c t o r ( s e l f . a p p l i c a t i o nW i l l Re s i gnAc t i ve ( n o t i f i c a t i o n : ) ) ,
n ame : N o t i f i c a t i on . Name . U I App l i c a t i o nW i l l Re s i g nAc t i ve ,
o b j e c t : арр )
=
f u n c a pp l i c a t i o nW i l l Re s i g nAc t ive ( no t i f i c a t i o n : N S N o t i f i c a t i on )
l e t f i l eURL = s el f . data F i l eURL ( )
l e t fou r L i n e s = Fou r L i n e s ( )
l e t a r r a y = ( s e l f . l i n e F i e l d s a s NSAr r a y ) . va l u e ( f o r K e y : " t e x t " )
a s ! [ S tring ]
fourLine s . l i nes
array
=
ГЛАВА 1 3 f: О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО ХРАН Е Н И Я ДАН Н ЫХ
497
l e t d a t a = N S Mu t a Ь l e Da t a ( )
l e t a r c h i v e r = N S Ke yedAr c h i ve r ( f o rW r i t i n gW i t h : d a t a )
a r c h i ve r . e n c ode ( f o u r L i n e s , f o r K e y : V i ewCon t r o l l e r . r o o t Ke y )
archiver . f i n i s hEncoding ( )
da t a . w r i t e ( t o : f i l e U R L a s U R L , a t om i ca l l y : t r u e )
f u n c da t a F i l e U R L ( ) - > N S U R L {
l e t u r l s = F i l eM a n a g e r . de f a u l t . u r l s ( f o r :
. do cume n t D i r e c t o r y , i n : . u s e r Doma i nMa s k )
va r u r l : NS U R L ?
u r l = URL ( f i l e URLW i t h P a t h : " " ) 1 1 С о з д а ем п у с т о й п у т ь
do {
t r y u r l = u r l s . f i r s t ! . appen d i n g P a t h C omp o n e n t ( " d a t a . a r c h i ve " }
catch !
print ( " E r ror i s \ ( e rror } " )
return url !
Сохран ите изменения и запустите эту верси ю приложения Persi stence. С нача­
ла мы определ или новое имя файла в методе dataFi l eURL ( ) , чтобы программа
не пыталась загружать старый список свойств как архив. Кроме того, м ы опре­
дел ил и новую константу, которая и грает рол ь значения ключа при шифрован и и
и расшифровке объекта. Затем м ы переопределил и методы загрузки и сохране­
н ия данных в классе Fou r L i n e s и испол ьзовал и методы п ротокола NSCod i ng
для реал ьной загрузки и сохранения дан ных. Пол ьзовательский интерфейс иден­
тичен предыдущей версии.
Для этой новой версии потребовалось больше строк кода, чем для предыду­
щей (со спискам и свойств), поэтому у вас м ожет возн икнуть сом нение: а есть
ли какое-то преимущество в испол ьзован и и архивирования перед с п искам и
свойств? Что касается этого приложения, то ответ простой: нет, в дан ном случае
действител ьно нет н икакого преимущества. С другой сторон ы, есл и бы у нас
был массив архи вируемых объектов, напри мер класса Fou r L i n e s (которы й м ы
только что построил и), то м ы могл и бы заархивировать весь массив, архивируя
сам экземпляр масси ва. При архивировании такие класс ы коллекций, как Array,
архивируют все объекты, которые они содержат. Поскол ьку каждый объект, ко­
торы й м ы поместили в массив ил и словарь, соответствует протоколу NSCodi ng,
можем архивировать этот массив ил и словарь и восстанавли вать его так, чтобы
все объекты, которые в нем содержал ись при архивировании, находил ись и в
восстановлен ном масси ве ил и словаре .
И наче говоря, этот подход намного предпочтительнее (по крайней мере, есл и
говорить о размере кода). Независимо от того, скол ько объектов вы добавите,
объем работы по зап иси этих объектов на диск (в предположении, что вы ис­
пользуете однофайловый вариант сохранения данн ых) останется тем же. И на­
оборот, объем работы при испол ьзовании списков свойств увел и ч и вается с каж­
дым добавляем ы м вам и объектом .
1
498
ГЛАВА 1 3 1Мi О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО ХРАН Е Н И Я ДАН Н Ы Х
И сп ол ь зо вание встр оен ной
в iOS ба з ы дан н ых SQLiteЗ
Третий вариант обеспечения дол говременного хранения дан н ы х, который
м ы рассмотри м , состоит в испол ьзован и и встроенной в iOS SQL-базы дан­
ных SQLiteЗ . База дан н ы х SQL iteЗ отличается в ысокой эффективностью при
сохранени и и извлечен и и больших объемов данных. Она также может вы пол­
нять сложные операции по агрегирован ию дан н ых, причем с гораздо большим
быстродействием по сравнению с испол ьзованием с той же цел ью объектов.
Например, есл и ваше приложение должно выч исл ить сум му значений конкрет­
ного поля по всем объектам приложения ил и есл и вам нужна была сумма зна­
чени й тол ько из тех объектов, которые отвечают определенному критерию, база
дан н ы х SQLiteЗ справилась бы с этой задачей без загрузки каждого объекта в
память. П олучение резул ьтатов агрегирования из базы SQL iteЗ происходит на
нескол ько порядков быстрее, чем загрузка всех объектов в память с последу­
ющим сум м ированием их значени й . Как пол ноценная встроен ная база дан ных
SQLiteЗ содержит и нструменты, позволя ющие повысить ее быстродействие пу­
тем создания, например, и ндексов табл и ц, что, безусловно, позволяет ускорить
обработку ваших запросов.
В базе дан н ых SQL iteЗ испол ьзуется язык структури рован н ы х запросов
(Structured Query Laпguage - SQL). SQL - стандартн ы й язы к, испол ьзуемый
для взаимодействи я с реляцион н ы м и базам и дан н ых. С и нтаксису SQL ( как,
впрочем, и SQL ite) посвя щено множество книг (даже не десятки, а сотн и). По­
этому, есл и вы не знаком ы с язы ком SQL, но хотите испол ьзовать базу SQLiteЗ
в с воем приложе н и и , вам придется усердно поработать в этом направлен и и .
М ы покажем, как установить базу дан ных SQLite и взаи модейство вать с ней из
своих iОS-приложений, и вы найдете в этой главе основы си нтаксиса. Но для
того чтобы действител ьно выжать все возможное из базы SQLiteЗ , вы долж­
н ы п риложить доп ол н ител ь н ы е усил и я . Напри мер, можете начать освоение
SQL с таких источн и ков, как "An I ntroductioп to the SQLiteЗ С/С++ l пterface"
( h t t p : / / www . s q l i t e . o rg / c i nt ro . h tml ) и "SQL As U nderstood Ьу SQL ite''
(http : / / www . s q l i t e . o rg / l ang . html ).
Реляционные базы данн ы х, вкл ючая SQL iteЗ, и языки объектно-ориентиро­
ван ного програм м ировани я испол ьзуют фундаментал ьно разл и ч н ые подходы к
хранению и организаци и дан ных. Поэтому для преобразования дан ных меж­
ду н и м и разработано м ножество методов, библ иотек и проч их инструментов,
которые все вместе получ ил и "коллективное" название объектно-реляцион ное
отоб ражение (object-relational mapping - ORM). В настоя щее время существу­
ет нескол ько технологических ОRМ-инструментов, предназначенных для Сосоа
Touch. Одно из таких ОRМ-решений, предоставлен ное ком панией Apple, - ме­
хан изм Core Data - мы рассмотрим н иже.
ГЛАВА 1 3 liii О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО ХРА Н Е Н И Я ДАН Н Ы Х
499
Здесь мы останови мся на основных возможностях работы с базой SQLiteЗ ,
а именно: на ее установке, создании табл ицы для хранения дан н ы х и испол ь­
зован ии базы дан ных в приложени и . Безусловно, в реальности такое простое
приложение, как наше, совсем не оправдало бы затраты на поддержание базы
SQLiteЗ . Однако именно простота этого приложения позволяет испол ьзовать его
в качестве хорошего обучающего примера.
Создание или открытие базы данных
Прежде чем вы сможете работать с механизмом SQLiteЗ , вы должн ы открыть
базу дан ных. Функция, которая испол ьзуется для этого, s q l i t e З _ open ( ) , от­
кроет существующую базу данн ых, а есл и в указанном месте ее не окажется, то
создаст новую. Код для открытия новой базы данн ы х при веден н иже.
var datab a s e : Op a q u e P o i n t e r ?
nil
l e t re s u l t = s q l i t e З _ o p e n ( " / p a t h / t o / d a t a b a s e / f i l e " , & da t ab a s e )
=
Есл и резул ьтат окажется рав н ы м константе SQL I T E ок, значит, база данных
была успешно открыта. Обратите внимание на то, что путь к файлу базы данных
должен быть передан в виде переменной dat aba s e . В и нтерфейсе прикладного
програм мирован ия SQL iteЗ АР! эта перемен ная представля ет собой структуру
из языка С типа sql i t e З . Когда в язык Swift был и м портирован и нтерфейс при­
кладного программирован ия на языке С, эта переменная превратилась в объект
типа Unsa feMutaЬ l e Po i n t e r<Copaque Po i n t e r>, которы й в текущей версии
языка Swift выражает указател ь vo i d * из языка С . Это значит, что м ы должны
работать с ним, как с непрозрач н ы м указателем (opaque pointer). В этом нет ни­
какой проблем ы, потому что нам не нужен доступ в внутрен нему содержани ю
этой структуры и з кода Swift - нам всего л и ш ь нужно передать этот указател ь
други м фун кциям SQLiteЗ , таким как s q l i t е З _c l o s e ( ) .
_
s q l i t e З _ c l o s e ( da t a b a s e )
Базы дан ных хранят все данные в табл и цах. Можно создать новую табл ицу
путем "конструирован ия" SQL-oпepaтopa CREATE и передач и его открытой базе
данных с помощью функции s q l i t е З ехес:
_
l e t c r e a t e SQL
" C REATE TAB LE I F N O T EX I S T S P E O P L E " +
" ( I D I NT E G E R P R I MARY К Е У AUTO I NCREMENT , F I E L D DATA Т Е ХТ ) "
va r e r rM s g : U n s a feMu t aЫ e P o i n t e r < I n t B > = n i l
r e s u l t = s q l i t e З _ e x e c ( da t a ba s e , c r e a t e SQL , n i l , n i l , & e r rM s g )
=
Фун кция s q l i t е З е х е с испол ьзуется для вы пол нения л юбой связан ной с
SQL iteЗ команды, которая не возвращает данн ы е, т.е. реал изует обновление,
вставку и удаление данных. Извлечение и нформации из базы данных выглядит
нескол ько сложнее . Сначала необходимо подготов ить оператор на основе SQL­
команды S ELECT.
_
let createSQL
" S E LE C T I D , F I E L D_ DATA FROM F I E L DS ORDER ВУ ROW "
va r s t a t eme n t : Op a qu e P o i n t e r ?
nil
result
s q l i t e 3 _ p r e p a r e _v2 ( da t ab a s e , c r e a t e S QL , - 1 , & s t a t emen t , n i l )
=
=
=
500
ГЛАВА 1 3 !<i О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н О ГО ХРАН Е Н И Я ДАН Н Ы Х
Есл и резул ьтат в ы пол нения фун кции равен константе SQL I T E ОК, знач ит,
ваш оператор был успеш но подготовлен, и вы можете переходить к обработке
резул ьтирующего множества. Рассмотри м при мер обработки структуры SQLiteЗ
как непрозрач ного указателя - в SQLiteЗ API перемен ная s t a t eme n t имеет
тип s q l i t е З _ s tmt .
Расс мотрим при мер обхода результирующего м ножества и извлечен11я из
баз ы данных переменных типа I nt и S t r i ng.
whi l e s q l i t e З _ s t ep ( s t a t eme n t ) = = S QL I T E _ ROW
l e t row
I n t ( s q l i t e З _ c o l umn _ i n t ( s t a t eme n t , 0 ) )
l e t r o w Da t a
s q l i t e З _ c o l umn _ t e x t ( s t a t eme n t , 1 )
l e t f i e l dVa l ue = S t r i ng . i n i t ( c S t r i n g : U n s a f e P o i n t e r < C C h a r > ( rowDa t a ! ) )
l i n e F i e l d s [ r ow ] . t e x t
f i e l dVa l u e !
=
=
=
s q l i t e З _ f i n a l i z e ( s t a t eme n t )
Здесь м ы снова должн ы установить мост между требован и я м и интерфейса
прикладного програм м ирования, нап исанного на языке С, и механизмами подде­
ржки языка Swift. В этом случае фун кция s q l i t е З _ column_text ( ) возвращает
значение типа con s t un s i gned cha r * , которое компилятор язы ка Swift перево­
дит в тип Uns a fe Pointer<U i n t 8 > . Нам необходимо создать объект типа S t r i ng
из возвращаемых с и м вольных дан ных, и м ы можем это сделать с помощью ме­
тода S t r i ng . i n i t ( c S t r i ng : ) ( Un s a f e Po i n t e r<CChar> ) . Вместо объекта
типа Un s a f e Po i n t e r<CCha r> у нас есть объект типа Un s a f e Po i nter<Uint B >,
но, к счастью, существует и н и циал изатор, позволя ющий создать второе из пер­
вого. Создав объект типа S t r i ng, м ы присваиваем его те кстовому свойству
U I Text F i e l d.
Использование связанных переменных
Несмотря на то что для вставки значен и й можно конструировать SQL-стро­
ки, обы ч ной практикой для этой цел и все же я вляется испол ьзован ие так назы­
вае м ы х связа н н ы х перемен н ы х (Ьi11d variaЫes). Корректная обработка строк
(т.е. гарантирован ие отсутствия в их составе недопусти м ы х сим волов и надле­
жащая обработка кавычек) и ногда вызы вает оп ределенные трудности . Однако
с испол ьзованием связан н ы х перемен ных эти проблемы решаются практически
сам и собой .
Для того чтобы вставить некоторое значен ие с помощью связанной перемен­
ной, создайте обы ч н ы й SQL-oпepaтop, но поместите в SQL-cтpoкy знак вопро­
са ( ? ). Кажд ы й вопросител ь н ы й знак представляет одну перемен ную, которая
должна быть связана до вы пол нения этого оператора. Затем подготовьте SQL­
oпepaтop, свяжите значение с каждой переменной и в ыпол н ите команду.
Рассмотри м при мер подготовки SQL-oпepaтopa с двумя связанн ы м и перемен­
н ы м и, связ ы вания целоч исленного значен ия с первой переменной и строки со второй и, наконец, выпол нения и завершения оператора:
ГЛАВА 1 3 iw О С Н О В Ы ДОЛГО В Р Е М Е Н Н ОГО ХРАН Е Н И Я ДАН Н ЫХ
501
va r s t a t erne n t : Op a q u e P o i n t e r ? = n i l
l e t s q l = " I N S E RT I N Т O FOO VALU E S ( ? , ? ) ; "
i f s q l i t e 3 _ p r e p a re _ v2 ( da t a b a s e , s q l , - 1 , & s t a t erne n t , n i l )
= = S QL I T E OK {
_
s q l i t e З _Ь i nd _ i n t ( s t a t ernen t , 1 , 2 3 5 )
s q l i t e З _Ь i n d_ t e x t ( s t a t erne n t , 2 , " B a r " , - 1 , n i l )
i f s q l i t e З _ s t e p ( s t a t ern e n t ) ! = S Q L I T E _ DON E {
p r i n t ( " T h i s s h o u l d Ье r e a l e r r o r c h e c k i n g ! " )
s q l i t e З _ f i n a l i z e ( s t a t ernent ) ;
Существует нескол ько операторов связы ван ия, которые выбираются в зави­
симости от испол ьзуемого типа данных. Бол ьш и нство фун кций связы вания при­
нимает только три параметра.
�
�
'1
Первый п араметр передается л юбой функции связы ван ия независимо
от типа дан ных. Он представляет собой указател ь на перемен ную типа
s q l i t е З _ s tmt, испол ьзуемую ранее в вызове s q l i t e 3 _prepare _v2 ( ) .
Второй параметр - это и ндекс перемен ной, с которой вы пол няется свя­
з ы вание. Это однои ндексное значен ие, которое и нтерпрети руется так:
первы й вопрос ител ь н ы й знак в SQL-oпepaтope имеет и ндекс 1 , а каждый
последующий на един и цу бол ьше предыдущего.
Третий параметр всегда содержит значен ие, которое должно замен ить во­
просительный знак.
Некоторые фун кции связывания (испол ьзуем ые, например, для с вязы вания
текстовых и двои чных дан ных) имеют еще два параметра.
\?t
Первы й допол н ительный параметр представляет собой дл ину данн ы х, пе­
редаваем ы х в третьем параметре. В случае испол ьзован ия С-строк можно
вместо дл ины строки передать ч исло - 1 , и тогда фун кция будет испол ьзо­
вать всю строку. Во всех остал ьных случаях необходимо указы вать дл и ну
передаваемых дан ных.
i:I
Последний допол н ител ьн ы й параметр - необязател ьный обратный вызов
функци и, который передается в случае, когда необходимо позаботиться об
освобождении памяти после выпол нения вашего оператора. Обычно такая
функция используется для освобождения памяти, занятой при вызове фун к­
ции ma l l oc ( ) .
1
С и нтаксис строк кода, следующих за операторам и связы вания, может по­
казаться нескол ько стран н ы м . Дело в том, что они обеспечи вают в ыполнение
вставки . При испол ьзован и и с вязанн ы х переме н н ы х тот же сам ы й с интаксис
испол ьзуется как для запросов, так и для обновлен и й . Есл и б ы SQL-cтpoкa
имела SQL-зaпpoc, а не обновление, необходимо было бы м ногократно вызы­
вать фун кцию s q l i t е З s t ep ( ) - до тех пор, пока она не вернет значение
502
ГЛАВА 1 3 m О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н ОГО Х РАН Е Н И Я ДАН Н Ы Х
SQL I T E _ DONE. Поскол ьку в дан ном при мере вы пол нялось именно обновление,
мы вызвал и эту фун кцию тол ько оди н раз .
П рило жение SQLiTEЗ
Испол ьзуя среду Xcode, создайте новы й проект по шаблону Si ngle View Ap­
plication и назовите его SQL i t e Pe r s i s tence. Проект станет иденти чны � пре­
дыдущему, поэтому откройте файл Vi ewCont r o l l e r . swi f t и внесите в него
следующие изменени я :
c l a s s V i ewCont r o l l e r : U I V i ew C o n t r o l l e r {
@ IBOutlet var lineFields : [ UI TextField] !
Затем откройте файл Ma i n . s t o r yboard. Создайте п редставление и соеди­
ните коллекцию выходов, следуя и нструкция м из раздела "Разработка представ­
ления для приложения Persistence". Закончив проектирован ие, сохраните файл
раскадровки.
Удел и в немного в н и мания теори и , м ожно переходить к п ракти ке . Давайте
снова модифицируем наше приложение Persistence, на этот раз сохраняя данные
с испол ьзованием механизма SQLiteЗ . Мы огран ичимся одной табл ицей и будем
сохранять значения полей в четырех разл ичных ее строках. Каждой строке при­
свои м номер, которы й будет связан с полем, и поэтому в нашем примере зна­
чение из поля f i e l d l будет сохранено в табл ице с номером строки, равным 1 .
Итак, начнем .
Компоновка с би блиотекой базы данных SQLiteЗ
Доступ к базе дан н ы х SQLite 3 реал изуется через процедурный интерфейс
прикладного програм м ирования, который предоставляет и нтерфейсы с разл ич­
н ы м и вызовами С-функци й . Для испол ьзован ия этого и нтерфейса нам необходи­
мо ском поновать приложение с динамической библиотекой l i bsql i t е З . dyl ib.
В ы берите пун кт SQLite Persistence в самом верху списка нави гатора проекта
( край няя слева панель), а затем пун кт SQLite Persistence в разделе TARG ETS
(средняя панел ь; рис. 1 3 . 7). Будьте внимател ь н ы : выбрать надо пункт Persistence
в разделе TARGETS, а не в разделе PROJECT.
В ыбрав цел ь SQLite Persistence, щел кните на в кладке Build Phases на край­
ней с права панел и . Вы у в идите список, состоя щий из свернутых элементов,
представля ющих этапы , которые п рограмма Xcode проходит при сборке при­
л ожения . Раскройте элемент с метко й Link Binary With Li braries. В ы увидите
стандартные каркасы , которые подключаются к вашему приложению. По умол­
чани ю этот список пуст, потому что ком пилятор автоматически устанавл и вает
связи с л юб ы м и каркасами iOS, которые испол ьзуются в вашем приложении,
но ком п илятор н и чего не знает о библиотеке SQLiteЗ, поэтому м ы должны до­
бавить ее сюда.
ГЛАВА 1 3 i!!i О С Н О В Ы ДОЛГО В Р Е М Е Н Н ОГО ХРАН Е Н И Я ДАН Н Ы Х
8
·
•
е:! iil
•
.
.
Jllo
°'
6
8
�-
0
.1!1
sow. PwrtltDnee
• AWDМQtt•.Mtt
1 VltwConrrciktt. IW'ih
SOl.118 P«ll•tenu
о
МНl:�or,oЬoli'd
·---­
........
...__.,
.
Wo.pjitt
·-
(!)
1
!й! (
503
iPnone SE
[]
PIIOJECТ
Q SOI.•• ..........
...
a.n.re1
TA.ltGПS
" Unll Вlnery Wfth Ulmlflel 11 li.1'11 )
"." .
+
" Сору 8ul'ldl• Resource1 ll ltмi11
Рис . 1 З . 7 . Выбор п роекта SQ Lite Persistence в навигаторе проекта, а также
выбор цели SQLite Persistence и вкладки Build Phases
Щелкн ите на кнопке + , расположенной внизу списка подкл юченных каркасов,
и вы увидите список доступных каркасов и библиотек. Найдите в этом списке
библиотеку l i b s q l i t е З . tbd (или воспол ьзуйтесь полем поиска) и щел кн ите
на кнопке Add . Обратите внимание на то, что в каталоге может быть несколько
элементов, имя которых начинается на l ib s q l i t e З . Необходимо выбрать и мен­
но библиотеку l ib s q l i t е З . tbd. Это псевдоним, который всегда ссылается на
последнюю версию библиотеки SQLiteЗ .
Модификация контроллера представления
для приложения Persistence
Теперь необходимо и м портировать заголовоч н ы е файл ы для библ и отеки
SQL iteЗ в контроллер представления, чтобы ком п илятор мог видеть фун кци и и
другие определения из интерфейса прикладного програм мирования. Прямого спо­
соба импортировать заголовоч ный файл в код на язы ке Swift не существует, по­
тому что библиотека SQLiteЗ не упакована в виде каркаса. Проще всего добавить
в проект мостовой заголовоч ный файл (bridging l1eader). С его помощью м ы
сможем добавлять другие заголовочные файлы, которые будет ч итать компилятор
языка Swift. Есть нескол ько способов добавления мостового файла. Мы приме­
ним наиболее простой - временно добавим в проект класс на языке Objective-C.
Н ажм ите комби нацию клавиш < X +N> ил и выпол н ите команду Filec> Newc:::>
File" . В разделе IOS диалогового окна выберите п и ктограм му Сосоа Touch
Class и щел кн ите на кнопке Next. Присвойте классу имя Tempora ry, сделайте
его подкл ассом класса NSObj e c t , измен ите язык на Obj e c t i ve -C и щелкни­
те на кнопке Next. На следующем э кране щел кните на кно п ке Create. После
этого среда Xcode откроет вспл ы вающее окно, в котором спросит вас, хотите
ли вы создать мостовой заголовоч н ы й файл . Щел кните на кнопке Create Brid­
ging Header. Перейдите в окно нави гатора проекта, где вы увидите файл ы для
нового класса (Tempo rary . m и Tempo rary . h) и мостовой заголовоч н ы й файл,
.'
504
ГЛАВА 1 3 №' О С Н О В Ы ДОЛ ГО В Р Е М Е Н Н ОГО ХРАН Е Н И Я ДАН Н ЫХ
который наз ывается SQLi t e Pe r s i s tence - B r i dg i ng-Heade r . h. Удал ите фай­
лы Tempo r a ry . m и T empo rary . h - они вам больше не понадобятся. Откройте
мостовой заголовоч н ы й файл в окне редактирования и добавьте в него следую­
щую строку :
# impo r t < s q l i t e З . h >
Теперь ком п илятор в идит б ибл иотеку и заголовоч н ы е файл ы механ изма
SQLiteЗ , и м ы можем написать более сложную програм му. Выберите файл View
Control l e r . swi f t и внесите в него изменения, приведенные в л исти н ге 1 3 . 1 0.
Л истинг 1 3 . 1 О . Использование механизма SQLiteЗ
для сохранения и считывания информации
ove r r ide f u n c v i e w D i d L o a d ( ) {
s up e r . v i e w D i dLoad ( )
1 1 Дополнител ь н а я н а с тройка п о сл е з а гру з ки предс т а в л е ни я ,
1 1 об ы ч н о и з n i Ь - файла .
v a r d a t a b a s e : Opa q u e P o i n t e r ? = n i l
v a r r e s u l t = s q l i t e З _ o p e n ( da t a Fi l e Pa t h ( ) , & d a t ab a s e )
i f r e s u l t ! = S QL I T E OK {
_
s q l i t e З c l o s e ( da t a b a s e )
p r i n t ( " Fa i l e d t o o p e n d a t a b a s e " )
return
l e t c r e a t e S QL = " C REAT E TABLE I F N O T EX I S T S F I E L DS " +
" ( ROW I N T E G E R P R I МARY КЕУ , F I E L D DATA ТЕХТ ) ; "
_
va r e r rM s g : Un s a feMu t a Ь l e Po i n t e r < I n t 8 > ?
nil
r e s u l t = s ql i te З e x e c ( da t ab a s e , c r e a t e S QL , n i l , n i l , & e r rMs g )
_
i f ( r e s u l t ! = S QL I T E OK ) {
s q l i t e З _ c l o s e ( da t a b a s e )
p r i n t ( " Fa i l e d t o c r e a t e t а Ы е " )
return
=
__
l e t qu e r y = " S E L E C T ROW , F I E L D_ DATA FROM F I E L D S ORDER ВУ ROW "
v a r s t a t eme n t : Opaqu e Po i n t e r ? = n i l
i f s q l i t e 3 _ p r e p a r e v 2 ( da t aba s e , que r y , - 1 , & s t a t eme n t , n i l ) = = S QL I T E
_
ок {
w h i l e s ql i t e З s t e p ( s t a t eme n t ) == S QL I TE _ ROW {
_
l e t row = I n t ( s q l i t e З _ c o l umn _ i n t ( s t a t emen t , 0 ) )
l e t rowData
s ql i t e З c o l umn t e x t ( s t a t eme n t , 1 )
l e t f i e l dVa l u e
S t r i ng . i n i t ( c S t r i n g :
U n s a f e Po i n t e r < C C ha r > ( rowDa t a ! ) )
l i n e Fi e l d s [ r ow ] . t e x t = f i e l dV a l u e
=
=
f
s q l i t e З f i n a l i z e ( s t a teme n t )
s q l i t e З c l o s e ( da t aba s e )
l e t арр = U IApp l i ca t i o n . s h a r e d ( )
N o t i f i c a t i o n C e n t e r . de f a u l t . a ddOb s e rve r ( s e l f , s e l e c t o r :
# s e l e c t o r ( s e l f . app l i c a t i onWi l l R e s i gnAc t i ve ( n o t i f i c a t i o n : ) ) ,
name : 
Скачать