如何在iPhone WWDC 2010 - 104 PhotoScroller中双击放大/缩小照片

Rog*_*one 40 iphone uiscrollview uitouch wwdc touchesbegan

我将浏览iPhone WWDC 2010 - 104 PhotoScroller App的示例代码.它与我的项目相关图像(PDF页面图像)工作得很好

但我正在努力检测PhotoScroller应用程序中的触摸.使用多次触摸的缩放由ScrollVoiew处理.现在我想要双击放大/缩小照片.在TilingView类中调用Touchesbegan方法.然后我使用[super touchesbegan:withevent:],现在触摸在ImageScrollView类中.

如何在PhotoViewController中获取这些触摸事件.如何实现放大和缩小触摸?

任何人都可以帮助这个Regard?

gee*_*nit 71

我研究了几个不同的网站,我想出了以下内容......

将此代码放入viewDidLoad或viewWillAppear方法:

//////////////////////////////
// Listen for Double Tap Zoom

UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];

[doubleTap setNumberOfTapsRequired:2];

[self.scrollView addGestureRecognizer:doubleTap];

[doubleTap release];
Run Code Online (Sandbox Code Playgroud)

将其添加到头文件中:

- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer;
Run Code Online (Sandbox Code Playgroud)

将其添加到您的实现中:

- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer {  

    if(self.scrollView.zoomScale > self.scrollView.minimumZoomScale)
        [self.scrollView setZoomScale:self.scrollView.minimumZoomScale animated:YES]; 
    else 
        [self.scrollView setZoomScale:self.scrollView.maximumZoomScale animated:YES]; 

  }  
Run Code Online (Sandbox Code Playgroud)

目前,这并不以用户双击的区域为中心.


pos*_*sen 65

我的代码,基于链接" UIImageView无法缩放 "中的一些代码.此代码处理放大和缩小之间的切换,并允许检测单击和双击.它还可以通过在嵌入图像上应用视图变换来适当地将缩放对中.此代码将从示例代码进入ImageScrollView类.

- (void)setupGestureRecognisers:(UIView *)viewToAttach {

    UITapGestureRecognizer *dblRecognizer;
    dblRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                        action:@selector(handleDoubleTapFrom:)];
    [dblRecognizer setNumberOfTapsRequired:2];

    [viewToAttach addGestureRecognizer:dblRecognizer];
    self.doubleTapRecognizer = dblRecognizer;

    UITapGestureRecognizer *recognizer;
    recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                     action:@selector(handleTapFrom:)];
    [recognizer requireGestureRecognizerToFail:dblRecognizer];

    [viewToAttach addGestureRecognizer:recognizer];
    self.tapRecognizer = recognizer;
}

- (void)handleTapFrom:(UITapGestureRecognizer *)recognizer {

   // do your single tap
}


- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center {

    CGRect zoomRect;

    zoomRect.size.height = [_imageView frame].size.height / scale;
    zoomRect.size.width  = [_imageView frame].size.width  / scale;

    center = [_imageView convertPoint:center fromView:self];

    zoomRect.origin.x    = center.x - ((zoomRect.size.width / 2.0));
    zoomRect.origin.y    = center.y - ((zoomRect.size.height / 2.0));

    return zoomRect;
}

- (void)handleDoubleTapFrom:(UITapGestureRecognizer *)recognizer {

    float newScale = [self zoomScale] * 4.0;

    if (self.zoomScale > self.minimumZoomScale)
    {
        [self setZoomScale:self.minimumZoomScale animated:YES]; 
    }
    else 
    {
        CGRect zoomRect = [self zoomRectForScale:newScale 
                                   withCenter:[recognizer locationInView:recognizer.view]];
        [self zoomToRect:zoomRect animated:YES];
    }
}
Run Code Online (Sandbox Code Playgroud)


n8t*_*8tr 39

这是基于@possen的优秀答案的Swift解决方案. - 将它放在包含scrollview的视图控制器中,并且是scrollview委托. - 这个解决方案很棒,因为它实际上缩放到了点击位置:

@IBAction func handleDoubleTapScrollView(recognizer: UITapGestureRecognizer) {
    if scrollView.zoomScale == 1 {
        scrollView.zoom(to: zoomRectForScale(scale: scrollView.maximumZoomScale, center: recognizer.location(in: recognizer.view)), animated: true)
    } else {
        scrollView.setZoomScale(1, animated: true)
    }
}

