最近要写一个类似于社交网络的卡片,主要功能就是文字展示和图片展示,图片展示要有小图的图片预览和点击大图预览。这是一张gif图片,如果看不到图片动起来的话可以右键在新标签页打开~
height="350" width="195" src="https://img-blog.youkuaiyun.com/20170503143113588?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU29sYXJfVGVycnk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast"> <br/> 我的思路是用一个UITableViewCell把所有组件放起来,其中嵌套一个UICollectionView来存放图片的小图预览,然后再写一个图片预览控件来展示图片大图。 <br/> 整个功能的结构: <br/> <img src="https://img-blog.youkuaiyun.com/20170502232417370?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU29sYXJfVGVycnk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="img" title=""/>
图片预览控件的实现:
新建一个UICollectionViewCell,用于存放所有将要滚动浏览的图片
ImagePreviewCollectionViewCell:
import UIKit
class ImagePreviewCollectionViewCell: UICollectionViewCell {
// MARK: - 滚动视图
var scrollView: UIScrollView!
// MARK: - 用于显示图片的imageView
var imageView: UIImageView!
// MARK: - 初始化
override init(frame: CGRect) {
super.init(frame: frame)
// MARK: - scrollView初始化
scrollView = UIScrollView(frame: self.contentView.bounds)
self.contentView.addSubview(scrollView)
scrollView.delegate = self
// MARK: - scrollView缩放范围1~3
scrollView.maximumZoomScale = 3.0
scrollView.minimumZoomScale = 1.0
// MARK: - imageView初始化
imageView = UIImageView()
imageView.frame = scrollView.bounds
imageView.isUserInteractionEnabled = true
imageView.contentMode = .scaleAspectFit
scrollView.addSubview(imageView)
// MARK: - 单击监听
let tapSingle = UITapGestureRecognizer(target: self, action: #selector(tapSingleDid(_:)))
tapSingle.numberOfTapsRequired = 1
tapSingle.numberOfTouchesRequired = 1
self.imageView.addGestureRecognizer(tapSingle)
}
// MARK: - 重置单元格内元素尺寸
func resetSize() {
// MARK: - scrollView重置,不缩放
scrollView.zoomScale = 1.0
// MARK: - imageView重置
if let image = self.imageView.image {
// MARK: - 设置imageView的尺寸使一个屏幕能显示完
imageView.frame.size = scaleSize(size: image.size)
// MARK: - 使图片居中
imageView.center = scrollView.center
}
}
// MARK: - 获取imageView的缩放尺寸,确保首次显示可以是一张完整的图片
func scaleSize(size: CGSize) -> CGSize {
let width = size.width
let height = size.height
let widthRatio = width / UIScreen.main.bounds.width
let heightRatio = height / UIScreen.main.bounds.height
let ratio = max(heightRatio, widthRatio)
return CGSize(width: width / ratio, height: height / ratio)
}
// MARK: - 图片单击事件处理
func tapSingleDid(_ ges: UITapGestureRecognizer) {
let vc = self.responderViewController()
vc?.dismiss(animated: true, completion: nil)
}
// MARK: - 查找所在的ViewController
func responderViewController() -> UIViewController? {
for view in sequence(first: self.superview, next: {$0?.superview}) {
if let responder = view?.next {
if responder.isKind(of: UIViewController.self) {
return responder as? UIViewController
}
}
}
return nil
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
// MARK: - ImagePreviewCollectionViewCell的UIScrollViewDelegate代理实现
extension ImagePreviewCollectionViewCell: UIScrollViewDelegate {
// MARK: - 缩放视图
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return self.imageView
}
// MARK: - 缩放响应,设置imageView的中心位置
func scrollViewDidZoom(_ scro