美文网首页iOS Developer
Swift -- 图片浏览器

Swift -- 图片浏览器

作者: 71150ce14a00 | 来源:发表于2017-02-16 12:07 被阅读813次
1 2
import UIKit
protocol  HJImageBrowserDelegate : NSObjectProtocol {

///  获取缩略图图片 && Getting thumbnail images
///  - parameter indexRow: 当前是第几个cell && The current is which a cell
///  - returns: 获取的缩略图图片 && Getting thumbnail images

func getTheThumbnailImage(_ indexRow: Int) ->UIImage

}

class HJImageBrowser:
UIView,
UICollectionViewDelegate,
UICollectionViewDataSource,
UICollectionViewDelegateFlowLayout{

/// 获取高清和缩略图图片代理 && Get Gao Qinghe thumbnail images agent
var delegate :HJImageBrowserDelegate?

/// 承载view  父视图view && Bearing the view parent view view
var bottomView:UIView!

/// 是否让走预加载图片 && If let go preload picture
var isShow: Bool!

/* 如果没有缩略图则显示这张图片 && If there is no thumbnail drawings show the picture
 如果这张图片也没有则什么也不显示 && If they aren't in the picture is what also don't show
 */
var defaultImage: UIImage!

/// 当前显示的是第几张图片 && How many pictures of the currently displayed
var indexImage: Int!

/// 高清图片数组 && High-resolution image array
var arrayImage: [String]!

/// 图片展示View && Pictures show the View
var collectionView:UICollectionView!

/// 图片个数显示 && The number of picture
var imageNumberLabel: UILabel!

override init(frame: CGRect) {
    
    super.init(frame: frame)
    
    creatUI()
    
}

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

}


