我想设置一个带有UIImage
的UIImageView,并将此imageview放在UIScrollView
内以获得此图像的缩放;
我希望这个UIImageView
和UIScrollView
适合视图中心的矩形...是否可能?
答案 0 :(得分:88)
<UIScrollViewDelegate>
UIScrollView
矩形。将检查器中的最大缩放设置为大于1的值。如4或10。UIImageView
中绘制UIScrollView
并将其设置为您想要的任何图像。使其与UIScrollView
。UIImageView
形式拖动到视图控制器的.h
,为IBOutlet
创建UIImageView
,称之为imageView
的聪明之处添加此代码:
-(UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView { return self.imageView; }
运行应用程序并捏合并平移心脏的内容。
答案 1 :(得分: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
,图片应该按原样显示(如果您将图片设置得稍低一些,则会缩放) maximumZoomScale
,我建议你把它留到4,没关系!
现在,您可以从那里以编程方式加载图像。
您要做的最后一件事是在xib文件中插入UIScrollView
并将其链接到imageScrollView
。您将图像置于完美的中心,您可以双击它以进行缩放,在您设置代码时捏缩放。
答案 2 :(得分:5)
使用Swift 4和iOS 11,您可以使用以下两种解决方案之一来解决您的问题。
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)
}
}
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()
}
}
来源:
答案 3 :(得分:3)
我编写了一个示例应用程序,它也支持AutoLayout和Storyboard来演示这种行为。我希望它能节省每个人的时间来解决这个问题:http://rexstjohn.com/facebook-like-ios-photo-modal-gallery-swipe-gestures/。