

ダブルタップでタップした箇所をズームする機能を実装したいのですが、scrollViewに乗せたUIImageViewをズームできません。  
(参考サイトはこちらです。)  
<http://cocoadays.blogspot.jp/2010/09/3.html>

imageViewをズームさせるにはどのようにすれば良いでしょうか？

[code]

    - (void)viewDidLoad {
        scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
        scrollView.frame = self.view.bounds;
        scrollView.backgroundColor = [UIColor blueColor];
        scrollView.conteimgViewntSize = CGSizeMake(imgView.bounds.size.width+100, imgView.bounds.size.height);
        scrollView.frame = CGRectMake(0,50,320,500);
        scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        scrollView.pagingEnabled = YES;
        scrollView.bouncesZoom = YES;
        scrollView.minimumZoomScale = 1.0;
        scrollView.maximumZoomScale = 2.0;
        scrollView.showsHorizontalScrollIndicator = NO;
        scrollView.showsVerticalScrollIndicator = NO;
        [self.view addSubview:scrollView];
    
        img =[UIImage imageNamed:[NSString stringWithFormat:@"a.jpg"]];
        imgView = [[UIImageView alloc]initWithImage:img];
        imgView.frame = CGRectMake(0, 0, self.view.frame.size.width, 448);
        imgView.userInteractionEnabled = YES;
        [scrollView addSubview:imgView];
    }
    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        UITouch* touch = [touches anyObject];
        if ([touch tapCount] == 2) {
            scrollView = (UIScrollView*)self.view;
    
            CGRect zoomRect;
            if (scrollView.zoomScale > 1.0) {
                zoomRect = scrollView.bounds;
            } else {
                zoomRect = [self zoomRectForScrollView:scrollView
                                                 withScale:2.0
                                                withCenter:[touch locationInView:nil]];
            }
            [scrollView zoomToRect:zoomRect animated:YES];
        }        
    }
    
[/code]


CC BY-SA 3.0
2015-09-07T08:41:52.843
16344
2015-09-09T07:22:52.157
2015-09-07T09:55:57.883
7362
11010
question
ios objective-c xcode c iphone
「ダブルタップでUIImageViewをズーム」ができません


ビューコントローラでUIScrollViewDelegateを継承してスクロールビューのdelegateと接続し、viewForZoomingInScrollView:メソッドでスクロールビューのコンテンツとなるUIImageViewを返す必要があると思います。

また、ダブルタップでズームインアウトするのはタッチイベントで書くよりもUITapGestureRecognizerを使って書いた方が、ほかのジェスチャにも対応したくなったときに楽できるんではないかと思います。


CC BY-SA 3.0
2015-09-07T09:59:05.043
16345
2015-09-07T09:59:05.043
7283
16344
answer

[code]

    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        UITouch* touch = [touches anyObject];
        if ([touch tapCount] == 2) {
            // scrollView = (UIScrollView*)self.view;
            // この行が間違い。
            UIScrollView *scrollView = self.scrollView; // こう修正。
            CGRect zoomRect;
            if (scrollView.zoomScale > 1.0) {
                zoomRect = scrollView.bounds;
            } else {
                zoomRect = [self zoomRectForScrollView:scrollView
                                                 withScale:2.0
                                                withCenter:[touch locationInView:nil]];
            }
            [scrollView zoomToRect:zoomRect animated:YES];
        }        
    }
    
[/code]

ほかにも間違いがあるかもしれませんが、とりあえず上記の修正をしないと、話が始まりません。

* * *

そもそも参考になさったリンク先の情報は、2010年のもの。約5年前では古いといわざるをえません。  
最大の問題は、タップイベントの取得に`touchesEnded`メソッドを使っている点です。`UIScrollView`は、画面のフリックやパンに応じてスクロールするため、タッチイベントの処理が実装済みなので、Responder
Chainを伝って、タッチイベントが`UIScrollView`から`UIViewController`に伝播してきません。  
現時点で主流と考えられる方法は、`UITapGestureRecognizer`クラスを使って、ダブルタップイベントを取得する方法です。  
以下サンプルコードです。320×320の`Scroll Viewに、おなじく320×320の`Image
View`を乗せ、ダブルタップで、2倍に拡大と、等倍に戻るを繰り返します。

_ViewController.h_

[code]

    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController <UIScrollViewDelegate>
    // UIScrollViewDelegateプロトコルを実装　注1
    
    @end
    
[/code]

_ViewController.m_

[code]

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @property (nonatomic) UIScrollView *scrollView; // Scroll View
    @property (nonatomic) UIImageView *imageView; // Image View
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.scrollView = [[UIScrollView alloc] initWithFrame: CGRectMake(0.0, 40.0, 320.0, 320.0)];
        // Tap Gesture Recognizerインスタンスを生成。
        UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(doubleTap:)];
        tapGestureRecognizer.numberOfTapsRequired = 2;
        // ダブルタップだけに反応する。（4連続タップしたら、2回反応しますけど）
        [self.scrollView addGestureRecognizer: tapGestureRecognizer];
        // Tap Gesture RecognizerをScroll Viewに組み込む。
        self.scrollView.delegate = self; // 注1
        self.scrollView.maximumZoomScale = 2.0;
        self.scrollView.minimumZoomScale = 0.5;
        // 拡大・縮小の限界値を設定
        [self.view addSubview: self.scrollView];
    
        self.imageView = [[UIImageView alloc] initWithImage: [UIImage imageNamed: @"image.png"]];
        // Image Viewを生成
        [self.scrollView addSubview: self.imageView];
    }
    
    // ダブルタップで呼ばれるアクションメソッド
    - (void)doubleTap: (UITapGestureRecognizer *)recognizer {
        // ダブルタップが終わったら
        if (recognizer.state == UIGestureRecognizerStateEnded) {
            // Scroll Viewの拡大率が等倍なら
            if (self.scrollView.zoomScale < 1.5) {
                CGPoint tappedPoint = [recognizer locationInView: self.imageView];
                // タップ位置を中心にして拡大するよう、タップ位置を取得
                [self.scrollView zoomToRect: CGRectMake(tappedPoint.x / 2.0, tappedPoint.y / 2.0, 160.0, 160.0) animated: YES];
                // 拡大
            } else { // 倍だったら
                [self.scrollView zoomToRect: CGRectMake(0.0, 0.0, 320.0, 320.0) animated: YES];
                // 等倍に戻る
            }
        }
    }
    
    // Scroll View Delegate 注1
    - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
        return self.imageView;
    }
    
    @end
    
[/code]

**注1：**  
`UIScrollView`で、ズームを有効にするには、ズームの対象の`UIView`（のサブクラス）を指定しなければいけません。指定の仕方は、Delegateメソッド`viewForZoomingInScrollView:`を使います。なので、`Scroll
View`のDelegate先を設定する必要があります。


CC BY-SA 3.0
2015-09-07T10:06:42.400
16346
2015-09-09T07:22:52.157
2015-09-09T07:22:52.157
7362
7362
16344
answer