UIPinchGestureRecognizer 中捏合缩放的最大/最小比例 - iPhone iOS
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5150642/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Max/Min Scale of Pinch Zoom in UIPinchGestureRecognizer - iPhone iOS
提问by VinnyD
How would I be able to limit the scale of the UIPinchGestureRecognizer to a min and max level? The scale property below seems to be relative to the last known scale (the delta from last state) and I can't figure out how to set a limit to the size/heigh of the object being zoomed.
我将如何能够在UIPinchGestureRecognizer的规模限制在最小和最大水平?下面的 scale 属性似乎是相对于最后一个已知比例(从最后一个状态开始的增量),我无法弄清楚如何设置被缩放对象的大小/高度的限制。
-(void)scale:(id)sender {
[self.view bringSubviewToFront:[(UIPinchGestureRecognizer*)sender view]];
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
lastScale = 1.0;
return;
}
CGFloat pinchscale = [(UIPinchGestureRecognizer*)sender scale];
CGFloat scale = 1.0 - (lastScale - pinchscale);
CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)sender view].transform;
CGAffineTransform holderTransform = holderView.transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[[(UIPinchGestureRecognizer*)sender view] setTransform:newTransform];
lastScale = [(UIPinchGestureRecognizer*)sender scale];
}
}
采纳答案by Anomie
There isn't a way to limit the scale on a UIPinchGestureRecognizer
. To limit the height in your code, you should be able to do something like this:
没有办法限制UIPinchGestureRecognizer
. 要限制代码中的高度,您应该能够执行以下操作:
CGFloat scale = 1.0 - (lastScale - pinchscale);
CGRect bounds = [(UIPinchGestureRecognizer*)sender view].bounds;
scale = MIN(scale, maximumHeight / CGRectGetHeight(bounds));
scale = MAX(scale, minimumHeight / CGRectGetHeight(bounds));
To limit width, change 'Height' to 'Width' in the last two lines.
要限制宽度,请将最后两行中的“高度”更改为“宽度”。
回答by Paul Solt
Here is the solution that I figured out after using Anomie's answer as a starting point.
这是我在使用 Anomie 的答案作为起点后想出的解决方案。
- (void)handlePinchGesture:(UIPinchGestureRecognizer *)gestureRecognizer {
if([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
// Reset the last scale, necessary if there are multiple objects with different scales
lastScale = [gestureRecognizer scale];
}
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
[gestureRecognizer state] == UIGestureRecognizerStateChanged) {
CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:@"transform.scale"] floatValue];
// Constants to adjust the max/min values of zoom
const CGFloat kMaxScale = 2.0;
const CGFloat kMinScale = 1.0;
CGFloat newScale = 1 - (lastScale - [gestureRecognizer scale]);
newScale = MIN(newScale, kMaxScale / currentScale);
newScale = MAX(newScale, kMinScale / currentScale);
CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
[gestureRecognizer view].transform = transform;
lastScale = [gestureRecognizer scale]; // Store the previous scale factor for the next pinch gesture call
}
}
回答by damian
The problem with most of the other answers is that they are trying to deal with scale as a linear value, when in fact it is non-linear due to the way UIPinchGestureRecognizer
calculates its scale property based on the touch distance. When this isn't taken into account, the user must use more or less pinch distance to 'undo' the scaling applied by a previous pinch gesture.
大多数其他答案的问题在于他们试图将比例作为线性值处理,而实际上由于UIPinchGestureRecognizer
基于触摸距离计算其比例属性的方式,它是非线性的。如果不考虑这一点,用户必须使用更多或更少的捏合距离来“撤消”先前捏合手势应用的缩放。
Consider: suppose transform.scale
= 1.0
and I place my fingers 6cm apart on the screen, then pinch inwards to 3cm apart - the resulting gestureRecognizer.scale
is 0.5
, and 0.5-1.0
is -0.5
, so transform.scale
will become 1.0+(-0.5)
= 0.5
. Now, I lift my fingers, place them back down 3cm apart and pinch outwards to 6cm. The resulting gestureRecognizer.scale
will be 2.0
, and 2.0-1.0
is 1.0
, so transform.scale
will become 0.5+1.0
= 1.5
. Not what I wanted to happen.
考虑:假设transform.scale
=1.0
并且我将我的手指分开 6 厘米放在屏幕上,然后向内捏合到分开 3 厘米 - 结果gestureRecognizer.scale
是0.5
,0.5-1.0
是-0.5
,所以transform.scale
会变成1.0+(-0.5)
= 0.5
。现在,我抬起手指,将它们放回相距 3 厘米,然后向外捏合至 6 厘米。结果gestureRecognizer.scale
将是2.0
,2.0-1.0
是1.0
,所以transform.scale
将成为0.5+1.0
= 1.5
。不是我想要发生的。
The fix is to calculate the delta pinch scale as a proportion of its previous value. I place my fingers down 6cm apart, and pinch inwards to 3cm, so gestureRecognizer.scale
is 0.5
. 0.5/1.0
is 0.5
, so my new transform.scale
is 1.0*0.5
= 0.5
. Next, I place my fingers down 3cm apart, and pinch outwards to 6cm. gestureRecognizer.scale
is then 2.0
, and 2.0/1.0
is 2.0
, so my new transform.scale
is 0.5*2.0
= 1.0
, which is exactly what I wanted to happen.
解决方法是将增量收缩比例计算为其先前值的比例。我将手指向下分开 6 厘米,然后向内捏 3 厘米,gestureRecognizer.scale
也是0.5
。0.5/1.0
is 0.5
,所以我的新transform.scale
是1.0*0.5
= 0.5
。接下来,我将手指向下分开 3 厘米,然后向外捏合至 6 厘米。gestureRecognizer.scale
is then2.0
和2.0/1.0
is 2.0
,所以我的新transform.scale
是0.5*2.0
= 1.0
,这正是我想要发生的。
Here it is in code:
这是在代码中:
in -(void)viewDidLoad
:
在-(void)viewDidLoad
:
self.zoomGestureCurrentZoom = 1.0f;
in -(void)onZoomGesture:(UIPinchGestureRecognizer*)gestureRecognizer
:
在-(void)onZoomGesture:(UIPinchGestureRecognizer*)gestureRecognizer
:
if ( gestureRecognizer.state == UIGestureRecognizerStateBegan )
{
self.zoomGestureLastScale = gestureRecognizer.scale;
}
else if ( gestureRecognizer.state == UIGestureRecognizerStateChanged )
{
// we have to jump through some hoops to clamp the scale in a way that makes the UX intuitive
float scaleDeltaFactor = gestureRecognizer.scale/self.zoomGestureLastScale;
float currentZoom = self.zoomGestureCurrentZoom;
float newZoom = currentZoom * scaleDeltaFactor;
// clamp
float kMaxZoom = 4.0f;
float kMinZoom = 0.5f;
newZoom = MAX(kMinZoom,MIN(newZoom,kMaxZoom));
self.view.transform = CGAffineTransformScale([[gestureRecognizer view] transform], newZoom, newZoom);
// store for next time
self.zoomGestureCurrentZoom = newZoom;
self.zoomGestureLastScale = gestureRecognizer.scale;
}
回答by unsynchronized
I took some info gleaned from Paul Solt and Anoime's answers, and added that to an existing category I have made for UIViewController to allow making any UIView draggable, to now make it pinchable using gestures and transforms.
我从 Paul Solt 和 Anoime 的答案中收集了一些信息,并将其添加到我为 UIViewController 创建的现有类别中,以允许任何 UIView 可拖动,现在使用手势和变换使其可捏。
Note: this dirties the tag property of the view you are making draggable/pinchable. So if you needed the tag for something else, you can consider placing that value in the NSMutableDictionary being used by this technique. That's available as [self dictForView:theView]
注意:这会弄脏您正在制作的可拖动/可捏视图的标签属性。因此,如果您需要其他内容的标签,您可以考虑将该值放置在此技术使用的 NSMutableDictionary 中。这可作为[self dictForView:theView]
Implementing in your project:
在您的项目中实施:
You can make any subview within the view controllers "view" draggable or pinchable (or both) place a single line of code in your viewDidLoad (for example:)
您可以使视图控制器中的任何子视图“查看”可拖动或可捏(或两者)在您的 viewDidLoad 中放置一行代码(例如:)
[self makeView:mySubView draggable:YES pinchable:YES minPinchScale:0.75 maxPinchScale:1.0];
turn it off in viewDidUnload (releases guestures & dictionary):
在 viewDidUnload 中关闭它(发布guestures和字典):
[self makeView:mySubView draggable:NO pinchable:NO minPinchScale:1.0 maxPinchScale:1.0];
DragAndPinchScale.h file
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
DragAndPinchScale.m file
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
回答by Shagun
Thanks, really useful code snippet above clamping to a minimum and maximum scale.
谢谢,上面的代码片段非常有用,可以限制到最小和最大比例。
I found that when I flipped the view first using:
我发现当我首先使用以下方法翻转视图时:
CGAffineTransformScale(gestureRecognizer.view.transform, -1.0, 1.0);
it would cause a flicker when scaling the view.
缩放视图时会导致闪烁。
Let me know what you think but the solution for me was to update the code sample above, and if the view has been flipped (flag set via property) then invert the scale value:
让我知道您的想法,但我的解决方案是更新上面的代码示例,如果视图已翻转(标志通过属性设置),则反转比例值:
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged)
{
CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:@"transform.scale"] floatValue];
if(self.isFlipped) // (inverting)
{
currentScale *= -1;
}
CGFloat newScale = 1 - (self.lastScale - [gestureRecognizer scale]);
newScale = MIN(newScale, self.maximumScaleFactor / currentScale);
newScale = MAX(newScale, self.minimumScaleFactor / currentScale);
CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
gestureRecognizer.view.transform = transform;
self.lastScale = [gestureRecognizer scale]; // Store the previous scale factor for the next pinch gesture call
回答by Fu Jiantao
Method 1
方法一
gestureRecognizer.scale
start with 1.0 at the beginning of pinch (gestureRecognizer.state == .began), and gestureRecognizer.scale
in later state (.changed or .end) is always based on that, for example, if the view size is view_size
at the beginning of pinch (might not be the same with the original size orig_view_size
), gestureRecognizer.scale
always starts with 1.0, and if it becomes 2.0 later, it's size will be 2 * view_size
, so the scale always based on that when the pinch starts.
gestureRecognizer.scale
从 1.0 开始捏 (gestureRecognizer.state == .began) 开始,并且gestureRecognizer.scale
在以后的状态 (.changed 或 .end) 始终基于此,例如,如果视图大小view_size
在捏的开头(可能与原来的大小不一样orig_view_size
),gestureRecognizer.scale
总是从1.0开始,如果以后变成2.0,它的大小就会是2 * view_size
,所以比例总是以捏开始时的大小为准。
And we can get the scale at the beginning of pinch (gestureRecognizer.state == .began)lastScale = self.imageView.frame.width/self.imageView.bounds.size.width
, so the scale of the original image now should be lastScale * gestureRecognizer.scale
并且我们可以得到pinch开始时的比例(gestureRecognizer.state == .began)lastScale = self.imageView.frame.width/self.imageView.bounds.size.width
,所以现在原图的比例应该是lastScale * gestureRecognizer.scale
lastScale
: The scale of last round of Pinch, a round of Pinch is from state.start to state.end, and the scale is based on the original view size.gestureRecognizer.scale
: current scale, based on the view size after last round of Pinch.currentScale
: current scale, based on the orignial view size.newScale
: new scale, based on the orignial view size.newScale = lastScale * gestureRecognizer.scale
, and you can limit the scale of the view by comparing the limitation withnewScale
.
lastScale
:上一轮Pinch的比例,一轮Pinch是从state.start到state.end,比例以原视图大小为准。gestureRecognizer.scale
:当前比例,基于上一轮捏合后的视图大小。currentScale
:当前比例,基于原始视图大小。newScale
:基于原始视图大小的新比例。newScale = lastScale * gestureRecognizer.scale
,您可以通过将限制与 进行比较来限制视图的比例newScale
。
```
``
var lastScale:CGFloat = 1.0
@objc func handlePinch(_ gestureRecognizer: UIPinchGestureRecognizer) {
var newScale = gestureRecognizer.scale
if gestureRecognizer.state == .began {
lastScale = self.imageView.frame.width/self.imageView.bounds.size.width
}
newScale = newScale * lastScale
if newScale < minScale {
newScale = minScale
} else if newScale > maxScale {
newScale = maxScale
}
let currentScale = self.imageView.frame.width/self.imageView.bounds.size.width
self.imageView.transform = CGAffineTransform(scaleX: newScale, y: newScale)
print("last Scale: \(lastScale), current scale: \(currentScale), new scale: \(newScale), gestureRecognizer.scale: \(gestureRecognizer.scale)")
}
```
``
Method 2
方法二
gestureRecognizer.scale
start with 1.0 on each Pinch notification, this require you reset gestureRecognizer.scale = 1
in the code in the end of each notification handler, so now gestureRecognizer.scale
is based on the view size of last Pinch notification, NOT based on the view size at the beginning of pinch. This is the most important difference with method 1. And since we don't rely on the scale of last round, we don't need lastScale
anymore.
gestureRecognizer.scale
每个 Pinch 通知从 1.0 开始,这需要您gestureRecognizer.scale = 1
在每个通知处理程序末尾的代码中重置,所以现在gestureRecognizer.scale
是基于最后一个 Pinch 通知的视图大小,而不是基于 pinch 开头的视图大小。这是与方法1最重要的区别。而且由于我们不依赖上一轮的规模,所以我们不再需要lastScale
了。
currentScale
: current scale, based on the orignial view size.gestureRecognizer.scale
: new scale, based on the view size of last Pinch (not the last round), the scale value based on the orignial view size will becurrentScale * gestureRecognizer.scale
currentScale
:当前比例,基于原始视图大小。gestureRecognizer.scale
: 新比例,基于上次捏合(不是最后一轮)的视图大小,基于原始视图大小的比例值将是currentScale * gestureRecognizer.scale
And we use transform.scaledBy
now, which use the scale based on view size of last Pinch (not the last round).
我们transform.scaledBy
现在使用,它使用基于最后一个捏(不是最后一轮)的视图大小的比例。
```
``
@objc func handlePinch(_ gestureRecognizer: UIPinchGestureRecognizer) {
let currentScale = self.imageView.frame.width/self.imageView.bounds.size.width
var newScale = gestureRecognizer.scale
if currentScale * gestureRecognizer.scale < minScale {
newScale = minScale / currentScale
} else if currentScale * gestureRecognizer.scale > maxScale {
newScale = maxScale / currentScale
}
self.imageView.transform = self.imageView.transform.scaledBy(x: newScale, y: newScale)
print("current scale: \(currentScale), new scale: \(newScale)")
gestureRecognizer.scale = 1
}
```
``
回答by Kevin_TA
Other approaches mentioned here did not work for me, but taking a couple things from previous answers and (in my opinion) simplifying things, I've got this to work for me. effectiveScale
is an ivar set to 1.0 in viewDidLoad
.
这里提到的其他方法对我不起作用,但是从以前的答案中提取一些东西并且(在我看来)简化了事情,我已经得到了这个对我有用。effectiveScale
是一个实例变量设置为在1.0 viewDidLoad
。
-(void)zoomScale:(UIPinchGestureRecognizer *)recognizer
{
if([recognizer state] == UIGestureRecognizerStateEnded) {
// Reset last scale
lastScale = 1.0;
return;
}
if ([recognizer state] == UIGestureRecognizerStateBegan ||
[recognizer state] == UIGestureRecognizerStateChanged) {
CGFloat pinchscale = [recognizer scale];
CGFloat scaleDiff = pinchscale - lastScale;
if (scaleDiff < 0)
scaleDiff *= 2; // speed up zoom-out
else
scaleDiff *= 0.7; // slow down zoom-in
effectiveScale += scaleDiff;
// Limit scale between 1 and 2
effectiveScale = effectiveScale < 1 ? 1 : effectiveScale;
effectiveScale = effectiveScale > 2 ? 2 : effectiveScale;
// Handle transform in separate method using new effectiveScale
[self makeAndApplyAffineTransform];
lastScale = pinchscale;
}
}
回答by Arvind Kumar
- (void)handlePinch:(UIPinchGestureRecognizer *)recognizer{
//recognizer.scale=1;
CGFloat pinchScale = recognizer.scale;
pinchScale = round(pinchScale * 1000) / 1000.0;
NSLog(@"%lf",pinchScale);
if (pinchScale < 1)
{
currentLabel.font = [UIFont fontWithName:currentLabel.font.fontName size:
(currentLabel.font.pointSize - pinchScale)];
recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
[currentLabel sizeToFit];
recognizer.scale=1;
}
else
{
currentLabel.font = [UIFont fontWithName:currentLabel.font.fontName size:(currentLabel.font.pointSize + pinchScale)];
recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
[currentLabel sizeToFit];
recognizer.scale=1;
}
//currentLabel.adjustsFontSizeToFitWidth = YES;
// [currentLabel sizeToFit];
NSLog(@"Font :%@",label.font);
}
回答by Roman Solodyashkin
- (void)pinchToZoom:(UIPinchGestureRecognizer*)gesture
{
switch (gesture.state)
{
case UIGestureRecognizerStateBegan:
{
lastScale = gesture.scale;
}break;
case UIGestureRecognizerStateChanged:
{
const CGFloat zoomSensitivity = 5;
const CGFloat zoomMin = 1;
const CGFloat zoomMax = 16;
CGFloat objectScale = gesture.view.contentScaleFactor;
CGFloat zoomDiff = lastScale - gesture.scale;
CGFloat zoomDirty = objectScale - zoomDiff * zoomSensivity;
CGFloat zoomTo = fmaxf(zoomMin, fminf(zoomDirty, zoomMax));
// step round if needed (neutralize elusive changes)
zoomTo = (NSInteger)(zoomTo * 10) * 0.1;
if ( objectScale != zoomTo )
gesture.view.contentScaleFactor = zoomTo;
lastScale = gesture.scale;
}break;
default:
break;
}
}
回答by micmcg
Can you use a scroll view instead? Then you could use scrollView.minimumZoomScale and scrollView.maximumZoomScale
你可以使用滚动视图吗?然后你可以使用 scrollView.minimumZoomScale 和 scrollView.maximumZoomScale