29

UIImageViewをaで設定し、UIImageこのimageviewをaの中に入れてUIScrollView、この画像のズームを取得したいと思います。そして私はこれが欲しいですUIImageViewそしてUIScrollViewビューの中央の長方形に収まるようにします...それは可能ですか?

4

4 に答える 4

92
  1. ビューコントローラを次のように設定します<UIScrollViewDelegate>
  2. UIScrollViewビューの中央に長方形に必要なサイズを描画します。インスペクタの最大ズームを1より大きい値に設定します。4や10など。
  3. スクロールビューを右クリックして、デリゲートをViewControllerに接続します。
  4. に描画UIImageViewし、UIScrollView必要な画像を設定します。と同じサイズにしUIScrollViewます。
  5. Ctrlキーを押しながらViewコントローラーのにドラッグUIImageViewして、.hのを作成しますIBOutlet。これをのUIImageViewような賢いものと呼びますimageView
  6. このコードを追加します:

    -(UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView
    {
        return self.imageView;
    }
    
  7. アプリを実行し、心ゆくまでピンチしてパンします。

于 2012-07-03T21:07:40.900 に答える
29

これこのファイルをダウンロードします。タッチを処理するためにそれらが必要になります。

ビューにscrollViewデリゲートを追加し<UIScrollViewDelegate>、アウトレットを宣言します。

 @property (nonatomic, retain) IBOutlet UIScrollView *imageScrollView;
 @property (nonatomic, retain) UIImageView *imageView;

ダウンロードしたファイルを画面内にインポートし、次の手順を実行します。

#import "TapDetectingImageView.h"

#define ZOOM_STEP 2.0
@interface myView (UtilityMethods)
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center;
@end


@implementation myView
@synthesize imageScrollView, imageView;


- (void)viewDidLoad
{

    [super viewDidLoad];

    //Setting up the scrollView    
    imageScrollView.bouncesZoom = YES;
    imageScrollView.delegate = self;
    imageScrollView.clipsToBounds = YES;

    //Setting up the imageView
    imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"myImage.png"]];
    imageView.userInteractionEnabled = YES;
    imageView.autoresizingMask = ( UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin);

    //Adding the imageView to the scrollView as subView
    [imageScrollView addSubview:imageView];
    imageScrollView.contentSize = CGSizeMake(imageView.bounds.size.width, imageView.bounds.size.height);
    imageScrollView.decelerationRate = UIScrollViewDecelerationRateFast;

    //UITapGestureRecognizer set up
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
    UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
    UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerTap:)];

    [doubleTap setNumberOfTapsRequired:2];
    [twoFingerTap setNumberOfTouchesRequired:2];

    //Adding gesture recognizer
    [imageView addGestureRecognizer:doubleTap];
    [imageView addGestureRecognizer:twoFingerTap];

    [singleTap release];
    [doubleTap release];
    [twoFingerTap release];

    // calculate minimum scale to perfectly fit image width, and begin at that scale
    float minimumScale = 1.0;//This is the minimum scale, set it to whatever you want. 1.0 = default
    imageScrollView.maximumZoomScale = 4.0;
    imageScrollView.minimumZoomScale = minimumScale;
    imageScrollView.zoomScale = minimumScale;
    [imageScrollView setContentMode:UIViewContentModeScaleAspectFit];
    [imageView sizeToFit];
    [imageScrollView setContentSize:CGSizeMake(imageView.frame.size.width, imageView.frame.size.height)];



}

- (void)scrollViewDidZoom:(UIScrollView *)aScrollView {
    CGFloat offsetX = (imageScrollView.bounds.size.width > imageScrollView.contentSize.width)? 
    (imageScrollView.bounds.size.width - imageScrollView.contentSize.width) * 0.5 : 0.0;
    CGFloat offsetY = (imageScrollView.bounds.size.height > imageScrollView.contentSize.height)? 
    (imageScrollView.bounds.size.height - imageScrollView.contentSize.height) * 0.5 : 0.0;
    imageView.center = CGPointMake(imageScrollView.contentSize.width * 0.5 + offsetX, 
                                   imageScrollView.contentSize.height * 0.5 + offsetY);
}