func zoomRectForScale(scale: CGFloat, center: CGPoint) -> CGRect {
    var zoomRect = CGRect.zero
    zoomRect.size.height = imageView.frame.size.height / scale
    zoomRect.size.width  = imageView.frame.size.width  / scale
    let newCenter = scrollView.convert(center, from: imageView)
    zoomRect.origin.x = newCenter.x - (zoomRect.size.width / 2.0)
    zoomRect.origin.y = newCenter.y - (zoomRect.size.height / 2.0)
    return zoomRect
}
Run Code Online (Sandbox Code Playgroud)

  • 就这样,这是行不通的。应该将convert(_:from :)调用更改为convert(_:to :),或者应该交换该行上的scrollView和imageView。根据文档,“矩形应位于viewForZooming(in :)返回的视图的坐标空间中”,在本例中为imageView。在Pavel Vavilov进行编辑之前是正确的。我已经提交了修改以更正此问题。 (4认同)

Ric*_*eda 14

我将@jayesh kavathiya和@possen的答案合并到一个单独的实现中,只要你为self.minimumZoomScale和设置了适当的值,它就能很好地工作self.maximumZoomScale.

- (void)doubleTap:(UITapGestureRecognizer*)recognizer
{
    if (self.zoomScale > self.minimumZoomScale)
    {
        [self setZoomScale:self.minimumZoomScale animated:YES];
    }
    else
    {
        CGPoint touch = [recognizer locationInView:recognizer.view];

        CGSize scrollViewSize = self.bounds.size;

        CGFloat w = scrollViewSize.width / self.maximumZoomScale;
        CGFloat h = scrollViewSize.height / self.maximumZoomScale;
        CGFloat x = touch.x-(w/2.0);
        CGFloat y = touch.y-(h/2.0);

        CGRect rectTozoom=CGRectMake(x, y, w, h);
        [self zoomToRect:rectTozoom animated:YES];
    }
}
Run Code Online (Sandbox Code Playgroud)


Akh*_*ngh 12

斯威夫特3

通常,双击和捏合手势都需要图像缩放功能,因此我提供了完整的解决方案来实现相同的功能.双击缩放的灵感来自上面的答案,并从这里获取捏缩放.

import UIKit

class ViewController: UIViewController, UIScrollViewDelegate {

    var imageView: UIImageView!
    var scrollImg: UIScrollView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let vWidth = self.view.frame.width
        let vHeight = self.view.frame.height

        scrollImg = UIScrollView()
        scrollImg.delegate = self
        scrollImg.frame = CGRect(x: 0, y: 0, width: vWidth, height: vHeight)
        scrollImg.backgroundColor = UIColor(red: 90, green: 90, blue: 90, alpha: 0.90)
        scrollImg.alwaysBounceVertical = false
        scrollImg.alwaysBounceHorizontal = false
        scrollImg.showsVerticalScrollIndicator = true
        scrollImg.flashScrollIndicators()

        scrollImg.minimumZoomScale = 1.0
        scrollImg.maximumZoomScale = 10.0

        let doubleTapGest = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTapScrollView(recognizer:)))
        doubleTapGest.numberOfTapsRequired = 2
        scrollImg.addGestureRecognizer(doubleTapGest)

        self.view.addSubview(scrollImg)

        imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: vWidth, height: vHeight))
        imageView.image = UIImage(named: "cat")
        imageView!.layer.cornerRadius = 11.0
        imageView!.clipsToBounds = false
        scrollImg.addSubview(imageView!)
    }

    func handleDoubleTapScrollView(recognizer: UITapGestureRecognizer) {
        if scrollImg.zoomScale == 1 {
            scrollImg.zoom(to: zoomRectForScale(scale: scrollImg.maximumZoomScale, center: recognizer.location(in: recognizer.view)), animated: true)
        } else {
            scrollImg.setZoomScale(1, animated: true)
        }
    }

    func zoomRectForScale(scale: CGFloat, center: CGPoint) -> CGRect {
        var zoomRect = CGRect.zero
        zoomRect.size.height = imageView.frame.size.height / scale
        zoomRect.size.width  = imageView.frame.size.width  / scale
        let newCenter = imageView.convert(center, from: scrollImg)
        zoomRect.origin.x = newCenter.x - (zoomRect.size.width / 2.0)
        zoomRect.origin.y = newCenter.y - (zoomRect.size.height / 2.0)
        return zoomRect
    }

    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        return self.imageView
    }

}
Run Code Online (Sandbox Code Playgroud)


小智 1

将 UITapGestureRecognizer 添加到 ImageScrollView 怎么样?

只要你看示例代码,就可以看看ScrollViewSuite示例代码中UIGestureRecognizers是如何使用的。