J'ai pris quelques informations glanées dans les réponses de Paul Solt et d'Anoime, et je les ai ajoutées à une catégorie existante que j'ai créée pour UIViewController afin de permettre de rendre n'importe quel UIView traînable, pour le rendre maintenant pinçable en utilisant des gestes et des transformations.
Remarque : cette opération modifie la propriété de la balise de la vue que vous rendez glissante/rapide. Donc si vous avez besoin de la balise pour autre chose, vous pouvez envisager de placer cette valeur dans le NSMutableDictionary utilisé par cette technique. Celui-ci est disponible sous la forme [self dictForView:theView]
Mise en œuvre dans votre projet :
Vous pouvez faire en sorte que n'importe quelle vue secondaire de la "vue" des contrôleurs de vue puisse être glissée ou pincée (ou les deux). placez une seule ligne de code dans votre viewDidLoad (par exemple :)
[self makeView:mySubView draggable:YES pinchable:YES minPinchScale:0.75 maxPinchScale:1.0];
le désactiver dans viewDidUnload (libère les invitations et le dictionnaire) :
[self makeView:mySubView draggable:NO pinchable:NO minPinchScale:1.0 maxPinchScale:1.0];
Fichier DragAndPinchScale.h
#import <UIKit/UIKit.h>
@interface UIViewController (DragAndPinchScale)
-(void) makeView:(UIView*)aView
draggable:(BOOL)draggable
pinchable:(BOOL)pinchable
minPinchScale:(CGFloat)minPinchScale
maxPinchScale:(CGFloat)maxPinchScale;
-(NSMutableDictionary *) dictForView:(UIView *)theView;
-(NSMutableDictionary *) dictForViewGuestures:(UIGestureRecognizer *)guesture;
@end
Fichier DragAndPinchScale.m
#import "DragAndPinchScale.h"
@implementation UIViewController (DragAndPinchScale)
-(NSMutableDictionary *) dictForView:(UIView *)theView{
NSMutableDictionary *dict = (NSMutableDictionary*) (void*) theView.tag;
if (!dict) {
dict = [[NSMutableDictionary dictionary ] retain];
theView.tag = (NSInteger) (void *) dict;
}
return dict;
}
-(NSMutableDictionary *) dictForViewGuestures:(UIGestureRecognizer *)guesture {
return [self dictForView:guesture.view];
}
- (IBAction)fingersDidPinchInPinchableView:(UIPinchGestureRecognizer *)fingers {
NSMutableDictionary *dict = [self dictForViewGuestures:fingers];
UIView *viewToZoom = fingers.view;
CGFloat lastScale;
if([fingers state] == UIGestureRecognizerStateBegan) {
// Reset the last scale, necessary if there are multiple objects with different scales
lastScale = [fingers scale];
} else {
lastScale = [[dict objectForKey:@"lastScale"] floatValue];
}
if ([fingers state] == UIGestureRecognizerStateBegan ||
[fingers state] == UIGestureRecognizerStateChanged) {
CGFloat currentScale = [[[fingers view].layer valueForKeyPath:@"transform.scale"] floatValue];
// limits to adjust the max/min values of zoom
CGFloat maxScale = [[dict objectForKey:@"maxScale"] floatValue];
CGFloat minScale = [[dict objectForKey:@"minScale"] floatValue];
CGFloat newScale = 1 - (lastScale - [fingers scale]);
newScale = MIN(newScale, maxScale / currentScale);
newScale = MAX(newScale, minScale / currentScale);
CGAffineTransform transform = CGAffineTransformScale([[fingers view] transform], newScale, newScale);
viewToZoom.transform = transform;
lastScale = [fingers scale]; // Store the previous scale factor for the next pinch gesture call
}
[dict setObject:[NSNumber numberWithFloat:lastScale]
forKey:@"lastScale"];
}
- (void)fingerDidMoveInDraggableView:(UIPanGestureRecognizer *)finger {
NSMutableDictionary *dict = [self dictForViewGuestures:finger];
UIView *viewToDrag = finger.view;
if (finger.state == UIGestureRecognizerStateBegan) {
[dict setObject:[NSValue valueWithCGPoint:viewToDrag.frame.origin]
forKey:@"startDragOffset"];
[dict setObject:[NSValue valueWithCGPoint:[finger locationInView:self.view]]
forKey:@"startDragLocation"];
}
else if (finger.state == UIGestureRecognizerStateChanged) {
NSMutableDictionary *dict = (NSMutableDictionary*) (void*) viewToDrag.tag;
CGPoint stopLocation = [finger locationInView:self.view];
CGPoint startDragLocation = [[dict valueForKey:@"startDragLocation"] CGPointValue];
CGPoint startDragOffset = [[dict valueForKey:@"startDragOffset"] CGPointValue];
CGFloat dx = stopLocation.x - startDragLocation.x;
CGFloat dy = stopLocation.y - startDragLocation.y;
// CGFloat distance = sqrt(dx*dx + dy*dy );
CGRect dragFrame = viewToDrag.frame;
CGSize selfViewSize = self.view.frame.size;
if (!UIDeviceOrientationIsPortrait(self.interfaceOrientation)) {
selfViewSize = CGSizeMake(selfViewSize.height,selfViewSize.width);
}
selfViewSize.width -= dragFrame.size.width;
selfViewSize.height -= dragFrame.size.height;
dragFrame.origin.x = MIN(selfViewSize.width, MAX(0,startDragOffset.x+dx));
dragFrame.origin.y = MIN(selfViewSize.height,MAX(0,startDragOffset.y+dy));
viewToDrag.frame = dragFrame;
}
else if (finger.state == UIGestureRecognizerStateEnded) {
[dict removeObjectForKey:@"startDragLocation"];
[dict removeObjectForKey:@"startDragOffset"];
}
}
-(void) makeView:(UIView*)aView
draggable:(BOOL)draggable
pinchable:(BOOL)pinchable
minPinchScale:(CGFloat)minPinchScale
maxPinchScale:(CGFloat)maxPinchScale{
NSMutableDictionary *dict = (NSMutableDictionary*) (void*) aView.tag;
if (!(pinchable || draggable)) {
if (dict){
[dict release];
aView.tag = 0;
}
return;
}
if (dict) {
UIPanGestureRecognizer *pan =[dict objectForKey:@"UIPanGestureRecognizer"];
if(pan){
if ([aView.gestureRecognizers indexOfObject:pan]!=NSNotFound) {
[aView removeGestureRecognizer:pan];
}
[dict removeObjectForKey:@"UIPanGestureRecognizer"];
}
UIPinchGestureRecognizer *pinch =[dict objectForKey:@"UIPinchGestureRecognizer"];
if(pinch){
if ([aView.gestureRecognizers indexOfObject:pinch]!=NSNotFound) {
[aView removeGestureRecognizer:pinch];
}
[dict removeObjectForKey:@"UIPinchGestureRecognizer"];
}
[dict removeObjectForKey:@"startDragLocation"];
[dict removeObjectForKey:@"startDragOffset"];
[dict removeObjectForKey:@"lastScale"];
[dict removeObjectForKey:@"minScale"];
[dict removeObjectForKey:@"maxScale"];
}
if (draggable) {
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(fingerDidMoveInDraggableView:)];
pan.minimumNumberOfTouches = 1;
pan.maximumNumberOfTouches = 1;
[aView addGestureRecognizer:pan];
[pan release];
dict = [self dictForViewGuestures:pan];
[dict setObject:pan forKey:@"UIPanGestureRecognizer"];
}
if (pinchable) {
CGAffineTransform initialTramsform = CGAffineTransformMakeScale(1.0, 1.0);
aView.transform = initialTramsform;
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(fingersDidPinchInPinchableView:)];
[aView addGestureRecognizer:pinch];
[pinch release];
dict = [self dictForViewGuestures:pinch];
[dict setObject:pinch forKey:@"UIPinchGestureRecognizer"];
[dict setObject:[NSNumber numberWithFloat:minPinchScale] forKey:@"minScale"];
[dict setObject:[NSNumber numberWithFloat:maxPinchScale] forKey:@"maxScale"];
}
}
@end
0 votes
Regardez cet échantillon sur le pinch zoom cocoabugs.blogspot.com/2011/03/