- (void)viewDidUnload {
    self.imageScrollView = nil;
    self.imageView = nil;
}



#pragma mark UIScrollViewDelegate methods

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return imageView;
}

#pragma mark TapDetectingImageViewDelegate methods

- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer {
    // zoom in
    float newScale = [imageScrollView zoomScale] * ZOOM_STEP;

    if (newScale > self.imageScrollView.maximumZoomScale){
        newScale = self.imageScrollView.minimumZoomScale;
        CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];

        [imageScrollView zoomToRect:zoomRect animated:YES];

    }
    else{

        newScale = self.imageScrollView.maximumZoomScale;
        CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];

        [imageScrollView zoomToRect:zoomRect animated:YES];
    }
}


- (void)handleTwoFingerTap:(UIGestureRecognizer *)gestureRecognizer {
    // two-finger tap zooms out
    float newScale = [imageScrollView zoomScale] / ZOOM_STEP;
    CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
    [imageScrollView zoomToRect:zoomRect animated:YES];
}

#pragma mark Utility methods

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

    CGRect zoomRect;

    // the zoom rect is in the content view's coordinates. 
    //    At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds.
    //    As the zoom scale decreases, so more content is visible, the size of the rect grows.
    zoomRect.size.height = [imageScrollView frame].size.height / scale;
    zoomRect.size.width  = [imageScrollView frame].size.width  / scale;

    // choose an origin so as to get the right center.
    zoomRect.origin.x    = center.x - (zoomRect.size.width  / 2.0);
    zoomRect.origin.y    = center.y - (zoomRect.size.height / 2.0);

    return zoomRect;
}

終わり!

基本的に、このコードが行うことは、のimageViewサブビューとしてを追加することimageScrollViewです。

次に、TapDetectingタップ数を認識するために、クラスメソッドをscrollViewに追加します。ユーザーがピンチしてズーム機能を追加します。

画像のを設定できminimumScaleます。そのままにしておく1.0と、画像はそのまま表示されます(少し低く設定すると、拡大縮小されます)。また、maximumZoomScale4のままにしておくことをお勧めします。

これで、そこからプログラムで画像を読み込むことができます。

あなたがしなければならない最後のことはUIScrollViewあなたのxibファイルの中に挿入してそれをにリンクすることimageScrollViewです。画像は完全な中央に表示されます。コードで設定するときに、画像をダブルタップしてズームしたり、ピンチしてズームしたりできます。

于 2012-07-03T21:09:39.463 に答える
8

Swift4とiOS11では、問題を解決するために、次の2つの解決策のいずれかを使用できます。


#1。インセットの使用

ViewController.swift

import UIKit

final class ViewController: UIViewController {

    private let scrollView = ImageScrollView(image: UIImage(named: "image")!)

    override func viewDidLoad() {
        view.backgroundColor = .black
        view.addSubview(scrollView)

        scrollView.frame = view.frame
        scrollView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    }

}

ImageScrollView.swift

import UIKit

final class ImageScrollView: UIScrollView {

    private let imageView = UIImageView()
    override var frame: CGRect {
        didSet {
            if frame.size != oldValue.size { setZoomScale() }
        }
    }

    required init(image: UIImage) {
        super.init(frame: .zero)

        imageView.image = image
        imageView.sizeToFit()
        addSubview(imageView)
        contentSize = imageView.bounds.size

        contentInsetAdjustmentBehavior = .never // Adjust content according to safe area if necessary
        showsVerticalScrollIndicator = false
        showsHorizontalScrollIndicator = false
        alwaysBounceHorizontal = true
        alwaysBounceVertical = true
        delegate = self
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // MARK: - Helper methods

    func setZoomScale() {
        let widthScale = frame.size.width / imageView.bounds.width
        let heightScale = frame.size.height / imageView.bounds.height
        let minScale = min(widthScale, heightScale)
        minimumZoomScale = minScale
        zoomScale = minScale
    }

}
extension ImageScrollView: UIScrollViewDelegate {

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

