【问题标题】:how to make an ImageView zoomable with or without ScrollView.?如何使用或不使用 ScrollView 使 ImageView 可缩放?
【发布时间】:2013-05-15 23:21:30
【问题描述】:

我的IB 中有一个UImageView,并在UImageView 上添加了一张地图图像。我想让该图像可以缩放。

这是我的代码:

- (void)viewDidLoad
{
   [super viewDidLoad];
    self.title = @"Map";

   self.mapImageView.contentMode = UIViewContentModeScaleAspectFit;
   [self.mapScrollView addSubview:self.mapImageView];
   [self.mapScrollView setContentSize:CGSizeMake(self.mapImageView.frame.size.width, self.mapImageView.frame.size.height)];
   [self.mapScrollView setMinimumZoomScale:1.0];
   [self.mapScrollView setMaximumZoomScale:4.0];
}

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
   return self.mapImageView;
}

但这无济于事,我可以看到 UIScrollView 来了,但我的图像没有任何反应。
提前致谢。

【问题讨论】:

  • 你设置了滚动视图的代理吗?
  • 我刚刚设置了委托。现在它正在缩放,但同时又回到了以前的状态,这并不能解决缩放的目的。
  • “回到以前的状态”是什么意思?
  • 当您将一个视图控制器推送到另一个视图控制器时,ViewDidLoad 调用了第二个视图控制器,但是将 secod 弹出到第一个视图然后 ViewDidLoad 没有被调用 fistView 它的 ViewwillAppear 调用所以将您的代码放入 ViewWillAppear
  • 当我捏住屏幕并将手指从屏幕上移开时,它只会同时放大和缩小。

标签: iphone ios objective-c uiscrollview uiimageview


【解决方案1】:

在您的ViewController.h 文件中添加UIScrollViewDelegate

然后将以下代码添加到您的 ViewController.m 文件中

如果您使用此代码,则无需添加UIPinchGestureRecognizer

    - (void)scrollViewDidZoom:(UIScrollView *)scrollView
    {

    UIView* zoomView = [scrollView.delegate viewForZoomingInScrollView:scrollView];

    CGRect zoomViewFrame = zoomView.frame;

    if(zoomViewFrame.size.width < scrollView.bounds.size.width)

    {

    zoomViewFrame.origin.x = (scrollView.bounds.size.width - zoomViewFrame.size.width) / 2.0;

    }

    else

    {
    zoomViewFrame.origin.x = 0.0;
    }

    if(zoomViewFrame.size.height < scrollView.bounds.size.height)

     {      zoomViewFrame.origin.y = (scrollView.bounds.size.height - zoomViewFrame.size.height) / 2.0;

    }
    else

    {
    zoomViewFrame.origin.y = 0.0;
    }
    zoomView.frame = zoomViewFrame;
    }

如下更改viewDidLoad

- (void)viewDidLoad
 {
     [super viewDidLoad];
    self.mapScrollView.delegate = self;
    self.mapScrollView.minimumZoomScale = 1.0;
    self.mapScrollView.maximumZoomScale = 4.0;
    UIImage * myImage= [UIImage imageNamed:@"Background.png"]; //add your image here
    [self.mapImageView setImage:myImage];
    [self.mapImageView sizeToFit];
    self.mapScrollView.contentSize = myImage.size;

}

在此处指定要放大的imageView

- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return self.mapImageView;
}

要避免 UIScrollView 在 zoomimg 上的奇怪行为,请使用此方法

- (void)view:(UIView*)view setCenter:(CGPoint)centerPoint
{
    CGRect viewFrame = view.frame;
        CGPoint contentOffset = self.mapScrollView.contentOffset;

        CGFloat x = centerPoint.x - viewFrame .size.width / 2.0;
        CGFloat y = centerPoint.y - viewFrame .size.height / 2.0;

    if(x < 0)
    {
        contentOffset.x = -x;
        viewFrame .origin.x = 0.0;
    }
    else
    {
        viewFrame .origin.x = x;
    }
    if(y < 0)
    {
        contentOffset.y = -y;
        viewFrame .origin.y = 0.0;
    }
    else
    {
        viewFrame .origin.y = y;
    }

    view.frame = viewFrame ;
    self.mapScrollView.contentOffset = contentOffset;
}

然后在viewDidAppear上调用上面的方法

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    CGPoint centerPoint = CGPointMake(CGRectGetMidX(self.mapScrollView.bounds),
                                  CGRectGetMidY(self.mapScrollView.bounds));
    [self view:self.mapImageView setCenter:centerPoint];
}

如果您需要更多说明,请查看link。我从那个链接学到了这项技术。

