干货!速写一个简单的图片浏览器 SP_PhotoBrowser

@使用

SP_PhotoBrowser.show(self, images: images, index:index)

1,主控制器

//
//  SP_PhotoBrowser.swift
//  IEXBUY
//
//  Created by sifenzi on 16/9/5.
//  Copyright © 2016年 IEXBUY. All rights reserved.
//

import UIKit

class SP_PhotoBrowser: UIViewController {
    //MARK:--- 提供调用接口 -----------------------------
    class func show(_ parentVC:UIViewController?, images:[String], index:Int){
    
        let vc = SP_PhotoBrowser()
        vc.currentPage = index
        vc.selectImages = images
        parentVC?.present(vc, animated: false) {}
    }
    //MARK:--- 主要参数 -----------------------------
    fileprivate let cellIdentifier = "cell_SP_PhotoBrowser"
    fileprivate var currentPage: Int = 0
    
    fileprivate var selectImages:[String] = [] {
        didSet{
            collectionView.reloadData()
        }
    }
    //MARK:--- 主要控件 -----------------------------
    fileprivate lazy var collectionView: UICollectionView = {
        //self.automaticallyAdjustsScrollViewInsets = false
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.itemSize = CGSize(width: self.view.frame.width,height: self.view.frame.height)
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0
        let collectionV = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout)
        collectionV.dataSource = self
        collectionV.delegate = self
        collectionV.isPagingEnabled = true
        collectionV.scrollsToTop = false
        collectionV.showsHorizontalScrollIndicator = false
        collectionV.contentOffset = CGPoint(x: 0, y: 0)
        collectionV.contentSize = CGSize(width: self.view.bounds.width * CGFloat(self.selectImages.count), height: self.view.bounds.height)
        
        
        collectionV.register(SP_PhotoPreviewCell.self, forCellWithReuseIdentifier: self.cellIdentifier)
        return collectionV
    }()
    fileprivate lazy var titleLab:UILabel = {
        let label = UILabel(frame: CGRect(x: (SP_ScreenWidth - 100)/2,y: 25,width: 100 ,height: 25))
        label.textAlignment = .center
        label.textColor = UIColor.white
        label.font = UIFont.systemFont(ofSize: 17.0)
        return label
    }()
    fileprivate lazy var navigationView:UIView = {
        let bgView = UIView(frame: CGRect(x: 0,y: 0,width: self.view.frame.width ,height: 64))
        bgView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5)
        
        
        bgView.addSubview(self.titleLab)
        
        let backButton = UIButton(frame: CGRect(x: 10,y: 25,width: 25 ,height: 25))
        backButton.setImage(UIImage(named:"photo_back" ), for: UIControlState())
        backButton.addTarget(self, action: #selector(SP_PhotoBrowser.backClick), for: .touchUpInside)
        bgView.addSubview(backButton)
        return bgView
    }()
    
    //MARK:--- 主要方法 -----------------------------
    override var preferredStatusBarStyle : UIStatusBarStyle {
        return .default
    }
    override var prefersStatusBarHidden : Bool {
        return true
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        setCollectionView()
        
        setNavigationView()
    }
    
    func setCollectionView(){
        view.addSubview(self.collectionView)
    }
    
    func setNavigationView() {
        self.view.addSubview(navigationView)
        updatePageTitle()
        let indexPath = IndexPath(row: currentPage, section: 0)
        collectionView.scrollToItem(at: indexPath, at: .left, animated: false)
    }
    func backClick() {
        self.dismiss(animated: false, completion: nil)
    }
    fileprivate func updatePageTitle(){
        self.titleLab.text =  String(self.currentPage+1) + "/" + String(self.selectImages.count)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}
