↑クリックして拡大
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大

頭痛が減ったので共有です!

rebuild.fmを応援しています!

HOME > ScrollViewで2指でPinch Zoom

ScrollViewで横スクロールしつつ2指でPinch Zoom

前回のScrollView記事ではスワイプするサンプルを記載しましたが、今回は横スクロールしつつ各ページでは二つ指によるズームの方法を検証します。

サンプル画像


参考:画像をダブルタップとピンチイン・ピンチアウトで拡大・縮小する
参考:UIScrollViewのサブビューを拡大した後におかしくなる
参考:UIScrollView - 拡大縮小
参考:How To Use UIScrollView to Scroll and Zoom Content in Swift

やってみた

画像一枚だけでのピンチズームのサンプルは多かったのですが、マンガアプリの様に横スクロールしつつ拡大縮小も行うサンプルが少なかったです。Objective-Cでのサンプルが あったのでSwift用に微調整してみました。

サンプル画像サンプル画像


import UIKit

class ViewController: UIViewController , UIScrollViewDelegate{
    
    var mainScrollView: UIScrollView!
    var pageImagesArr = ["tutorial_page_1.png","tutorial_page_2.png","tutorial_page_3.png"];
    
    let C_IMAGEVIEW_TAG = 1000;
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        mainScrollView = UIScrollView(frame: self.view.bounds)
        mainScrollView.pagingEnabled = true;
        mainScrollView.showsHorizontalScrollIndicator = false;
        mainScrollView.showsVerticalScrollIndicator = false;
        
        var innerScrollFrame:CGRect = mainScrollView.bounds;
        
        var pageSize = self.pageImagesArr.count;
        for (var i = 0; i < pageSize; i++) {
            
            let img:UIImage = UIImage(named:self.pageImagesArr[i])!;
            let iv:UIImageView = UIImageView(image:img);
            iv.frame = mainScrollView.frame;
            iv.tag = i + C_IMAGEVIEW_TAG;
            
            var pageScrollView = UIScrollView(frame: innerScrollFrame)
            pageScrollView.minimumZoomScale = 1
            pageScrollView.maximumZoomScale = 2
            pageScrollView.zoomScale = 1;
            pageScrollView.contentSize = iv.bounds.size;
            pageScrollView.delegate = self
            pageScrollView.showsHorizontalScrollIndicator = false;
            pageScrollView.showsVerticalScrollIndicator = false;
            pageScrollView.addSubview(iv);
            
            mainScrollView.addSubview(pageScrollView);
            
            if (i < 2) {
                innerScrollFrame.origin.x = innerScrollFrame.origin.x + innerScrollFrame.size.width;
            }
        }
        
        mainScrollView.contentSize = CGSizeMake(innerScrollFrame.origin.x + innerScrollFrame.size.width, mainScrollView.bounds.size.height);
        self.view.addSubview(mainScrollView);
    }
    
    func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
        let pageNum = mainScrollView.bounds.origin.x / mainScrollView.frame.width;
        return self.view.viewWithTag(Int(pageNum)+C_IMAGEVIEW_TAG) as UIImageView;
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

ScrollViewの中にScrollViewを入れ子にして対応しています。私がハマってしまったのはviewForZoomingInScrollViewです。 この関数がScrollViewを拡大する際に「何を拡大するか」を判断する箇所ですので、ここの指定が間違っていると適切ではないViewを拡大して しまいます。上記はTagと現在のページ番号から適切な画像を計算して選んでいます。画像を適切なファイル名に切り替えてご利用ください。

カスタマイズ

画面下に現在何枚目からのPageControlを追加してみる

サンプル画像


import UIKit

class ViewController: UIViewController , UIScrollViewDelegate{
    
    var mainScrollView: UIScrollView!
    var pageControl: UIPageControl!
    var pageImagesArr = ["tutorial_page_1.png","tutorial_page_2.png","tutorial_page_3.png"];
    