【讨论】:

  • 我现在正在使用您的代码,但没有任何反应。我如何逐步使用您的代码,让我知道我是否犯了任何错误。 1)在 IB 中添加了一个 scrollView 并将其发送回,将委托设置为文件的所有者 2)删除我上面给定的所有代码。 3) 在 vi​​ewDidLoad 之后粘贴您的代码。 4)运行代码,没有任何反应。
  • 1.打开 .xib 并添加 UIScrollview 2.将 UIImageView 添加到该 UIScrollview 3.为 UIScrollview 和 UIImageView 创建 IBOutlet 并将其连接到 .xib。 4. 在 vi​​ewController.h 中添加 UIScrollViewDelegate 如下 @interface ScrollxViewController : UIViewController 5. 在 vi​​ewController.h 中创建属性并在 viewController.m 中合成属性 6. 像上面一样更改 viewDidLoad 、 scrollViewDidZoom 和 viewForZoomingInScrollView 。 7.构建和运行图像将缩放。如果您需要完整的代码,请告诉我我会上传它
  • 抱歉回复太晚了,我真的很感谢你,但还是有一些问题。机智使用您的代码,它正在缩放但不正确,它正在水平缩放并垂直压缩,因此该图像中没有正确的东西。希望你能理解这里的问题。
  • 您可以参考此链接以获得进一步的说明。他们指定了如何将 contentview 居中 (iosdeveloperzone.com/2012/07/07/…)
  • @Zac24 你解决了这个问题吗?如果是这样,请发布解决方案。我遇到了类似的问题,尽管尝试了不同的解决方案,但它仍然存在。
【解决方案2】:

试试这个

    //At ViewDidLoad (OR whare you create your mapImageView)
   UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scale:)];
   [pinchRecognizer setDelegate:self];
   [mapImageView addGestureRecognizer:pinchRecognizer];

   mapImageView.userInteractionEnabled=YES;




   -(void)scale:(id)sender {
       [YourView bringSubviewToFront:[(UIPinchGestureRecognizer*)sender view]];

       if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
           lastScale = 1.0;  //global float variable.
           return;
       }

       CGFloat scale = 1.0 - (lastScale - [(UIPinchGestureRecognizer*)sender scale]);

       CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)sender view].transform;
       CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);

       [[(UIPinchGestureRecognizer*)sender view] setTransform:newTransform];
   }

【讨论】:

  • 应用程序崩溃。由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“ + *0x1f5b0560.marker + *0x1f5b5e70.marker + *0x1f5b5f50.marker + *0x1f5bbc40.marker + *0x1f5c1760.marker + *0x1f5c2a00.marker + *0x1f5c4150.marker:内部错误。为变量 tempToBeOptimizedToZero 设置空向量。'
  • 等等。我会调试并在这里发布。
【解决方案3】:

要在没有scrollView 的情况下执行此操作,请将此代码段添加到您的班级:

-(void) addGesturesTo : (UIImageView *) imageView{
    // Register for double-finger dragging to pan the camera.
    UIPinchGestureRecognizer* pinchGestureReconizer = [[UIPinchGestureRecognizer alloc] initWithTarget: self                                                                                                    action: @selector(handlePich:)];
    [imageView addGestureRecognizer:pinchGestureReconizer];
}
- (void) handlePich: (UIPinchGestureRecognizer *) pinchGestureRecognizer{
    CGFloat scale = pinchGestureRecognizer.scale;
    [[pinchGestureRecognizer view]  setTransform:CGAffineTransformScale([pinchGestureRecognizer view].transform, scale, scale)];
    pinchGestureRecognizer.scale = 1.0;
}

现在用imageView 致电addGesturesTo。如:

[self addGesturesTo:imageView];

使用 ScrollView 执行此操作:按照以下步骤操作:

  • 添加scrollView设置委托给自己
  • scrolView 内添加imageView
  • 在你的类中实现- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;并返回imageView

【讨论】:

  • 没有scrollView。我将从我的 viewController 中删除 scrollView 并将此代码 sn-p 添加到我的课程中,然后在哪里调用此 [self addGesturesTo:imageView];
  • 随心所欲。在viewDidLoad 可能是。
  • 在控制台中得到了类似的东西。无法同时满足约束。可能以下列表中的至少一个约束是您不想要的。试试这个:(1)查看每个约束并尝试找出您不期望的; (2) 找到添加了一个或多个不需要的约束的代码并修复它。 (注意:如果您看到不理解的 NSAutoresizingMaskLayoutConstraints,请参阅 UIView 属性 translatesAutoresizingMaskIntoConstraints 的文档)
  • ("&lt;NSAutoresizingMaskLayoutConstraint:0x1f5f5d50 h=--- v=--- H:[UIWindow:0x1f5d43b0(320)]&gt;", "&lt;NSAutoresizingMaskLayoutConstraint:0x1f5f48d0 h=-&amp;- v=-&amp;- UILayoutContainerView:0x1f5d5620.width == UIWindow:0x1f5d43b0.width&gt;", "&lt;NSAutoresizingMaskLayoutConstraint:0x1f5f34e0 h=-&amp;- v=-&amp;- UINavigationTransitionView:0x1f5d89b0.width == UILayoutContainerView:0x1f5d5620.width&gt;") Will attempt to recover by breaking constraint &lt;NSAutoresizingMaskLayoutConstraint:0x1f5f34e0 h=-&amp;- v=-&amp;- UINavigationTransitionView:0x1f5d89b0.width == UILayoutContainerView:0x1f5d5620.width&gt;
  • 中断 objc_exception_throw 以在调试器中捕获它。 中列出的 UIView 上的 UIConstraintBasedLayoutDebugging 类别中的方法也可能会有所帮助。这就是我在控制台中得到的。
猜你喜欢
  • 2011-11-12
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 2021-01-09
  • 1970-01-01
  • 2012-12-19
  • 1970-01-01
  • 2011-08-12
相关资源
最近更新 更多