Обсуждение
Обсуждение
Когда мы говорим о рисовании фигур в iOS или OS X, мы подразумеваем пути (paths). Что такое путь в данном случае? Путь возникает между одной или несколькими сериями точек, расположенными на экране. Между путями и линиями существует значительная разница. Путь может содержать несколько линий, но линия не может содержать несколько путей. Считайте, что путь — это просто серия точек.
Линии нужно рисовать, пользуясь путями. Укажите начальную и конечную точки пути, а потом прикажите Core Graphics заполнить этот путь за вас. Core Graphics считает, что вы создали линию вдоль этого пути, и нарисует его указанным вами цветом (см. раздел 17.3).
Более подробно мы рассмотрим пути в дальнейшем (в разделе 17.7), а пока сосредоточимся на том, как создавать с помощью путей прямые линии. Для этого нужно выполнить следующие шаги.
1. Выбрать цвет в вашем графическом контексте (см. раздел 17.3).
2. Получить описатель графического контекста — это делается с помощью функции UIGraphicsGetCurrentContext.
3. Задать начальную точку для линии, воспользовавшись процедурой CGContextMoveToPoint.
4. Переместить перо в графическом контексте, воспользовавшись процедурой CGContextAddLineToPoint, и указать конечную точку линии.
5. Создать намеченный путь с помощью процедуры CGContextStrokePath. Эта процедура отрисует путь в графическом контексте, использовав указанный вами цвет.
Кроме того, можно воспользоваться процедурой CGContextSetLineWidth, которая задает толщину линий, отрисовываемых в заданном графическом контексте. Первый параметр этой процедуры — графический контекст, на котором вы рисуете, а второй параметр — толщина линии, выражаемая числом с плавающей точкой (CGFloat).
В iOS толщина линии измеряется в логических точках.
Вот пример:
— (void)drawRect:(CGRect)rect{
/* Задаем цвет, которым собираемся отрисовывать линию. */
[[UIColor brownColor] set];
/* Получаем актуальный графический контекст. */
CGContextRef currentContext = UIGraphicsGetCurrentContext();
/* Задаем толщину линии. */
CGContextSetLineWidth(currentContext,
5.0f);
/* В этой точке будет начинаться линия. */
CGContextMoveToPoint(currentContext,
50.0f,
10.0f);
/* В этой точке линия будет заканчиваться. */
CGContextAddLineToPoint(currentContext,
100.0f,
200.0f);
/* Для отрисовки линии используем цвет, заданный в контексте в настоящий
момент. */
CGContextStrokePath(currentContext);
}
Запустив этот код в симуляторе iOS, вы получите примерно такие результаты, как на рис. 17.17.
Рис. 17.17. Рисование линии в текущем графическом контексте
Приведу еще один пример. Как было упомянуто ранее, процедура CGContextAddLineToPoint указывает конечную точку данной линии. А что делать, если мы уже провели линию из точки (20; 20) в точку (100; 100), а теперь хотим провести линию из точки (100; 100) в точку (300; 100)? Может возникнуть версия, что, нарисовав первую линию, мы должны переместить перо в точку (100; 100) с помощью процедуры CGContextMoveToPoint, а потом провести линию в точку (300; 100), используя процедуру CGContextAddLineToPoint. Да, это сработает, но задачу можно решить более эффективным способом. После того как вы вызовете процедуру CGContextAddLineToPoint для указания конечной точки отрисовываемой в данный момент линии, положение вашего пера изменится на значение, которое будет передано этому методу. Иными словами, после того, как вы выпустите метод, воспользовавшись пером, метод поставит перо в конечной точке того объекта, который был отрисован (объект может быть любым). Итак, чтобы нарисовать еще одну линию из актуальной конечной точки в новую точку, нужно просто еще раз вызвать процедуру CGContextAddLineToPoint, сообщив ей новую конечную точку. Вот пример:
— (void)drawRect:(CGRect)rect{
/* Задаем цвет, которым мы собираемся отрисовывать линию. */
[[UIColor brownColor] set];
/* Получаем актуальный графический контекст. */
CGContextRef currentContext = UIGraphicsGetCurrentContext();
/* Задаем толщину линий. */
CGContextSetLineWidth(currentContext,
5.0f);
/* В этой точке будет начинаться линия. */
CGContextMoveToPoint(currentContext,
20.0f,
20.0f);
/* В этой точке линия будет заканчиваться. */
CGContextAddLineToPoint(currentContext,
100.0f,
100.0f);
/* Продолжаем линию до новой точки. */
CGContextAddLineToPoint(currentContext,
300.0f,
100.0f);
/* Для отрисовки линии используем цвет, заданный в контексте в настоящий
момент. */
CGContextStrokePath(currentContext);
}
Результат показан на рис. 17.18. Как видите, удалось успешно отрисовать обе линии, не перемещая перо для отрисовки второй линии.
Точка соединения двух линий называется перемычкой (Join). Работая с Core Graphics, можно указывать тип перемычки, которую вы хотите сделать между линиями, сочлененными друг с другом. Для выбора такого типа используется процедура CGContextSetLineJoin. Она принимает два параметра: во-первых, графический контекст, в котором вы задаете перемычку такого типа, а во-вторых, сам тип перемычки, CGLineJoin. CGLineJoin — это перечень следующих значений:
Рис. 17.18. Одновременно отрисовываем две линии
• kCGLineJoinMiter — на месте перемычки образуется острый угол. Этот тип задается по умолчанию;
• kCGLineJoinBevel — угол на месте перемычки линий будет немного спрямлен, как будто обтесан;
• kCGLineJoinRound — как понятно из названия, такая перемычка — скругленная.
Рассмотрим пример. Допустим, мы хотим написать программу, способную отрисовывать в графическом контексте «скатные крыши», каждая из которых иллюстрировала бы определенный тип перемычки между линиями, а также выводить под «крышей» текст с названием используемой перемычки. В результате получится рисунок, напоминающий рис. 17.19.
Рис. 17.19. Три типа перемычек между линиями, существующие в Core Graphics
Для решения этой задачи я написал метод drawRooftopAtTopPointof: textToDisplay: lineJoin:, принимающий три параметра:
• точку, в которой должна располагаться верхушка «крыши»;
• текст, отображаемый под «крышей»;
• используемый тип перемычки.
Код будет таким:
— (void) drawRooftopAtTopPointof:(CGPoint)paramTopPoint
textToDisplay:(NSString *)paramText
lineJoin:(CGLineJoin)paramLineJoin{
/* Задаем цвет, которым собираемся отрисовывать линию. */
[[UIColor brownColor] set];
/* Получаем актуальный графический контекст. */
CGContextRef currentContext = UIGraphicsGetCurrentContext();
/* Задаем перемычку между линиями. */
CGContextSetLineJoin(currentContext,
paramLineJoin);
/* Задаем толщину линий. */
CGContextSetLineWidth(currentContext,
20.0f);
/* В этой точке будет начинаться линия. */
CGContextMoveToPoint(currentContext,
paramTopPoint.x — 140,
paramTopPoint.y + 100);
/* В этой точке линия будет заканчиваться. */
CGContextAddLineToPoint(currentContext,
paramTopPoint.x,
paramTopPoint.y);
/* Продолжаем линию до новой точки, чтобы получилась фигура,
напоминающая крышу. */
CGContextAddLineToPoint(currentContext,
paramTopPoint.x + 140,
paramTopPoint.y + 100);
/* Для отрисовки линии используем цвет, заданный в контексте в настоящий
момент. */
CGContextStrokePath(currentContext);
/* Рисуем под крышей текст, при этом используется черный цвет. */
[[UIColor blackColor] set];
/* Теперь рисуем текст. */
CGPoint drawingPoint = CGPointMake(paramTopPoint.x — 40.0f,
paramTopPoint.y + 60.0f);
[paramText drawAtPoint: drawingPoint
withFont: [UIFont boldSystemFontOfSize:30.0f]];
}
А теперь вызовем наш метод в методе экземпляра drawRect: объекта-вида, где находится графический контекст:
— (void)drawRect:(CGRect)rect{
[self drawRooftopAtTopPointof: CGPointMake(160.0f, 40.0f)
textToDisplay:@"Miter"
lineJoin: kCGLineJoinMiter];
[self drawRooftopAtTopPointof: CGPointMake(160.0f, 180.0f)
textToDisplay:@"Bevel"
lineJoin: kCGLineJoinBevel];
[self drawRooftopAtTopPointof: CGPointMake(160.0f, 320.0f)
textToDisplay:@"Round"
lineJoin: kCGLineJoinRound];
}
Более 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) на устройстве. Чтобы лучше понять, как работает этот механизм,
Обсуждение
Обсуждение Пуш-уведомления похожи на локальные уведомления тем, что позволяют сообщать пользователю определенную информацию, даже если ваше приложение неактивно при поступлении уведомления. В то время как локальные уведомления назначаются самим приложением,