extension HJImageBrowser{

func  creatUI(){
    
    self.backgroundColor = viewTheBackgroundColor
    
    //        self.bottomView = UIView()
    
    isShow = false
    
    creatCollectionView()
    
}

func  creatCollectionView(){
    
    let fowLayout = UICollectionViewFlowLayout.init()
    
    fowLayout.minimumLineSpacing = 0;
    
    fowLayout.scrollDirection = .horizontal
    
    fowLayout.itemSize = CGSize(width: ScreenWidth + imageInterval,
                                    height: ScreenHeight)
    
    collectionView = UICollectionView.init(frame: CGRect(x: 0,
        y: 0,
        width: ScreenWidth + imageInterval,
        height: ScreenHeight),
                                           collectionViewLayout: fowLayout)
    
    collectionView.allowsMultipleSelection = true
    
    collectionView.register(HJCell.self, forCellWithReuseIdentifier: "cellId")
    
    collectionView.isPagingEnabled = true
    
    collectionView.delegate = self
    
    collectionView.dataSource = self
    
    collectionView.alpha = 0
    
    collectionView.showsHorizontalScrollIndicator = false
    
    collectionView.showsVerticalScrollIndicator = false
    
    collectionView.backgroundColor = viewTheBackgroundColor
    
    imageNumberLabel = UILabel.init(frame: CGRect(x: 0, y: ScreenHeight - 30, width: ScreenWidth, height: 20))
    
    imageNumberLabel.backgroundColor = UIColor.clear
    
    imageNumberLabel.textColor = UIColor.white
    
    imageNumberLabel.textAlignment = .center
    
    imageNumberLabel.alpha = 0
    
    self.addSubview(collectionView)
    
    self.addSubview(imageNumberLabel)
    
}

override func layoutSubviews(){
    
    super.layoutSubviews()
    
    imageNumberLabel.text = String.init(self.indexImage) + "/" + "\(self.arrayImage.count)"
    
    if (isShow == false) {
        
        if (self.indexImage == nil) {
            
            

            
            let altShow = UIAlertView.init(title: nil,
                                           message: "请设置imageInterval属性",
                                           delegate: nil,
                                           cancelButtonTitle: "确定")
            altShow.show()
            
            self.removeFromSuperview()
            
            return
            
        }
        
        self.collectionView.contentOffset = CGPoint(x: (self.frame.size.width + imageInterval) *  CGFloat(self.indexImage), y: 0)
        
        isShow = true
        
        let  tempView = UIImageView.init()
        
        var ima = UIImage.init()
        
        self.addSubview(tempView)
        
        if ((self.delegate?.getTheThumbnailImage(self.indexImage)) != nil) {
            
            ima = (self.delegate?.getTheThumbnailImage(self.indexImage))!
            
            
        }else{
            
            if (self.defaultImage != nil) {
                
                ima = self.defaultImage!
                
            }else{
                
                ima = getColorImageWithColor()
                
            }
            
        }
        
        tempView.image = ima
        
        var ve = UIView()
        
        if self.bottomView == nil {
            
            let altShow = UIAlertView.init(title: nil,
                                           message: "请设置bottomView属性",
                                           delegate: nil,
                                           cancelButtonTitle: "确定")
            
            altShow.show()
            
            self.removeFromSuperview()
            
            return
            
        }
        
        
        if self.bottomView.isKind(of: UICollectionView.classForCoder()) {
            
            let view = self.bottomView as! UICollectionView
            
            let path = IndexPath.init(row: self.indexImage, section: 0)
            
            ve = view.cellForItem(at: path)!
            
        }else{
            
            ve = self.bottomView.subviews[indexImage]
        }
        
        let rect = self.bottomView.convert(ve.frame, to: self)
        
        tempView.frame = rect
        
        self.collectionView.isHidden = true
        
        self.collectionView.alpha = 1
        
        let heightS = (ima.size.height)/(ima.size.width)*ScreenWidth
        
        let widthS = (ima.size.width)/(ima.size.height)*heightS
        
        UIView.animate(withDuration: animationTime, animations: {
            
            tempView.frame = CGRect(x: 0, y: 0, width: widthS, height: heightS)
            
            if heightS < ScreenHeight {
                
                tempView.center = self.center
                
            }
            
        }, completion: { (callBack) in
            
            tempView.removeFromSuperview()
            
            self.collectionView.isHidden = false
            
        }) 
    }
}

internal func show(){
    
    let window = UIApplication.shared.keyWindow
    
    self.frame = (window?.bounds)!
    
    window?.addSubview(self)
    
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{
    
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! HJCell
    
    cell.bottomView = self.bottomView
    
    
    if ((self.delegate?.getTheThumbnailImage(indexPath.row)) != nil) {
        
        cell.setImageWithURL(arrayImage[indexPath.row],
                             placeholderImage:
            (self.delegate?.getTheThumbnailImage(indexPath.row))!,
                             defaultImage:self.defaultImage)
        
    }else{
        
        if (self.defaultImage == nil) {
            
            self.defaultImage = UIImage.init()
        }
        
        cell.setImageWithURL(arrayImage[indexPath.row],
                             placeholderImage:self.defaultImage,
                             defaultImage:self.defaultImage)
    }
    
    return cell
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    
    return arrayImage.count
    
}

func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    
    let firstIndexPath = self.collectionView.indexPathsForVisibleItems.first
    
    indexImage = firstIndexPath?.row
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    
    let path = self.collectionView.indexPathForItem(at: self.collectionView.contentOffset)
    let number = path?.row
    
    imageNumberLabel.text = "\(number!)" + "/" + "\(self.arrayImage.count)"
    
    UIView.animate(withDuration: 3, animations: {
        
        self.imageNumberLabel.alpha = 0
        
    }) 
    
}

func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
    
    UIView.animate(withDuration: 0.2, animations: {
        
        self.imageNumberLabel.alpha = 1
        
    }) 
    
}

}