// MARK: -  collectionView dataSource delagate
extension SP_PhotoBrowser:UICollectionViewDataSource,UICollectionViewDelegate {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.selectImages.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.cellIdentifier, for: indexPath) as! SP_PhotoPreviewCell
        
        cell.name = self.selectImages[indexPath.row]
        cell.SP_PhotoPreviewCellBlock = { _ in
            self.backClick()
        }
        return cell
    }
    // MARK: -  scroll page
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let offset = scrollView.contentOffset
        self.currentPage = Int(offset.x / self.view.bounds.width)
        self.updatePageTitle()
    }
}

2,图片装载 Cell

//
//  SP_PhotoPreviewCell.swift
//  IEXBUY
//
//  Created by sifenzi on 16/9/5.
//  Copyright © 2016年 IEXBUY. All rights reserved.
//

import UIKit
import SDWebImage
class SP_PhotoPreviewCell: UICollectionViewCell, UIScrollViewDelegate {

    var SP_PhotoPreviewCellBlock: (()->Void)?
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        self.configView()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
    }
    func configView() {
        self.addSubview(scrollView)
        scrollView.addSubview(imageView)
        //手势
        self.addGestureRecognizer(singleTap)
        self.addGestureRecognizer(doubleTap)
        
        self.addSubview(loadingView)
        
    }
    fileprivate lazy var scrollView: UIScrollView = {
        let scrollView = UIScrollView(frame: self.bounds)
        scrollView.minimumZoomScale = 1.0
        scrollView.maximumZoomScale = 4.0
        scrollView.delegate = self
        scrollView.showsHorizontalScrollIndicator = false
        scrollView.showsVerticalScrollIndicator = false
        scrollView.isMultipleTouchEnabled = true//多点触摸
        scrollView.bouncesZoom = true //NO时缩放不可超出最大最小缩放范围
        scrollView.scrollsToTop = false //控制控件滚动到顶部
        //self.scrollView!.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]//变换同等高度和宽度
        scrollView.delaysContentTouches = false//控制视图是否延时调用开始滚动的方法
        scrollView.canCancelContentTouches = true//控制控件是否接触取消touch的事件
        scrollView.alwaysBounceVertical = false //控制垂直方向遇到边框是否反弹
        return scrollView
    }()
    
    fileprivate lazy var imageView: UIImageView = {
        let imgView = UIImageView()
        imgView.clipsToBounds = true
        return imgView
    }()
    
    fileprivate lazy var loadingView:SP_PhotoProgressView = {
        //加载进度
        let loadView = SP_PhotoProgressView()
        loadView.isHidden = false
        loadView.progress = 0.1
        let photoViewSize = self.bounds.size;
        loadView.center = CGPoint(x: photoViewSize.width * 0.5 , y: photoViewSize.height * 0.5)
        loadView.bounds = CGRect(x: 0, y: 0, width: 50, height: 50)
        return loadView
    }()
    fileprivate lazy var singleTap:UITapGestureRecognizer = {
        let tap = UITapGestureRecognizer(target: self, action: #selector(PhotoPreviewCell.singleTap(_:)))
        tap.require(toFail: self.doubleTap)
        return tap
    }()
    fileprivate lazy var doubleTap:UITapGestureRecognizer = {
        let tap = UITapGestureRecognizer(target: self, action: #selector(PhotoPreviewCell.doubleTap(_:)))
        tap.numberOfTapsRequired = 2
        return tap
    }()
    func singleTap(_ tap:UITapGestureRecognizer) {
        SP_PhotoPreviewCellBlock?()
    }
    
    
    var name:String = "" {
        didSet{
            let exists = SDWebImageManager.shared().cachedImageExists(for: URL(string: name))
            if !exists {
                loadingView.isHidden = false
                loadingView.progress = 0.1
            }
            
            imageView.sd_setImage(with: URL(string: name), placeholderImage: UIImage(named: "HuanChong中"), options: .lowPriority, progress: { [weak self] (receivedSize, totalSize) in
                let progress = Double(receivedSize) / Double(totalSize)
                self?.loadingView.progress = progress
            }) { [weak self] (image, error, cacheType, url) in
                guard self != nil else {return}
                self?.setImageViewFrame(self!.name)
                self?.loadingView.isHidden = true
            }
        }
    }
    
    fileprivate func setImageViewFrame(_ url:String) {
        guard !url.isEmpty else {return}
        DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {
            if let url = URL(string:url), let data = try? Data(contentsOf: url) {
                let image = UIImage(data: data) ?? UIImage()
                DispatchQueue.main.async(execute: {
                    self.scrollView.zoomScale = self.scrollView.minimumZoomScale
                    
                    let imageSize = image.size
                    var fitSize = imageSize
                    fitSize.width = self.bounds.width
                    fitSize.height = fitSize.width / imageSize.width * imageSize.height
                    self.imageView.center = CGPoint(x: self.bounds.width * 0.5, y: self.bounds.height * 0.5)
                    self.imageView.bounds = CGRect(x: 0, y: 0, width: fitSize.width, height: fitSize.height)
                    self.scrollView.contentSize = self.imageView.bounds.size
                })
            }
        }
    }
    
    //MARK:--- 缩放 -----------------------------
    func doubleTap(_ tap:UITapGestureRecognizer) {
        // 状态还原
        if self.scrollView.zoomScale == self.scrollView.minimumZoomScale {
            let tapPoint = tap.location(in: self)
            self.scrollView.zoom(to: CGRect(x: tapPoint.x, y: tapPoint.y, width: 1, height: 1), animated: true)
        } else {
            self.scrollView.setZoomScale(self.scrollView.minimumZoomScale, animated: true)
        }
    }
    
    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        return self.imageView
    }
    
    func scrollViewDidZoom(_ scrollView: UIScrollView) {
        let contentSize = scrollView.contentSize
        let scrollViewSize = scrollView.bounds.size
        
        let centerX = scrollViewSize.width > contentSize.width ? scrollViewSize.width * 0.5 : contentSize.width * 0.5
        let centerY = scrollViewSize.height > contentSize.height ? scrollViewSize.height * 0.5 : contentSize.height * 0.5
        
        imageView.center = CGPoint(x: centerX, y: centerY)
        
    }
}