    func scrollViewDidZoom(_ scrollView: UIScrollView) {
        let imageViewSize = imageView.frame.size
        let scrollViewSize = scrollView.bounds.size
        let verticalInset = imageViewSize.height < scrollViewSize.height ? (scrollViewSize.height - imageViewSize.height) / 2 : 0
        let horizontalInset = imageViewSize.width < scrollViewSize.width ? (scrollViewSize.width - imageViewSize.width) / 2 : 0
        scrollView.contentInset = UIEdgeInsets(top: verticalInset, left: horizontalInset, bottom: verticalInset, right: horizontalInset)
    }

}

#2。自動レイアウトの使用

ViewController.swift

import UIKit

final class ViewController: UIViewController {

    private let scrollView = ImageScrollView(image: UIImage(named: "image")!)

    override func viewDidLoad() {
        view.backgroundColor = .black
        view.addSubview(scrollView)

        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    }

    override func viewDidLayoutSubviews() {        
        scrollView.setZoomScale()
    }

}

ImageScrollView.swift

import UIKit

final class ImageScrollView: UIScrollView {

    private let imageView = UIImageView()
    private var imageViewBottomConstraint = NSLayoutConstraint()
    private var imageViewLeadingConstraint = NSLayoutConstraint()
    private var imageViewTopConstraint = NSLayoutConstraint()
    private var imageViewTrailingConstraint = NSLayoutConstraint()

    required init(image: UIImage) {
        super.init(frame: .zero)

        imageView.image = image
        imageView.sizeToFit()
        addSubview(imageView)

        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageViewLeadingConstraint = imageView.leadingAnchor.constraint(equalTo: leadingAnchor)
        imageViewTrailingConstraint = imageView.trailingAnchor.constraint(equalTo: trailingAnchor)
        imageViewTopConstraint = imageView.topAnchor.constraint(equalTo: topAnchor)
        imageViewBottomConstraint = imageView.bottomAnchor.constraint(equalTo: bottomAnchor)
        NSLayoutConstraint.activate([imageViewLeadingConstraint, imageViewTrailingConstraint, imageViewTopConstraint, imageViewBottomConstraint])

        contentInsetAdjustmentBehavior = .never // Adjust content according to safe area if necessary
        showsVerticalScrollIndicator = false
        showsHorizontalScrollIndicator = false
        alwaysBounceHorizontal = true
        alwaysBounceVertical = true
        delegate = self
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // MARK: - Helper methods

    func setZoomScale() {
        let widthScale = frame.size.width / imageView.bounds.width
        let heightScale = frame.size.height / imageView.bounds.height
        let minScale = min(widthScale, heightScale)
        minimumZoomScale = minScale
        zoomScale = minScale
    }

}
extension ImageScrollView: UIScrollViewDelegate {

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

    func scrollViewDidZoom(_ scrollView: UIScrollView) {
        let yOffset = max(0, (bounds.size.height - imageView.frame.height) / 2)
        imageViewTopConstraint.constant = yOffset
        imageViewBottomConstraint.constant = yOffset

        let xOffset = max(0, (bounds.size.width - imageView.frame.width) / 2)
        imageViewLeadingConstraint.constant = xOffset
        imageViewTrailingConstraint.constant = xOffset

        layoutIfNeeded()
    }

}

出典:

于 2017-07-30T16:43:13.943 に答える
3

この動作を示すために、AutoLayoutとストーリーボードもサポートするサンプルアプリケーションを作成しました。これを理解しようとするすべての人の時間を節約できることを願っています:http://rexstjohn.com/facebook-like-ios-photo-modal-gallery-swipe-gestures/

于 2013-12-25T05:58:27.663 に答える