@objc(HJCell)
class HJCell:
UICollectionViewCell,
UIScrollViewDelegate,
UIActionSheetDelegate{

static let cellId = "HJCell"

var BigImage: UIImageView!

var BottomScroll: UIScrollView!

var bottomView:UIView!

var cireView: cireview!

override init(frame: CGRect) {
    
    super.init(frame: frame)
    
    creatUI()
    
}

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

func creatUI(){
    
    self.cireView = cireview.init(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
    
    self.cireView.value  = 0
    
    self.cireView.maximumValue = 1
    
    self.cireView.isUserInteractionEnabled = false
    
    self.cireView.center = CGPoint(x: ScreenWidth/2, y: ScreenHeight/2)
    
    BottomScroll = UIScrollView.init(frame: CGRect(x: 0,
        y: 0,
        width: ScreenWidth,
        height: ScreenHeight))
    
    BottomScroll.delegate = self
    
    BottomScroll.maximumZoomScale = 2.0;
    
    BottomScroll.minimumZoomScale = 1.0;
    
    BottomScroll.backgroundColor = viewTheBackgroundColor
    
    BigImage = UIImageView.init()
    
    BigImage.isUserInteractionEnabled = true
    
    BottomScroll.addSubview(BigImage)
    
    self.addSubview(BottomScroll)
    
    let singleTap = UITapGestureRecognizer.init(target: self,
                                                action: #selector(self.oneTouch(_:)))
    
    let doubleTap = UITapGestureRecognizer.init(target: self,
                                                action: #selector(self.twoTouch(_:)))
    
    let longpressGesutre = UILongPressGestureRecognizer(target: self,
                                                        action: #selector(self.handleLongpressGesture(_:)))
    
    doubleTap.numberOfTapsRequired = 2
    
    singleTap.require(toFail: doubleTap)
    
    doubleTap.require(toFail: longpressGesutre)
    
    BottomScroll.addGestureRecognizer(singleTap)
    
    BottomScroll.addGestureRecognizer(doubleTap)
    
    BottomScroll.addGestureRecognizer(longpressGesutre)
    
    self.cireView.isHidden = true
    
    self.addSubview(cireView)
    
}

func setUpTheValue(_ value:CGFloat){
    
    self.cireView.value =  value
    
}

internal func setImageWithURL(_ url:String, placeholderImage:UIImage, defaultImage:UIImage){
    
    self.setBigImageTheSizeOfThe(placeholderImage, defaultImage:defaultImage)
    
    self.cireView.isHidden = false
    
    BigImage.sd_setImage(with: URL.init(string: url),
                                placeholderImage: getColorImageWithColor(),
                                options: .cacheMemoryOnly,
                                progress: { (receivedSize, expectedSize) in
        
        let showProgress = Float(receivedSize)/Float(expectedSize)
        
        self.setUpTheValue(CGFloat.init(showProgress))
        
    }) { (image, error, cacheType, imageURL) in
        
        self.cireView.isHidden = true
        
        if image == nil {
            
            self.setBigImageTheSizeOfThe(placeholderImage, defaultImage:defaultImage)
            
            return
            
        }
        
        self.setBigImageTheSizeOfThe(image!, defaultImage:defaultImage)
        
    }
    
    
    
}

func setBigImageTheSizeOfThe(_ bImage:UIImage, defaultImage:UIImage){
    
    self.BottomScroll.contentOffset = CGPoint.zero
    
    self.BottomScroll.contentSize = CGSize.zero
    
    self.BottomScroll.contentInset = UIEdgeInsets.zero
    
    self.BottomScroll.zoomScale = 1
    
    var heightS = (bImage.size.height)/(bImage.size.width)*self.BottomScroll.frame.size.width
    
    var widthS = (bImage.size.width)/(bImage.size.height)*heightS
    
    if heightS.isNaN || widthS.isNaN {
        
        let image = defaultImage
        
        heightS = (image.size.height)/(image.size.width)*self.BottomScroll.frame.size.width
        
        widthS = (image.size.width)/(image.size.height)*heightS
        
        if heightS.isNaN || widthS.isNaN {
            
            let imageI = getColorImageWithColor()
            
            heightS = (imageI.size.height)/(imageI.size.width)*self.BottomScroll.frame.size.width
            
            widthS = (imageI.size.width)/(imageI.size.height)*heightS
            
            self.BigImage.image = imageI
            
        }else{
            
            heightS = (image.size.height)/(image.size.width)*self.BottomScroll.frame.size.width
            
            widthS = (image.size.width)/(image.size.height)*heightS
            
            self.BigImage.image = image
        }
        
    }
    
    self.BigImage.frame = CGRect(x: 0, y: 0, width: widthS, height: heightS)
    
    if heightS > ScreenHeight {
        
        self.BottomScroll.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
        
        self.BottomScroll.contentSize = CGSize(width: widthS, height: heightS)
        
    }else{
        
        self.BottomScroll.contentInset = UIEdgeInsetsMake((self.BottomScroll.frame.size.height - heightS)/2, 0, 0, 0)
        
    }
}

func oneTouch(_ sender: UITapGestureRecognizer){
    
    let  tempView = UIImageView.init()
    
    let imaV = sender.view?.subviews[0] as! UIImageView
    
    let ima = imaV.image
    
    tempView.image = ima
    
    self.superview?.superview?.addSubview(tempView)
    
    let ve:UIView!
    
    if self.bottomView.isKind(of: UICollectionView.classForCoder()) {
        
        let view = self.bottomView as! UICollectionView
        
        let path = IndexPath.init(row: self.indexPath().row, section: 0)
        
        ve = view.cellForItem(at: path)
        
    }else{
        
        ve = self.bottomView.subviews[self.indexPath().row]
        
    }
    
    if ve == nil {
        
        UIView.animate(withDuration: animationTime, animations: {
            
            self.superCollectionView().alpha = 0
            
            self.superview?.superview?.alpha = 0
            
        }, completion: { (callBack) in
            
            self.superview?.superview?.removeFromSuperview()
            
        }) 
        
        return
    }
    
    let rect = self.bottomView.convert(ve.frame, to: self)
    
    let poin = self.bottomView.convert(ve.center, to: self)
    
    let heightS = (ima?.size.height)!/(ima?.size.width)!*ScreenWidth
    
    let widthS = (ima?.size.width)!/(ima?.size.height)!*heightS
    
    tempView.frame = CGRect(x: 0, y: 0, width: widthS, height: heightS)
    
    if ima?.size.height < ScreenHeight {
        
        tempView.center = (self.superview?.superview?.center)!
        
    }
    
    self.superCollectionView().alpha = 0.5
    
    self.superview?.superview?.backgroundColor = UIColor.clear
    
    UIView.animate(withDuration: animationTime, animations: {
        
        self.superCollectionView().alpha = 0
        
        tempView.center = poin
        
        tempView.bounds = rect
        
    }, completion: { (callBack) in
        
        self.superview?.superview?.removeFromSuperview()
        
    }) 
}

func twoTouch(_ sender: UITapGestureRecognizer){
    
    let touchPoint = sender.location(in: sender.view)
    
    let scroll =  sender.view as! UIScrollView
    
    let imageView = scroll.subviews[0]
    
    let zs = scroll.zoomScale
    
    UIView.animate(withDuration: 0.5, animations: {
        
        scroll.zoomScale = (zs == 1.0) ? 2.0 : 0.0
        
    }) 
    
    UIView.animate(withDuration: 0.5, animations: {
        
        if scroll.zoomScale==2.0{
            
            let rectHeight = (self.frame.size.height)/scroll.zoomScale
            
            let rectWidth = self.frame.size.width/scroll.zoomScale
            
            let rectX = touchPoint.x-rectWidth/2.0
            
            let rectY = touchPoint.y-rectHeight/2.0
            
            let zoomRect = CGRect(x: rectX, y: rectY, width: rectWidth, height: rectHeight)
            
            scroll.zoom(to: zoomRect, animated: false)
            
            if imageView.frame.size.height > ScreenHeight {
                
                self.BottomScroll.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
                
            }else{
                
                self.BottomScroll.contentInset = UIEdgeInsetsMake((self.BottomScroll.frame.size.height - (imageView.frame.size.height))/2, 0, 0, 0)
                
            }
            
        }else{
            
            if imageView.frame.size.height > ScreenHeight {
                
                self.BottomScroll.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
                
            }else{
                
                self.BottomScroll.contentInset = UIEdgeInsetsMake((self.BottomScroll.frame.size.height - (imageView.frame.size.height))/2, 0, 0, 0)
                
            }
            
        }
    }) 
}

func handleLongpressGesture(_ sender : UILongPressGestureRecognizer){
    
    if (sender.state == .began) {
        
        
        let saveImageAlt = UIActionSheet.init(title: "保存图片到本地", delegate: self, cancelButtonTitle: "取消", destructiveButtonTitle: "保存")
        
        saveImageAlt.show(in: self)
    }
}

func actionSheet(_ actionSheet: UIActionSheet, willDismissWithButtonIndex buttonIndex: Int){
    
    if buttonIndex == 0 {
        
        UIImageWriteToSavedPhotosAlbum(self.BigImage.image!,
                                       self,
                                       #selector(HJCell.image(_:didFinishSavingWithError:contextInfo:)), nil)
        
    }
    
}

func image(_ image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: AnyObject) {
    
    if error != nil {
        
        let altShow =  UIAlertView.init(title: nil,
                                        message: "图片保存失败",
                                        delegate: nil,
                                        cancelButtonTitle: "确定")
        
        altShow.show()
        
        return
        
    }
    
    let altShow =  UIAlertView.init(title: nil,
                                    message: "图片保存成功",
                                    delegate: nil,
                                    cancelButtonTitle: "确定")
    altShow.show()
    
}

func viewForZooming(in scrollView: UIScrollView) -> UIView? {
    
    return scrollView.subviews[0]
    
}

func scrollViewDidZoom(_ scrollView: UIScrollView) {

    let image = scrollView.subviews[0]
    
    if image.frame.size.height > ScreenHeight {
        
        UIView.animate(withDuration: 0.2, animations: {
            
            self.BottomScroll.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
            
        })
        
    }else{
        
        UIView.animate(withDuration: 0.2, animations: {
            
            self.BottomScroll.contentInset = UIEdgeInsetsMake((self.BottomScroll.frame.size.height - image.frame.size.height)/2, 0, 0, 0)
            
        })
    }
}

func indexPath() ->IndexPath{
    
    let collectionView = self.superCollectionView
    
    let indexPath = collectionView().indexPath(for: self)
    
    return indexPath!;
    
}

func superCollectionView() ->UICollectionView{
    
    return self.findSuperViewWithClass(UICollectionView.classForCoder()) as! UICollectionView
    
}

func findSuperViewWithClass(_ superViewClass:AnyClass) ->UIView{
    
    var superView = self.superview
    
    var foundSuperView:UIView?
    
    while (superView != nil && foundSuperView == nil) {
        
        if ((superView?.isKind(of: superViewClass)) != nil) {
            
            foundSuperView = superView
            
        }else{
            
            superView = superView!.superview;
            
        }
        
    }
    
    return foundSuperView!
}

}

/// 进度框 && The progress of the box
class cireview: UIView{
    
var value: CGFloat = 0 {
    didSet {
        self.setNeedsDisplay()
    }
}

var maximumValue: CGFloat = 0 {
    didSet { self.setNeedsDisplay() }
}

var contentLabel: UILabel!

override init(frame: CGRect) {
    
    super.init(frame: frame)
    
    self.isOpaque = false
    
    self.backgroundColor = progressViewBackColor
    
    contentLabel = UILabel.init(frame: CGRect(x: 10, y: 10, width: 30, height: 30))
    
    contentLabel.textAlignment = .center
    
    contentLabel.textColor = progressColor
    
    contentLabel.adjustsFontSizeToFitWidth = true
    
    contentLabel.text = "0.0%"
    
    self.addSubview(contentLabel)
}

override func draw(_ rect: CGRect) {
    super.draw(rect)
    
    let lineWidth: CGFloat = 5.0
    
    let radius = rect.width / 2.0 - lineWidth
    
    let centerX = rect.midX
    
    let centerY = rect.midY
    
    let startAngle = CGFloat(-90 * M_PI / 180)

    let endAngle = CGFloat(((self.value / self.maximumValue) * 360 - 90) ) * CGFloat(M_PI) / 180
    
    let context = UIGraphicsGetCurrentContext()
    
    context!.setStrokeColor(progressArticleColor)
    
    context!.setLineWidth(lineWidth)
    
//        CGContextAddArc(context!, centerX, centerY, radius, startAngle, endAngle, 0)
    
    context!.strokePath()
    
    context!.setStrokeColor(progressBackColor)
    
//        CGContextAddArc(context!, centerX, centerY, radius, startAngle, endAngle, 1)
    
    context!.strokePath()
    
    let content = Int(self.value * 100)
    
    self.contentLabel.text = String.init(content) + "%"

}

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

}


/// Tools 工具类 && The Tools Tools
import Foundation
// FIXME: comparison operators with optionals were removed           from the Swift Standard Libary.
// Consider refactoring the code to use the non-optional operators.
fileprivate func < <T : Comparable>(lhs: T?, rhs: T?) -> Bool {
  switch (lhs, rhs) {
  case let (l?, r?):
  return l < r
case (nil, _?):
  return true
default:
return false
}
}


///屏幕高度 && The screen height
let ScreenHeight = UIScreen.main.bounds.size.height

///屏幕宽度 && The width of the screen
let ScreenWidth = UIScreen.main.bounds.size.width

///图片与图片之间的间隔 && The interval between images and pictures
let imageInterval = CGFloat(20)

///视图的背景颜色 && The background color of the view
let viewTheBackgroundColor = UIColor.black

/// 动画时间 && Animation time
let animationTime = 0.5

///  进度条字体颜色 The progress bar font color
let progressColor = UIColor.black

///  进度条 条的背景颜色 && The background color of the article the progress bar
let progressBackColor =  UIColor.darkGray.cgColor

///  进度条 条的颜色 && The progress bar of the color
let progressArticleColor =  UIColor.white.cgColor

/// 进度条View背景色 && The progress bar View the background color
let progressViewBackColor = UIColor.clear

/// 默认背景图片颜色获取和设置 && The default color to get and        set background image
func getColorImageWithColor() ->(UIImage){

let color = UIColor.brown

let rect = CGRect(x: 0, y: 0, width: ScreenWidth, height: 200)

UIGraphicsBeginImageContext(rect.size);

let context = UIGraphicsGetCurrentContext();

context!.setFillColor(color.cgColor);

context!.fill(rect);

let img = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return img!;

}

调用方法

    let bview = HJImageBrowser()
    
    bview.delegate = self
    
    bview.bottomView = self.collectionView
    
    bview.indexImage = indexPath.row
    
    bview.defaultImage = getColorImageWithColor()
    
    bview.arrayImage = dataArray
    
    bview.show()

实现代理方法

func getTheThumbnailImage(_ indexRow: Int) -> UIImage {
    
    let indexPath = IndexPath.init(row: indexRow, section: 0)
    
    let cell = self.collectionView.cellForItem(at: indexPath)
    
    if cell == nil {
        
        return getColorImageWithColor()
        
    }
    
    var imagV = UIImageView()
    
    for temp in (cell?.subviews)! {
        
        if temp.isKind(of: UIImageView.classForCoder()) {
            
            imagV = temp as! UIImageView
            
        }
        
    }
    
    return imagV.image!
}

demo 地址

相关文章

网友评论

    本文标题:Swift -- 图片浏览器

    本文链接:https://www.haomeiwen.com/subject/ufacwttx.html