3,加载进度环

//
//  SP_PhotoBrowser.swift
//  IEXBUY
//
//  Created by sifenzi on 16/9/5.
//  Copyright © 2016年 IEXBUY. All rights reserved.
//

import UIKit

class SP_PhotoProgressView: UIView {

    var progress: Double = 0 {
        didSet {
            self.setNeedsDisplay()
        }
    }
    
    var mCenter = CGPoint.zero
    
    var mRadius: CGFloat = 0
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.8)
        self.layer.masksToBounds = true
    }
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func draw(_ rect: CGRect) {
        super.draw(rect)
        if (mRadius == 0) {
            let w = rect.size.width;
            let h = rect.size.height;
            mCenter = CGPoint(x: w * 0.5, y: h * 0.5);
            mRadius = min(w, h) * 0.5 - 8;
            self.layer.cornerRadius = min(w, h) * 0.5;
        }
        let ctx = UIGraphicsGetCurrentContext();
        
        let center = mCenter;
        let radius = mRadius;
        let startAngle = CGFloat(-M_PI_2);
        let endAngle = CGFloat(-M_PI_2 + progress * M_PI * 2);
        
        let blackPath = UIBezierPath(arcCenter: center, radius: radius, startAngle: startAngle, endAngle: CGFloat(M_PI * 2.0) + startAngle, clockwise: true)
        ctx?.setLineWidth(3.0);
        UIColor.black.set()
        ctx?.addPath(blackPath.cgPath);
        ctx?.strokePath();
        
        let whitePath = UIBezierPath(arcCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
        ctx?.setLineWidth(3.0);
        ctx?.setLineCap(.round);
        UIColor.white.set()
        ctx?.addPath(whitePath.cgPath);
        ctx?.strokePath();
    }
}

你可能感兴趣的:(干货!速写一个简单的图片浏览器 SP_PhotoBrowser)