图像未放大时如何停止移动图像?
Posted
技术标签:
【中文标题】图像未放大时如何停止移动图像?【英文标题】:how to stop moving image when image is not zoomed in? 【发布时间】:2015-11-02 11:14:36 【问题描述】:我有一个UIImageView
我正在执行缩放缩放和全缩放移动图像。我可以移动图像但问题是即使图像没有放大它仍然会在屏幕上移动。请告诉我如何预防?
这是代码
#define MINIMUM_SCALE 0.5
#define MAXIMUM_SCALE 6.0
@property CGPoint translation;
- (void)pan:(UIPanGestureRecognizer *)gesture
static CGPoint currentTranslation;
static CGFloat currentScale = 0;
if (gesture.state == UIGestureRecognizerStateBegan)
currentTranslation = _translation;
currentScale = self.view.frame.size.width / self.view.bounds.size.width;
if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged)
CGPoint translation = [gesture translationInView:self.view];
_translation.x = translation.x + currentTranslation.x;
_translation.y = translation.y + currentTranslation.y;
CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x , _translation.y);
CGAffineTransform transform2 = CGAffineTransformMakeScale(currentScale, currentScale);
CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);
self.view.transform = transform;
- (void)pinch:(UIPinchGestureRecognizer *)gesture
if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged)
// NSLog(@"gesture.scale = %f", gesture.scale);
CGFloat currentScale = self.view.frame.size.width / self.view.bounds.size.width;
CGFloat newScale = currentScale * gesture.scale;
if (newScale < MINIMUM_SCALE)
newScale = MINIMUM_SCALE;
if (newScale > MAXIMUM_SCALE)
newScale = MAXIMUM_SCALE;
CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x, _translation.y);
CGAffineTransform transform2 = CGAffineTransformMakeScale(newScale, newScale);
CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);
self.view.transform = transform;
gesture.scale = 1;
**PS:**ImageView 应该只在图像缩放时移动,否则它不应该是可移动的。
【问题讨论】:
完成 - 我猜你欠我两个赏金好友;) 【参考方案1】:我建议一种不同的方法:
创建一个UIScrollView
将UIImageView
添加到scrollView 的contentView
并允许在scrollView 上滚动和缩放。
为防止在未缩放时滚动,请将setScrollEnabled
设置为NO
并在zoomLevel 达到自定义阈值时在scrollViewDidZoom
中启用它。
等等。像这样应该可以使您尝试用更少的代码完成的工作变得更加容易。
- (void)viewDidLoad:(BOOL)animated
[super viewDidLoad:animated];
self.scrollView.scrollEnabled = NO;
self.scrollView.minimumZoomScale = 1;
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
if (scrollView.zoomLevel > 1)
scrollView.scrollEnabled = YES;
else
scrollView.scrollEnabled = NO;
【讨论】:
如果它解决了你的问题,你能把它标记为正确答案吗?【参考方案2】:我重新发布了我在您关于该主题的第一个问题 (Pinch zoom shifting image to most left corner on iPad in ios?) 中给您的代码,因为我认为您执行此操作的方式无法按预期工作(据我测试)。
捏缩放应该在手指中间缩放,而不是在图像中间。如果你真的想在中心应用缩放,我添加了一个布尔属性 zoomOnCenter。
边界检查在 translateBy 方法中完成。
这里是 xCode 测试项目的链接:https://drive.google.com/file/d/0B88aMtNA0z2aWVBIbGZGdVhpdWM/view?usp=sharing
界面
@interface PinchViewController : UIViewController
@property(nonatomic,strong) IBOutlet UIView* contentView;
@property(nonatomic,assign) BOOL zoomOnCenter;
@end
实施
@implementation PinchViewController
CGPoint translation;
CGFloat scale;
CGAffineTransform scaleTransform;
CGAffineTransform translateTransform;
CGPoint previousTranslation;
CGFloat previousScale;
NSUInteger previousNumTouches;
-(void)viewDidLoad
scale = 1.0f;
scaleTransform = CGAffineTransformIdentity;
translateTransform = CGAffineTransformIdentity;
previousTranslation = CGPointZero;
previousNumTouches = 0;
UIPinchGestureRecognizer *pinch=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinch:)];
[self.view addGestureRecognizer:pinch];
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[panGesture setMinimumNumberOfTouches:1];
[panGesture setMaximumNumberOfTouches:1];
[self.view addGestureRecognizer:panGesture];
-(void)handlePinch:(UIPinchGestureRecognizer*)recognizer
// 1 - find pinch center
CGPoint mid = self.zoomOnCenter ? CGPointZero : [self computePinchCenter:recognizer];
mid.x-= recognizer.view.bounds.size.width / 2.0f;
mid.y-= recognizer.view.bounds.size.height / 2.0f;
// 2 - compute deltas
NSUInteger numTouches = recognizer.numberOfTouches;
if ( (recognizer.state==UIGestureRecognizerStateBegan) || ( previousNumTouches != numTouches ) )
previousScale = recognizer.scale;
previousTranslation = mid;
previousNumTouches = numTouches;
CGFloat deltaScale = ( recognizer.scale - previousScale ) * scale;
previousScale = recognizer.scale;
CGPoint deltaTranslation = CGPointMake(mid.x-previousTranslation.x, mid.y-previousTranslation.y);
previousTranslation = mid;
deltaTranslation.x/=scale;
deltaTranslation.y/=scale;
// 3 - apply
scale+=deltaScale;
if (scale<0.01) scale = 0.01; else if (scale>10) scale = 10;
scaleTransform = CGAffineTransformMakeScale(scale, scale);
[self translateBy:deltaTranslation];
- (void)handlePan:(UIPanGestureRecognizer *)recognizer
if (recognizer.state==UIGestureRecognizerStateBegan) previousTranslation = CGPointZero;
CGPoint recognizerTranslation = [recognizer translationInView:self.contentView];
CGPoint deltaTranslation = CGPointMake(recognizerTranslation.x - previousTranslation.x,recognizerTranslation.y - previousTranslation.y);
previousTranslation = recognizerTranslation;
[self translateBy:deltaTranslation];
-(void)translateBy:(CGPoint)delta
CGSize contentSize = self.contentView.bounds.size;
CGSize viewSize = self.view.bounds.size;
CGSize scaledViewSize = viewSize;
scaledViewSize.width/=scale;
scaledViewSize.height/=scale;
CGPoint maxTranslation = CGPointMake( (contentSize.width-scaledViewSize.width) / 2.0f , (contentSize.height-scaledViewSize.height) / 2.0f );
if ( contentSize.width*scale < viewSize.width )
delta.x=0;
translation.x = 0;
else
translation.x+=delta.x;
if ( translation.x < - maxTranslation.x )
translation.x = - maxTranslation.x;
else if ( translation.x > maxTranslation.x )
translation.x = maxTranslation.x;
if ( contentSize.height*scale < viewSize.height )
delta.y=0; translation.y = 0;
else
translation.y+=delta.y;
if ( translation.y < - maxTranslation.y )
translation.y = - maxTranslation.y;
else if ( translation.y > maxTranslation.y )
translation.y = maxTranslation.y;
translateTransform = CGAffineTransformMakeTranslation(translation.x,translation.y);
self.contentView.transform = CGAffineTransformConcat(translateTransform,scaleTransform);
-(CGPoint)computePinchCenter:(UIPinchGestureRecognizer*)recognizer
// 1 - handle up to 3 touches
NSUInteger numTouches = recognizer.numberOfTouches;
if (numTouches>3) numTouches = 3;
// 2 - Find fingers middle point - with (0,0) being the center of the view
CGPoint pt1,pt2,pt3,mid;
switch (numTouches)
case 3:
pt3 = [recognizer locationOfTouch:2 inView:recognizer.view];
case 2:
pt2 = [recognizer locationOfTouch:1 inView:recognizer.view];
case 1:
pt1 = [recognizer locationOfTouch:0 inView:recognizer.view];
switch (numTouches)
case 3:
mid = CGPointMake( ( ( pt1.x + pt2.x ) / 2.0f + pt3.x ) / 2.0f, ( ( pt1.y + pt2.y ) / 2.0f + pt3.y ) / 2.0f );
break;
case 2:
mid = CGPointMake( ( pt1.x + pt2.x ) / 2.0f, ( pt1.y + pt2.y ) / 2.0f );
break;
case 1:
mid = CGPointMake( pt1.x, pt1.y);
break;
return mid;
@end
【讨论】:
【参考方案3】:您可以检查 imageView 的框架,如果相同,则表示 imageview 尚未缩放因此,如果 imageview 的框架相同,您可以禁用平移手势......如果框架已更改,那么您可以启用平移手势.....
【讨论】:
以上是关于图像未放大时如何停止移动图像?的主要内容,如果未能解决你的问题,请参考以下文章
不幸的是,当在android中通过横向模式捕获图像时,图像未旋转已停止?