Обсуждение
Обсуждение
Толчки, прилагаемые к экранным элементам, очень полезны — особенно толчки, вызывающие непрерывное движение. Допустим, вы разрабатываете приложение-фотоальбом для iPad. В верхней части экрана создали три слайда, каждый из которых соответствует странице альбома, созданной пользователем. В нижней части экрана располагаются различные картинки, которые пользователь может перетаскивать и раскладывать на страницах. Один из способов, позволяющих реализовать для пользователя такую возможность, — добавление к опорному виду регистратора жестов касания (tap gesture recognizer), создание которого рассмотрено в разделе 10.5. Этот регистратор обеспечивает отслеживание пользовательских жестов касания и позволяет перемещать изображения на целевой слайд. Процесс выглядит как перетаскивание. Другой, пожалуй, более оптимальный способ решения этой задачи — использование толчкового поведения, которое разработчики Apple включили в UIKit.
Толчковое поведение относится к типу UIPushBehavior и обладает магнитудой и углом. Угол измеряется в радианах, а магнитуда в 1 точку приводит к ускорению движения, равному 100 точек/с2. Толчковые поведения создаются точно так же, как и любые другие: сначала их необходимо инициализировать, а потом добавить к аниматору типа UIDynamicAnimator.
В этом примере мы собираемся создать вид и поместить его в центре более крупного вида контроллера. Мы подключим к аниматору поведение столкновений, благодаря чему маленький вид не будет вылетать за пределы большого вида (с контроллером). О том, как работать со столкновениями, мы поговорили в разделе 2.2. Затем добавим регистратор жестов касания (см. раздел 10.5) к контроллеру вида. Этот регистратор будет уведомлять нас о каждом жесте касания, произошедшем на экране.
Когда касание будет зарегистрировано, рассчитаем угол между точкой касания и центром маленького квадратного вида. Так мы получим угол, выраженный в радианах, под которым сможем толкнуть этот квадратный вид. Затем рассчитаем расстояние между точкой касания и центром маленького вида, полученное значение используем в качестве магнитуды толчка. Таким образом, магнитуда будет тем больше, чем дальше от центра квадратного вида находится точка касания.
В данном разделе предполагается, что читатель понимает основы тригонометрии. Но даже если вы с ними не знакомы — ничего страшного, поскольку для работы потребуются лишь те формулы, которые я описываю в примерах кода к этому разделу. На рис. 2.2 показано, как вычисляется угол между двумя точками. Итак, я надеюсь, что объяснение получится достаточно подробным, чтобы вы могли написать собственное решение данной проблемы.
Рис. 2.2. Расчет угла между двумя точками
Итак, начнем с определения всех важных свойств нашего контроллера вида:
#import «ViewController.h»
@interface ViewController ()
@property (nonatomic, strong) UIView *squareView;
@property (nonatomic, strong) UIDynamicAnimator *animator;
@property (nonatomic, strong) UIPushBehavior *pushBehavior;
@end
@implementation ViewController
<# Остальной ваш код находится здесь #>
В этом примере мы добавим к аниматору поведение столкновения и толчковое поведение. Толчковое поведение добавляется к классу в качестве свойства, а поведение столкновений — просто как локальная переменная. Дело в том, что, как только мы добавим к аниматору поведение столкновения, именно аниматор будет вычислять все столкновения с границами опорного вида и нам больше не придется ссылаться на это поведение столкновений. Однако если говорить о толчковом поведении, то при обработке касаний придется обновлять это толчковое поведение, чтобы графический элемент подталкивался к точке касания. Вот почему нам требуется связь касания с толчковым поведением, но не требуется такая связь со столкновениями.
Далее напишем метод, создающий маленький квадратный вид и помещающий его в центре большого вида с контроллером:
— (void) createSmallSquareView{
self.squareView =
[[UIView alloc] initWithFrame:
CGRectMake(0.0f, 0.0f, 80.0f, 80.0f)];
self.squareView.backgroundColor = [UIColor greenColor];
self.squareView.center = self.view.center;
[self.view addSubview: self.squareView];
}
Затем применим регистратор жестов касания, чтобы обнаруживать прикосновения к виду с контроллером:
— (void) createGestureRecognizer{
UITapGestureRecognizer *tapGestureRecognizer =
[[UITapGestureRecognizer alloc] initWithTarget: self
action:@selector(handleTap:)];
[self.view addGestureRecognizer: tapGestureRecognizer];
}
Эти методы выполняют за нас всю необходимую работу. Позже, когда вид отобразится на экране, мы будем вызывать эти методы и они будут действовать.
И не забудем написать метод, который будет задавать поведение столкновения и толчковое поведение:
— (void) createAnimatorAndBehaviors{
self.animator = [[UIDynamicAnimator alloc]
initWithReferenceView: self.view];
/* Создаем обнаружение столкновений */
UICollisionBehavior *collision = [[UICollisionBehavior alloc]
initWithItems:@[self.squareView]];
collision.translatesReferenceBoundsIntoBoundary = YES;
self.pushBehavior = [[UIPushBehavior alloc]
initWithItems:@[self.squareView]
mode: UIPushBehaviorModeContinuous];
[self.animator addBehavior: collision];
[self.animator addBehavior: self.pushBehavior];
}
Подробнее о поведении столкновений рассказано в разделе 2.2. Как только мы запрограммируем все эти методы, нам понадобится вызывать их, когда вид появится на экране:
— (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear: animated];
[self createGestureRecognizer];
[self createSmallSquareView];
[self createAnimatorAndBehaviors];
}
Отлично. Теперь, взглянув на файл реализации метода createGestureRecognizer, вы увидите, что мы устанавливаем регистратор жестов касаний в методе контроллера вида — этот метод называется handleTap:. В методе handleTap: вычисляем расстояние между центральной точкой маленького квадратного вида и той точкой опорного вида, до которой дотронулся пользователь. В результате имеем магнитуду силы толчка. Кроме того, рассчитаем угол между центром маленького квадратного вида и точкой касания, чтобы определить угол толчка:
— (void) handleTap:(UITapGestureRecognizer *)paramTap{
/* Получаем угол между центральной точкой квадратного вида и точкой касания */
CGPoint tapPoint = [paramTap locationInView: self.view];
CGPoint squareViewCenterPoint = self.squareView.center;
/* Вычисляем угол между центральной точкой квадратного вида и точкой касания, чтобы определить угол толчка
Формула для определения угла между двумя точками:
arc tangent 2((p1.x — p2.x), (p1.y — p2.y)) */
CGFloat deltaX = tapPoint.x — squareViewCenterPoint.x;
CGFloat deltaY = tapPoint.y — squareViewCenterPoint.y;
CGFloat angle = atan2(deltaY, deltaX);
[self.pushBehavior setAngle: angle];
/* Используем расстояние между точкой касания и центром квадратного вида для вычисления магнитуды толчка
Формула определения расстояния:
Квадратный корень из ((p1.x — p2.x)^2 + (p1.y — p2.y)^2) */
CGFloat distanceBetweenPoints =
sqrt(pow(tapPoint.x — squareViewCenterPoint.x, 2.0) +
pow(tapPoint.y — squareViewCenterPoint.y, 2.0));
[self.pushBehavior setMagnitude: distanceBetweenPoints / 200.0f];
}
Не буду чрезмерно углубляться в тригонометрию, но в этом коде используется простая формула, изучаемая в школьном курсе. По этой формуле рассчитывается угол в радианах между двумя точками. Также применяется теорема Пифагора, позволяющая узнать расстояние между двумя точками. Эти формулы вы найдете, взглянув на комментарии, которые я оставил в коде. Если же хотите подробнее разобраться с такими понятиями, как углы и радианы, рекомендую проштудировать учебник по тригонометрии.
Теперь, запустив приложение, вы сначала увидите маленький зеленый квадрат в центре экрана. Дотроньтесь до экрана в любой точке поля, окружающего квадрат (белое пространство), чтобы зеленый квадрат (вид) стал двигаться. В данном примере я беру расстояние между точкой касания и центром квадрата и делю его на 200, чтобы получить реалистичную магнитуду толчка, но вы в данном примере можете увеличить ускорение, выбрав, скажем, значение 100, а не 200. Всегда лучше экспериментировать с разными числовыми значениями, чтобы подобрать оптимальный вариант для вашего приложения.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
Обсуждение
Обсуждение Обычно после того, как пользователь успешно снимет фотографию на устройство с iOS, он ожидает, что этот снимок сохранится в его библиотеке фотографий. Однако приложения, не входящие в стандартный комплект программ iOS, могут запросить пользователя сделать снимок
Обсуждение
Обсуждение Фреймворк Assets Library — удобный посредник между разработчиком и библиотекой фотографий. Как будет указано в разделе 13.6, в iOS SDK вам предоставляются встроенные компоненты графического пользовательского интерфейса, которыми можно пользоваться для доступа к
Обсуждение
Обсуждение Чтобы пользователь мог выбирать фотоснимки или видеоролики из своей библиотеки фотографий, необходимо установить свойство sourceType экземпляра UIImagePickerController в значение UIImagePickerControllerSourceTypePhotoLibrary и только потом открывать перед пользователем инструмент для выбора
Обсуждение
Обсуждение Библиотека ресурсов подразделяется на группы. В каждой группе содержатся ресурсы, а каждый ресурс имеет свойства, например URL (универсальные локаторы ресурсов) и объекты представления.Все ресурсы всех типов можно получать из библиотеки ресурсов с помощью
Обсуждение
Обсуждение Класс UIVideoEditorController, содержащийся в iOS SDK, позволяет программисту вывести на экран перед пользователем специальный интерфейс для редактирования. Все, что требуется сделать, — предоставить URL видеоролика, который предполагается отредактировать, а потом
Обсуждение
Обсуждение В зависимости от того, на работу в какой версии iOS рассчитано ваше приложение, его можно запускать и выполнять на различных устройствах, где установлены разные версии iOS. Например, вы можете разрабатывать приложение в последней версии iOS SDK, но в качестве целевой
Обсуждение
Обсуждение Когда приложение переходит в фоновый режим, работа его основного потока приостанавливается. Потоки, которые вы создаете в своем приложении с помощью метода класса detachNewThreadSelector: toTarget: withObject:, относящегося к классу NSThread, также приостанавливаются. Если вы
Обсуждение
Обсуждение Многие приложения, ежедневно поступающие на рынок App Store, обладают возможностями соединения с теми или иными серверами. Некоторые выбирают с сервера данные для обновления, другие отсылают информацию на сервер и т. д. В течение долгого времени в iOS существовал
Обсуждение
Обсуждение В iOS приложение может запросить продолжить воспроизведение своих аудиофайлов, даже если оно само переходит в фоновый режим. В этом разделе мы воспользуемся плеером AVAudioPlayer, который прост и удобен в обращении. Наша задача — запустить аудиоплеер и воспроизвести
Обсуждение
Обсуждение Когда приложение работает в приоритетном режиме, можно получать от экземпляра CLLocationManager делегатные сообщения, информирующие вас о том, что iOS обнаружила перемещение устройства на новое место. Однако если приложение переходит в фоновый режим и становится
Обсуждение
Обсуждение Допустим, пустое приложение iOS (то есть приложение всего с одним окном, для которого еще не написан код) впервые запускается на устройстве с iOS, поддерживающем работу в многозадачном режиме. Оно запускается именно впервые, а не возвращается из фонового режима в
Обсуждение
Обсуждение При работе с приложениями, которые используют класс NSURLConnection, но, уходя в фоновый режим, не запрашивают у iOS дополнительного времени, обращаться с соединениями не составляет никакого труда. Рассмотрим на примере, как будет действовать асинхронное соединение,
Обсуждение
Обсуждение Пока ваше приложение работает в фоновом режиме, может произойти многое! Например, пользователь может вдруг изменить локализацию устройства с iOS на странице Settings (Настройки) и задать, к примеру, испанский язык вместо английского. Приложения могут
Обсуждение
Обсуждение В приложениях, написанных для iOS, файл пакета настроек может быть предоставлен пользователю для внесения собственных настроек. Эти настройки будут доступны пользователю в приложении (Settings) на устройстве. Чтобы лучше понять, как работает этот механизм,
Обсуждение
Обсуждение Пуш-уведомления похожи на локальные уведомления тем, что позволяют сообщать пользователю определенную информацию, даже если ваше приложение неактивно при поступлении уведомления. В то время как локальные уведомления назначаются самим приложением,
Нахавандипур Вандад
Просмотр ограничен
Смотрите доступные для ознакомления главы 👉