Tôi muốn đặt UIImageView với UIImage
và đặt hình ảnh này bên trong một UIScrollView
để thu phóng hình ảnh này; và tôi muốn điều này UIImageView
và UIScrollView
để vừa với hình ảnh ở chính giữa của chế độ xem ... có thể không?IOS: thêm imageview vào chế độ xem cuộn để phóng to thu nhỏ
Trả lời
- Đặt điều khiển xem của bạn lên như một
<UIScrollViewDelegate>
- Vẽ bạn
UIScrollView
kích thước bạn muốn cho hình chữ nhật ở trung tâm của quan điểm. Đặt mức thu phóng tối đa trong thanh tra thành một cái gì đó lớn hơn 1. Giống như 4 hoặc 10. - Nhấp chuột phải vào chế độ xem cuộn và kết nối đại biểu với bộ điều khiển chế độ xem của bạn.
- Vẽ
UIImageView
của bạn trongUIScrollView
và thiết lập nó với bất kỳ hình ảnh nào bạn muốn. Làm cho nó có cùng kích thước vớiUIScrollView
. - Ctrl + kéo biểu mẫu bạn
UIImageView
vào bộ điều khiển View của bạn để tạoIBOutlet
cho sốUIImageView
, gọi nó là thông minh nhưimageView
. Thêm mã này:
-(UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView { return self.imageView; }
Chạy ứng dụng và nhúm và chảo đến khi nội dung của trái tim của bạn.
Bạn có thể làm ví dụ về điều này nhưng theo chương trình không? – fawrkes
cho đến nay giải pháp đơn giản và rõ ràng nhất mà tôi đã tìm thấy – anthonypliu
@Justin Paulson Chúng tôi có thể hạn chế thu phóng kích thước hình ảnh không. Tôi không muốn người dùng thu nhỏ kích thước hình ảnh. Bạn có thể giúp tôi không? –
Tải xuống this và this tệp. Bạn sẽ cần chúng để xử lý các chạm.
Thêm vào quan điểm của bạn scrollview đại biểu <UIScrollViewDelegate>
và tuyên bố các cửa hàng:
@property (nonatomic, retain) IBOutlet UIScrollView *imageScrollView;
@property (nonatomic, retain) UIImageView *imageView;
nhập các tập tin tải về bên trong màn hình và làm:
#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;
}
Xong!
Về cơ bản, mã này làm là thêm imageView
làm chế độ xem phụ của imageScrollView
.
Sau đó, nó sẽ thêm các phương thức lớp TapDetecting
vào scrollView, để nhận biết số lượng vòi - pinch người dùng thực hiện và thêm chức năng thu phóng.
Bạn có thể đặt minimumScale
của hình ảnh, nếu bạn để lại 1.0
hình ảnh sẽ được hiển thị dưới dạng (nếu bạn đặt nó thấp hơn một chút), và maximumZoomScale
, tôi đề nghị bạn rời khỏi nó đến 4, nó là tốt!
Bây giờ, bạn có thể tải hình ảnh theo chương trình từ đó.
Điều cuối cùng bạn phải làm là chèn UIScrollView
vào trong tệp xib của bạn và liên kết nó với imageScrollView
. Bạn sẽ có hình ảnh ở trung tâm hoàn hảo, bạn có thể nhấn đúp vào nó để thu phóng, chụm để thu phóng khi bạn thiết lập trong mã.
Điều này giống như một công thức nấu ăn. Các bước phải nhưng bạn không giải thích lý do tại sao anh ta nên làm theo cách này. Điều này sẽ giúp anh ta và những người khác cuối cùng hơn. – Pfitz
Đây là mã cơ bản tôi đang sử dụng trong các ứng dụng của mình. Tôi sẽ giải thích – Phillip
Đừng làm cho tôi sai - mã là tốt, nhưng tại sao cũng quan trọng. Nếu không, anh ta sẽ không biết cách giải quyết một vấn đề tương tự. – Pfitz
Tôi đã viết một ứng dụng ví dụ cũng hỗ trợ AutoLayout và Storyboards để chứng minh hành vi này.Tôi hy vọng nó giúp mọi người tiết kiệm thời gian để tìm ra điều này: http://rexstjohn.com/facebook-like-ios-photo-modal-gallery-swipe-gestures/.
Với Swift 4 và iOS 11, bạn có thể sử dụng một trong hai giải pháp sau để giải quyết vấn đề của mình.
# 1. Sử dụng insets
ViewController.swift
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. Sử dụng Auto Layout
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()
}
}
Nguồn:
Vì vậy, bạn muốn hình ảnh để phóng to với một nhúm, nhưng mọi thứ khác trong giao diện cuộn để giữ nguyên? – woz
yes ............. – CrazyDev
Vâng, điều đó hoàn toàn có thể xảy ra. Bạn đã thử bất cứ điều gì cả? Hầu hết những gì bạn mô tả có thể được thực hiện trong trình tạo giao diện/bảng phân cảnh –