    let C_IMAGEVIEW_TAG = 1000;
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        mainScrollView = UIScrollView(frame: self.view.bounds)
        mainScrollView.pagingEnabled = true;
        mainScrollView.delegate = self;
        mainScrollView.showsHorizontalScrollIndicator = false;
        mainScrollView.showsVerticalScrollIndicator = false;
        
        var innerScrollFrame:CGRect = mainScrollView.bounds;
        
        var pageSize = self.pageImagesArr.count;
        for (var i = 0; i < pageSize; i++) {
            
            let img:UIImage = UIImage(named:self.pageImagesArr[i])!;
            let iv:UIImageView = UIImageView(image:img);
            iv.frame = mainScrollView.frame;
            iv.tag = i + C_IMAGEVIEW_TAG;
            
            var pageScrollView = UIScrollView(frame: innerScrollFrame)
            pageScrollView.minimumZoomScale = 1
            pageScrollView.maximumZoomScale = 2
            pageScrollView.zoomScale = 1;
            pageScrollView.contentSize = iv.bounds.size;
            pageScrollView.delegate = self
            pageScrollView.showsHorizontalScrollIndicator = false;
            pageScrollView.showsVerticalScrollIndicator = false;
            pageScrollView.addSubview(iv);
            
            mainScrollView.addSubview(pageScrollView);
            
            if (i < 2) {
                innerScrollFrame.origin.x = innerScrollFrame.origin.x + innerScrollFrame.size.width;
            }
        }
        
        mainScrollView.contentSize = CGSizeMake(innerScrollFrame.origin.x + innerScrollFrame.size.width, mainScrollView.bounds.size.height);
        self.view.addSubview(mainScrollView);
        
        //UIPageControllの作成
        pageControl = UIPageControl(frame: CGRectMake(0, self.view.frame.maxY - 50, mainScrollView.frame.width, 50))
        pageControl.backgroundColor = UIColor.grayColor();
        pageControl.numberOfPages = pageSize
        pageControl.currentPage = 0
        pageControl.userInteractionEnabled = false
        self.view.addSubview(pageControl)
        
    }
    
    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
        let pageNum = mainScrollView.bounds.origin.x / mainScrollView.frame.width;
        pageControl.currentPage = Int(pageNum);
    }
    
    func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
        let pageNum = mainScrollView.bounds.origin.x / mainScrollView.frame.width;
        return self.view.viewWithTag(Int(pageNum)+C_IMAGEVIEW_TAG) as UIImageView;
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

まとめ

ScrollView+ピンチ拡大縮小に関しては簡単にできたのですが、ここに横スワイプが加わると手間がかかってしまいました。 このサンプルも何かのお役に立てれば嬉しいです。

↓こんな記事もありますよ!


2021-05-14 14:21:41

WatchOSのwatchconnectivityのFiletransferの落とし穴。と、避け方。

AppleWatch 実機だと成功するんだけど、シュミレーターだと失敗するという、、、 昔作成してた時は成功してたのになーと思って調べると、どうやら昔は成功してたみたい。watchOS6以降は...

2021-05-06 14:04:37

LINEのアニメーションスタンプ制作の落とし穴、、、失敗談

ゴールデンウィークにLINEスタンプを作成してみました。 作り切って申請も通したんですが、意図したアニメーションと違う、、、、 LINEクリエーターの画面だと、アニメーションのプレビュー...

2021-05-01 18:05:35

久しぶりのAdmobをobjective-cに実装。コンパイルエラーだらけ。バーミッション不具合でエミュレータにインスコできない。

忘れないようにメモ エミュレータにアプリをインストールする際にパーミッション系のエラーがでた時、また、iphone実機にインストールする際にも権限系のエラーが出る場合。 ターゲット→ex...
このエントリーをはてなブックマークに追加
右側のFacebookのLikeをクリック頂けると記事更新の際に通知されますので宜しければご利用下さい!