В iOS 7 Apple представила классы, чтобы помочь разработчикам в создании пользовательских интерфейсов, которые «чувствовали бы себя реальными» и вели себя «реалистично» для взаимодействия с пользователем. Инструменты, используемые для достижения этой цели, — это в основном динамика UIKit и эффекты движения.
Ранее, чтобы добиться такого взаимодействия, разработчик должен был хорошо разбираться в математике, физике и библиотеке Core Animation. С новыми библиотеками стало проще настраивать и реализовывать такие реалистичные модели поведения и анимации.
Эффекты движения позволяют настроить внешний вид пользовательского интерфейса приложения в соответствии с ориентацией телефона и тем, как пользователь удерживает и перемещает его. Пример этого можно увидеть на главном экране, который имеет эффекты параллакса, которые реагируют на перемещение телефона. Это придает ощущение глубины плоскому интерфейсу.
UIKit Dynamics позволяет вам добавлять в свои представления реальные виды поведения, чтобы при их анимации эффект был тем, чего вы привыкли ожидать от объектов реального мира. Эти поведения включают гравитацию, столкновение, привязанность и т. Д.
Классы, которые обеспечивают различное поведение для ваших элементов пользовательского интерфейса:
-
UIGravityBehavior
— обеспечивает гравитационное поведение ваших взглядов. -
UICollisionBehavior
— обеспечивает обнаружение столкновений. -
UISnapBehavior
— Заставляет представление перемещаться и привязываться к определенной точке интерфейса, как если бы он был подключен к нему. -
UIAttachmentBehavior
— Определяет динамическое соединение между двумя динамическими элементами или между динамическим элементом и точкой привязки. -
UIPushBehavior
— применяет непрерывную или мгновенную силу к одному или нескольким динамическим элементам, заставляя эти элементы соответствующим образом менять положение.
Чтобы добавить любое поведение, описанное выше, в представление, мы инициализируем поведение и передаем ему представления, которые мы хотим продемонстрировать поведение. Затем мы устанавливаем конфигурации для него, если мы хотим изменить настройки по умолчанию (мы рассмотрим это позже). Затем мы добавляем это в UIDynamicAnimator
который предоставляет контекст для различных UIDynamicAnimator
поведения и анимации, которые вы определяете. UIDynamicAnimator
инициализируется с опорным представлением, которое он использует, чтобы определить свою систему координат и вычислить выходные данные различных поведений.
Мы рассмотрим, как реализовать 5 вариантов поведения, описанных выше. Я создал стартовый проект, который вы можете скачать, и последний пример здесь . Он предоставляет простой тип приложения основного вида, в котором основной вид показывает список поведений, которые мы рассмотрим, а подробный вид показывает демонстрацию поведения в действии. Это настроено так, чтобы мы могли сосредоточиться на UIKit Dynamics и не нужно было объяснять, как настроить проект. Мы собираемся использовать Swift для этого примера, поэтому вам потребуется Xcode 6, чтобы следовать.
Гравитация и столкновение
Мы начнем с добавления гравитации к виду. Это общая концепция, которую мы привыкли ожидать от объектов в нашем мире. Когда что-то не имеет силы, удерживающей его, оно падает на землю. Мы можем смоделировать это поведение, используя класс UIGravityBehavior
.
В классе проекта GravityAndCollisionViewController
мы сначала добавляем представление, на которое будет действовать гравитационное поведение.
Добавьте следующую переменную экземпляра в класс.
var squareView: UIView!
В viewDidLoad()
добавьте следующее в конце метода.
squareView = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100)) squareView.backgroundColor = UIColor.blueColor() view.addSubview(squareView)
Запустите приложение, и вы должны увидеть синий квадрат в верхней части экрана.
Чтобы добавить гравитационное поведение к представлению, добавьте следующие переменные экземпляра.
var gravity: UIGravityBehavior! var animator: UIDynamicAnimator!
Затем добавьте следующее в конце viewDidLoad()
animator = UIDynamicAnimator(referenceView: view) gravity = UIGravityBehavior(items: [squareView]) animator.addBehavior(gravity)
Вышеприведенный код инициализирует аниматор с текущим видом, создает гравитационное поведение и добавляет к нему вид, который вы хотите продемонстрировать. При запуске приложения квадратный вид падает прямо с экрана. По умолчанию гравитация действует вниз, но вы можете изменить это, изменив свойство angle
UIGravityBehavior
. Вы также можете изменить скорость падения объекта, установив другую magnitude
. Как и в случае с реальной гравитацией, вид сбрасывается вниз, пока не достигнет границы. Так как мы не определили один, представление продолжает падать и даже выходит из поля зрения.
Мы сохраняем квадратное представление в пределах нашего экрана, устанавливая границу. Чтобы установить границу, вы можете либо установить границы эталонного зрения, чтобы быть границами вашего обнаружения столкновения или вы могли бы определить собственные линии, чтобы быть границами для ваших столкновений.
Чтобы добавить границу, мы должны создать экземпляр класса UICollisionBehavior
. Добавьте следующую переменную экземпляра в класс.
var collision: UICollisionBehavior!
Затем добавьте следующее в конец метода viewDidLoad()
.
collision = UICollisionBehavior(items: [squareView]) collision.translatesReferenceBoundsIntoBoundary = true animator.addBehavior(collision)
Приведенный выше код инициализирует объект UICollisionBehavior
массивом объектов, к которым мы хотим добавить поведение при столкновении. Этот класс, как и другие классы поведения, принимает массив объектов, соответствующих протоколу UIDynamicItem
. Все экземпляры UIView
соответствуют этому протоколу, поэтому наш квадрат хорошо подходит.
Затем мы устанавливаем свойство translatesReferenceBoundsIntoBoundary
экземпляра поведения коллизии в значение true
чтобы границы нашего ссылочного представления (которое было установлено при инициализации UIDynamicAnimator
) были установлены как границы поведения обнаружения коллизий.
При запуске приложения квадрат упадет и достигнет нижней части экрана с несколькими отскоками, прежде чем осесть.
Если вы хотите определить свои собственные границы, вы можете использовать метод addBoundaryWithIdentifier
чтобы установить границы. Например, если граница определена, как показано ниже, будет установлен барьер, который остановит квадрат в определенной позиции.
collision.addBoundaryWithIdentifier("barrier", fromPoint: CGPointMake(self.view.frame.origin.x, 350), toPoint: CGPointMake(self.view.frame.origin.x + self.view.frame.width, 350))
Полный код для класса GravityAndCollisionViewController
показан ниже.
Щелчок
Далее мы рассмотрим класс UISnapBehavior
. Это позволяет привязать вид к определенной точке экрана с эластичностью реального эффекта привязки. Мы будем использовать распознаватель жестов касания на нашем контроллере вида, чтобы мы могли определять, когда пользователь касается экрана и точки контакта, чтобы мы могли привязать квадратное представление к этой точке.
Откройте файл Main.storyboard
и найдите контроллер представления Snap
. Перетащите Распознаватель жестов касанием из библиотеки объектов на контроллер представления. Затем создайте действие для распознавателя жестов, перетащив его из распознавателя в файл SnapViewController.swift
. Назовите действие handleTap
и выберите тип действия как UITapGestureRecognizer
вместо AnyObject
.
Измените файл SnapViewController.swift
как показано.
Здесь мы сначала объявляем UIView
, UISnapBehavior
и UIDynamicAnimator
. В viewDidLoad()
мы создаем экземпляр квадратного вида и добавляем его в наш основной вид. Мы также создаем экземпляр аниматора. В handleTap()
действия handleTap()
мы получаем местоположение, к которому было применено handleTap()
и handleTap()
экземпляр поведения привязки для привязки к этому месту. Вы можете изменить уровень колебаний, изменив свойство damping
поведения привязки.
Обратите внимание, что мы создаем экземпляр UISnapBehavior
каждый раз, когда пользователь касается экрана. Мы также удаляем любое предыдущее поведение привязки перед добавлением нового к аниматору. У аниматора должно быть только одно поведение привязки к конкретному элементу. Когда несколько поведений привязки для одного и того же элемента добавляются к одному и тому же аниматору, поведение привязки не будет выполняться, так как он не будет знать, какое из них выполнить первым. Вы можете проверить это, удалив блок if
который удаляет поведение привязки из аниматора. При запуске программы первое нажатие будет работать, как и ожидалось, второе нажатие будет иметь небольшое перемещение квадрата (если оно есть), и когда вы продолжите нажимать на экран и, по существу, добавляете привязку к аниматору, квадрат не будет двигаться в все.
Прикреплять
Класс UIAttachmentBehavior
можно использовать для создания соединения между двумя элементами или между элементом и точкой. Мы будем смотреть на то, как использовать его, прилагая вид на точку привязки. Затем мы добавим жест панорамирования для распознавания перетаскиваний на экране и обновим точку привязки прикрепленного вида, куда пользователь перетаскивает.
Откройте файл Main.storyboard
и найдите контроллер представления Attach
. Перетащите Pan Gesture Recognizer из библиотеки объектов в контроллер представления. Затем создайте действие для распознавателя жестов, перетащив его из распознавателя в файл AttachViewController.swift
. Назовите handlePan
и выберите тип действия как UIPanGestureRecognizer
вместо AnyObject
.
Затем измените файл SnapViewController.swift
как показано.
В приведенном выше коде мы создаем два представления. Большой синий квадратный вид и меньший красный. Красный квадрат есть только в качестве наглядного пособия, чтобы мы могли видеть точку привязанности. Мы не будем прикреплять синий квадрат к красному, скорее мы будем прикреплять его к точке.
После создания двух представлений мы создаем экземпляр экземпляра UIAttachmentBehavior
с элементом squareView
и устанавливаем его опорную точку в качестве местоположения центра красного представления. Затем мы добавим поведение к аниматору.
В функции handlePan()
мы устанавливаем точку привязки поведения вложения в качестве точки касания пользователя, а затем обновляем позицию красного квадрата до этой позиции, чтобы мы могли видеть новое местоположение точки привязки.
Когда вы запускаете приложение, синий квадрат будет падать вниз из-за силы тяжести, но из-за привязанности он не будет полностью падать, вместо этого он начнет колебаться вокруг точки привязки. При перетаскивании на экране красный квадрат будет двигаться вместе с перетаскиванием, как и точка привязки синего квадрата.
От себя
UIPushBehavior
имеет два режима для создания поведения push — непрерывное поведение push и мгновенное поведение push.
Непрерывное нажатие применит величину к виду в течение всего времени нажатия. Это означает, что представление будет ускоряться, потому что к нему постоянно добавляется больше энергии. При мгновенном толчке толчок происходит только один раз, поэтому изображение не ускоряется при движении.
Мы собираемся сравнить поведение двух, создав два представления и применяя различное поведение к каждому представлению.
Измените файл PushViewController.swift
как показано.
Чтобы толчок сработал, вам нужно установить параметры величины и угла толчка. Величина — это вектор силы для поведения толчка. Он используется для расчета того, насколько и насколько быстро перемещается представление. Свойство угла является значением с плавающей точкой в радианах. Это определит направление толчка. В нашем примере угол сдвига составляет 90 градусов (M_PI_2 равно pi / 2). Это сдвигает представления вниз, если вы хотите, чтобы представления были сдвинуты вверх, то вы бы использовали отрицательное значение.
Когда вы запустите приложение, вы заметите, что синий квадрат с мгновенным толчком к нему начинается с большей скоростью, чем красный вид, но красный вид получает большее ускорение и в конечном итоге движется быстрее, чем синий вид.
Настройка динамического поведения вашего представления
Физика по умолчанию, встроенная в динамическое поведение UIKit, может подойти с любыми эффектами, которые вы пытаетесь достичь в своих представлениях, но вы также можете настроить это и изменить то, как элемент реагирует на это поведение. Используя класс UIDynamicItemBehaviour
, вы можете назначать различные характеристики вашим динамическим элементам, которые будут влиять на их реакцию на динамические эффекты, размещенные на них.
Вы делаете это, UIDynamicItemBehaviour
экземпляр класса UIDynamicItemBehaviour
и устанавливая свойства экземпляра, который вы хотите изменить. Затем вы добавляете это к аниматору так же, как и к любому другому поведению.
Свойства, которые вы можете установить в классе поведения элемента:
- трение — значение с плавающей точкой от 0 до 1, которое указывает, насколько стойким к движению будет элемент, когда он скользит по другим предметам или другие предметы скользят по его краям.
- эластичность — значение с плавающей запятой между 0 и 1, которое определяет эластичность столкновения элемента.
- плотность — используется аниматором для расчета массы элемента, которая влияет на то, как он реагирует на приложенные к нему силы. Это значение с плавающей запятой между 0 и 1, и его значение по умолчанию равно 1.
- allowRotation — логическое значение, определяющее, сможет ли элемент поворачиваться аниматором.
- Сопротивление — это сопротивление элемента движению. Это может быть от 0 до
CGFLOAT_MAX
.
чем выше вы устанавливаете значение, тем более устойчивым становится элемент к действующим на него силам. - angularResistance — определяет сопротивление элемента вращательному движению.
В качестве примера мы будем использовать первый пример из класса GravityAndCollisionViewController
и добавим поведение элемента, которое сделает представление квадрата более эластичным.
Добавьте следующую переменную в класс GravityAndCollisionViewController
.
var itemBehaviour: UIDynamicItemBehavior!
Затем добавьте следующее в конце viewDidLoad()
itemBehaviour = UIDynamicItemBehavior(items: [squareView]) itemBehaviour.elasticity = 0.7 animator.addBehavior(itemBehaviour)
При запуске приложения квадратный вид будет отскакивать больше раз, чем ранее, до того как установится из-за его более высокой эластичности.
Пример приложения
Теперь мы будем использовать различные варианты поведения, на которые мы смотрели, чтобы создать представление, которое открывается при запуске и которое пользователь может отклонить, либо нажав кнопку, либо взяв вид и переместив его за пределы экрана. Представление будет перемещено за пределы экрана только в том случае, если пользователь перемещает его слишком далеко на юг, в противном случае он просто возвращается на исходное место. В обоих случаях вид будет падать с экрана.
Чтобы начать, добавьте кнопку в Пример сцены приложения в Main.storyboard
. Затем добавьте действие путем перетаскивания ExampleApplicationViewController
управления с кнопки в класс ExampleApplicationViewController
. Назовите действие showAlertView
. Когда вы закончите, у вас должна появиться ExampleApplicationViewController.swift
функция в вашем файле ExampleApplicationViewController.swift
.
@IBAction func showAlertView(sender: UIButton) { }
Затем измените файл ExampleApplicationViewController.swift
как показано ниже. Я не буду объяснять все, потому что мы уже рассмотрели поведение, которое я использовал в предыдущих примерах. Для того, что не было рассмотрено, я включил комментарии, чтобы объяснить код.
Когда вы запускаете приложение, при нажатии кнопки «Показать оповещение» на экран будет привязано красное представление, а фон станет серым. Пользователь сможет закрыть вид, нажав кнопку «Отключить». При этом вид исчезнет с экрана, а фон снова станет белым. Пользователь также может перетаскивать вид, но после его отпускания он возвращается на свое место. Когда пользователь перетаскивает вид слишком далеко и отпускает его, он падает с экрана.
Вывод
У вас есть большая свобода с библиотекой UIKit Dynamics, создающей представления, которые действуют как объекты реального мира. Существует бесконечное множество возможностей того, как это можно применить к вашему приложению. Однако вы можете испытать искушение добавить множество интересных эффектов в свое приложение, помните — просто потому, что вы можете, это не значит, что вы должны это делать.
Что бы вы ни решили сделать с этими инструментами, убедитесь, что вы придерживаетесь Руководства Apple по интерфейсу iOS для человека и не перегружаете своих пользователей всеми «крутыми глазками» в вашем приложении. Одна из самых первых вещей, которые вы прочтете в документе iOS HIG, — «Уважение. Пользовательский интерфейс помогает пользователям понимать контент и взаимодействовать с ним, но никогда не конкурирует с ним », поэтому используйте свои возможности с умом.