Основное изменение масштаба Используя жесты повышения
UIScrollView
делает поддержку жестов повышения для изменения масштаба простого. Ваше приложение указывает факторы изменения масштаба (именно так намного больше или меньший можно сделать содержание), и Вы реализуете единственный метод делегата. Предпринятие тех немногих шагов позволяет Вашему представлению прокрутки поддерживать жесты повышения для изменения масштаба.
Поддержка жестов изменения масштаба повышения
Повышение - в и жесты изменения масштаба повышения является стандартными жестами, которые пользователи приложения для iOS ожидают использовать при увеличении и уменьшении масштаба. Рисунок 3-1 показывает примеры жестов повышения.
Для поддержки изменения масштаба необходимо установить делегата к представлению прокрутки. Объект делегата должен соответствовать UIScrollViewDelegate
протокол. Во многих случаях делегат будет классом контроллера представления прокрутки. Тот класс делегата должен реализовать viewForZoomingInScrollView:
метод и возврат представление для изменения масштаба. Реализация метода делегата, показанного ниже возвратов значение контроллера imageView
свойство, которое является экземпляром UIImageView
. Это указывает что imageView
свойство будет масштабироваться в ответ на жесты изменения масштаба, а также любое программируемое изменение масштаба.
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView |
{ |
return self.imageView; |
} |
Для указания суммы, пользователь может масштабировать, Вы устанавливаете значения minimumZoomScale
и maximumZoomScale
свойства, оба из которых первоначально установлены в 1.0
. Значение этих свойств может быть установлено в Интерфейсном Разработчике UIScrollView
панель инспектора, или программно. Перечисление 3-1 показывает код, требуемый в подклассе UIViewController поддерживать изменение масштаба. Это предполагает, что экземпляр подкласса контроллера является делегатом и реализует viewForZoomingInScrollView:
метод делегата, показанный выше.
Перечисление 3-1 UIViewController
реализация подкласса минимальных требуемых методов изменения масштаба
- (void)viewDidLoad { |
[super viewDidLoad]; |
self.scrollView.minimumZoomScale=0.5; |
self.scrollView.maximumZoomScale=6.0; |
self.scrollView.contentSize=CGSizeMake(1280, 960); |
self.scrollView.delegate=self; |
} |
Указание фактора изменения масштаба и делегата возражает что реализации viewForZoomingInScrollView:
метод является минимальными требованиями для поддержки изменения масштаба с помощью жестов повышения.
Изменение масштаба программно
Представление прокрутки, возможно, должно масштабировать в ответ на сенсорные события, такие как двойные касания или другие жесты касания, или в ответ на другое пользовательское действие кроме жеста повышения. Позволить это, UIScrollView
обеспечивает реализации двух методов: setZoomScale:animated:
и zoomToRect:animated:
.
setZoomScale:animated:
устанавливает текущий масштаб изменения масштаба в указанное значение. Значение должно быть в диапазоне, указанном minimumZoomScale
и maximumZoomScale
диапазон. Если анимированный параметр YES
, изменение масштаба выполняет постоянную анимацию, пока оно не достигает своего завершения; иначе изменение по своим масштабам непосредственно. Также возможно установить zoomScale
свойство непосредственно. Это - эквивалент вызова setZoomScale:animated:
передача NO
как анимированный параметр. При изменении масштаба использующий этот метод, или путем изменения свойства непосредственно, представление будет масштабироваться таким образом, что центр представления остается стационарным.
zoomToRect:animated:
метод масштабирует содержание для заполнения указанного прямоугольника. Как с setZoomScale:animated:
этот метод это имеет анимированный параметр, определяющий, приводит ли изменение в расположении и изменении масштаба к анимации, имеющей место.
Ваше приложение будет часто хотеть установить масштаб изменения масштаба и расположение в ответ на касание в определенном расположении. Поскольку setZoomScale:animated:
изменения масштаба вокруг центра видимого содержания, Вам будет нужна функция, которая будет брать определенное расположение и масштабировать фактор и преобразовывать это в прямоугольник, который является надлежащим zoomToRect:animated:
. Служебный метод, получающий представление прокрутки, масштаб изменения масштаба и точку для центрирования изменения масштаба rect на, показан в Перечислении 3-2
Перечисление 3-2 служебный метод, преобразовывающий указанный масштаб и центральную точку к прямоугольнику для изменения масштаба
- (CGRect)zoomRectForScrollView:(UIScrollView *)scrollView withScale:(float)scale withCenter:(CGPoint)center { |
CGRect zoomRect; |
// The zoom rect is in the content view's coordinates. |
// At a zoom scale of 1.0, it would be the size of the |
// imageScrollView's bounds. |
// As the zoom scale decreases, so more content is visible, |
// the size of the rect grows. |
zoomRect.size.height = scrollView.frame.size.height / scale; |
zoomRect.size.width = scrollView.frame.size.width / scale; |
// choose an origin so as to get the right center. |
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0); |
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0); |
return zoomRect; |
} |
} |
Этот служебный метод полезен при ответе на двойное касание в пользовательском подклассе, поддерживающем тот жест. Для использования этого метода просто передают соответствующий экземпляр UIScrollView, новый масштаб (часто получаемый из существующего zoomScale
путем добавления или умножения суммы изменения масштаба), и точка, вокруг которой можно центрировать изменение масштаба. Когда ответ на двойное касание жестикулирует, центральная точка обычно является расположением касания. Прямоугольник, возвращающийся методом, подходит для передачи zoomToRect:animated:
метод.
Информирование Делегата, что Закончено Изменение масштаба
Когда пользователь завершил жесты повышения изменения масштаба, или программируемое изменение масштаба представления прокрутки завершается, UIScrollView
делегату сообщают путем получения a scrollViewDidEndZooming:withView:atScale:
сообщение.
Этот метод передается экземпляр представления прокрутки, подпредставление представления прокрутки, прокрученное, и масштабный коэффициент, в котором изменение масштаба завершилось как параметры. После получения этого делегата обмениваются сообщениями, Ваше приложение может тогда принять соответствующие меры.
Обеспечение, что Масштабируемым Содержанием является Sharp, когда Масштабируется
Когда содержание представления прокрутки масштабируется, содержание представления изменения масштаба просто масштабируется в ответ на изменение в факторе прокрутки. Это создает в большем или меньшем, довольном, но не заставляет содержание перерисовывать. В результате выведенное на экран содержание не выведено на экран резко. Когда масштабируемое содержание является изображением, и Ваше приложение не выводит на экран новое, более подробное содержание, такое как приложение Карт, это может не быть проблемой.
Если Ваше приложение действительно должно вывести на экран более подробные растровые изображения в ответ на изменение масштаба, можно хотеть исследовать пример Мозаичного размещения в примере кода ScrollViewSuite. Это использует метод предварительного рендеринга масштабируемого содержания в маленьких блоках, и затем выводит на экран тех в отдельных представлениях в представлении прокрутки.
Однако, если Ваше масштабируемое содержание нарисовано в режиме реального времени и должно быть выведено на экран резко, когда масштабируется, Ваш класс приложений, рисующий масштабируемое представление, должен использовать Базовую Анимацию. Класс должен изменить Базовый класс Анимации, используемый в качестве UIView
уровень класса к CATiledLayer
и нарисуйте использование Базовой Анимации drawLayer:inContext:
метод.
Перечисление 3-3 показывает полноценное внедрение подкласса, который нарисует крест и позволит Вам масштабировать. Изображение остается резким в течение действия изменения масштаба. Zoomable
представление является a UIView
подкласс, добавленный как подпредставление представления прокрутки с размером содержания (460,320) и возвращающийся прокруткой, просматривает метод делегата viewForZoomingInScrollView:
. Никакое действие с частью разработчика не требуется, чтобы вызывать Zoomable
представление, которое будет перерисовано, когда происходит изменение масштаба.
Реализация перечисления 3-3 подкласса UIView, что его содержание получения резко во время изменения масштаба
#import "ZoomableView.h" |
#import <QuartzCore/QuartzCore.h> |
@implementation ZoomableView |
// Set the UIView layer to CATiledLayer |
+(Class)layerClass |
{ |
return [CATiledLayer class]; |
} |
// Initialize the layer by setting |
// the levelsOfDetailBias of bias and levelsOfDetail |
// of the tiled layer |
-(id)initWithFrame:(CGRect)r |
{ |
self = [super initWithFrame:r]; |
if(self) { |
CATiledLayer *tempTiledLayer = (CATiledLayer*)self.layer; |
tempTiledLayer.levelsOfDetail = 5; |
tempTiledLayer.levelsOfDetailBias = 2; |
self.opaque=YES; |
} |
return self; |
} |
// Implement -drawRect: so that the UIView class works correctly |
// Real drawing work is done in -drawLayer:inContext |
-(void)drawRect:(CGRect)r |
{ |
} |
-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context |
{ |
// The context is appropriately scaled and translated such that you can draw to this context |
// as if you were drawing to the entire layer and the correct content will be rendered. |
// We assume the current CTM will be a non-rotated uniformly scaled |
// affine transform, which implies that |
// a == d and b == c == 0 |
// CGFloat scale = CGContextGetCTM(context).a; |
// While not used here, it may be useful in other situations. |
// The clip bounding box indicates the area of the context that |
// is being requested for rendering. While not used here |
// your app may require it to do scaling in other |
// situations. |
// CGRect rect = CGContextGetClipBoundingBox(context); |
// Set and draw the background color of the entire layer |
// The other option is to set the layer as opaque=NO; |
// eliminate the following two lines of code |
// and set the scroll view background color |
CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0); |
CGContextFillRect(context,self.bounds); |
// draw a simple plus sign |
CGContextSetRGBStrokeColor(context, 0.0, 0.0, 1.0, 1.0); |
CGContextBeginPath(context); |
CGContextMoveToPoint(context,35,255); |
CGContextAddLineToPoint(context,35,205); |
CGContextAddLineToPoint(context,135,205); |
CGContextAddLineToPoint(context,135,105); |
CGContextAddLineToPoint(context,185,105); |
CGContextAddLineToPoint(context,185,205); |
CGContextAddLineToPoint(context,285,205); |
CGContextAddLineToPoint(context,285,255); |
CGContextAddLineToPoint(context,185,255); |
CGContextAddLineToPoint(context,185,355); |
CGContextAddLineToPoint(context,135,355); |
CGContextAddLineToPoint(context,135,255); |
CGContextAddLineToPoint(context,35,255); |
CGContextClosePath(context); |
// Stroke the simple shape |
CGContextStrokePath(context); |
} |