Swift封裝圖片瀏覽,多張圖片瀏覽,縮放,gif圖片的播放
阿新 • • 發佈:2019-01-01
封裝了一個圖片瀏覽器,實現了圖片的瀏覽,縮放,支援多張圖片的瀏覽縮放,儲存到相簿等功能
實現功能
1.圖片瀏覽,根據圖片的大小適應,瀏覽長圖
2.多張圖片左右滑動瀏覽
3.圖片的縮放
4.播放gif圖片
實現技術
1.使用UICollectionView作為圖片瀏覽的承載控制器 2.自定義cell顯示圖片, 3.使用UIScrollerView作為最底層檢視 4.使用UIImageView顯示圖片 5.使用Kingfisher載入網路圖片 6.使用UIImageWriteToSavedPhotosAlbum儲存圖片到相簿 7.使用SVProgressHUD作為儲存圖片成功的提示 8.使用snapkit作為layout的佈局約束
為什麼在cell中要使用UIScrollerView
1.顯示長圖片,可以上下滑動瀏覽圖片
2.使用UIScrollerView的代理方法實現圖片的縮放功能,
3.使用UIScrollerView的代理方法實現監聽圖片縮放完成後的居中操作
效果演示
使用方法
///index為當前點選了圖片陣列中的第幾張圖片,Urls為圖片Url地址陣列
**Urls必須傳入為https或者http的圖片地址陣列,**
let vc = PictureVisitControl(index: index.row, Urls: Urls as! [URL])
present(vc, animated: true , completion: nil)
原始碼
import UIKit
import SVProgressHUD
class PictureVisitControl: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
}
var currentIndex:Int?
var pictureUrls:[URL]?
init(index:Int,Urls:[URL]) {
//先初始化本類屬性,在初始化父類
currentIndex = index
pictureUrls = Urls
super.init (nibName: nil, bundle: nil)
setUpUI()
view.backgroundColor = .white
}
private func setUpUI(){
view.addSubview(collectionView)
view.addSubview(closebtn)
view.addSubview(SaveBtn)
//設定資料來源
collectionView.dataSource = self;
collectionView.register(PictureVisitControlCell.self, forCellWithReuseIdentifier: "item")
setlayoutContains()
}
private func setlayoutContains(){
closebtn.snp.makeConstraints { (make) in
make.bottom.equalTo(self.view.snp.bottom).offset(-30)
make.left.equalTo(20)
make.width.equalTo(100)
make.height.equalTo(35)
}
SaveBtn.snp.makeConstraints { (make) in
make.bottom.equalTo(self.view.snp.bottom).offset(-30)
make.right.equalTo(self.view.snp.right).offset(-20)
make.width.equalTo(100)
make.height.equalTo(35)
}
collectionView.snp.makeConstraints { (make) in
make.top.left.bottom.right.equalTo(0)
}
}
@objc private func closeAction(){
dismiss(animated: true, completion: nil)
}
@objc private func SaveAction(){
let index = collectionView.indexPathsForVisibleItems.last!
let cell:PictureVisitControlCell = collectionView.cellForItem(at: index) as! PictureVisitControlCell
//儲存圖片
let img = cell.IMg.image
UIImageWriteToSavedPhotosAlbum(img!, self, #selector(image(image:didFinishSavingWithError:contextInfo:)), nil)
// - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;
}
@objc func image(image:UIImage,didFinishSavingWithError error:NSError?,contextInfo:AnyObject){
if error != nil {
SVProgressHUD.showError(withStatus: "儲存失敗")
}else
{
SVProgressHUD.showSuccess(withStatus: "儲存成功")
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private lazy var collectionView:UICollectionView = UICollectionView(frame:CGRect.zero, collectionViewLayout: PicturePrepareLayout())
private lazy var closebtn:UIButton = {
let btn = UIButton()
btn.setTitle("關閉", for: .normal)
btn.setTitleColor(.white, for: .normal)
btn.backgroundColor = UIColor.darkGray
btn.addTarget(self, action: #selector(closeAction), for: UIControlEvents.touchUpInside)
return btn
}()
private lazy var SaveBtn:UIButton = {
let btn = UIButton()
btn.setTitle("儲存", for: .normal)
btn.setTitleColor(.white, for: .normal)
btn.backgroundColor = UIColor.darkGray
btn.addTarget(self, action: #selector(SaveAction), for: UIControlEvents.touchUpInside)
return btn
}()
}
class PicturePrepareLayout:UICollectionViewFlowLayout {
override func prepare() {
itemSize = UIScreen.main.bounds.size
minimumLineSpacing = 0
minimumInteritemSpacing = 0
scrollDirection = UICollectionViewScrollDirection.horizontal
collectionView?.showsHorizontalScrollIndicator = false
collectionView?.isPagingEnabled = true
collectionView?.bounces = false;
}
}
extension PictureVisitControl:UICollectionViewDataSource,PictureVisitControlCellDelegate{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return pictureUrls?.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "item", for: indexPath) as! PictureVisitControlCell
cell.PictureVisitDelegate = self
cell.imageURL = pictureUrls?[indexPath.row]
return cell
}
func TapPhotoCloseDismiss(cell: PictureVisitControlCell) {
dismiss(animated: true, completion: nil)
}
}
PictureVisitControlCell的實現
import UIKit
import Kingfisher
protocol PictureVisitControlCellDelegate:NSObjectProtocol {
func TapPhotoCloseDismiss(cell:PictureVisitControlCell)
}
class PictureVisitControlCell: UICollectionViewCell {
weak var PictureVisitDelegate : PictureVisitControlCellDelegate?
var imageURL:URL?{
didSet{
reSetPosion()
IMg.kf.setImage(with: imageURL, placeholder:nil, options: nil, progressBlock: nil) { (image, error, _, _) in
//調整圖片位置
self.setImgViewPosion()
}
}
}
//調整圖片顯示的位置
private func setImgViewPosion(){
let size = self.disPlaySize(image: IMg.image!)
if size.height < ScreenHeight{
self.IMg.frame = CGRect.init(origin: CGPoint.zero, size: size)
//處理居中顯示
let y = (UIScreen.main.bounds.height - size.height) * 0.5
self.scrollView.contentInset = UIEdgeInsets(top: y, left: 0, bottom: -y, right: 0)
}else
{
self.IMg.frame = CGRect.init(origin: CGPoint.zero, size: size)
scrollView.contentSize = size
}
}
//重置scrollerView和imageView的屬性
private func reSetPosion(){
scrollView.contentInset = UIEdgeInsets.zero
scrollView.contentOffset = CGPoint.zero
scrollView.contentSize = CGSize.zero
//重置imageview的屬性
IMg.transform = CGAffineTransform.identity
}
private func disPlaySize(image:UIImage)->CGSize{
let scale = image.size.height / image.size.width
let width = UIScreen.main.bounds.width
let height = width * scale
return CGSize(width: width, height: height)
}
override init(frame: CGRect) {
super.init(frame: frame)
SetUpUI()
}
private func SetUpUI(){
contentView.addSubview(scrollView)
scrollView.addSubview(IMg)
//添加布局
scrollView.frame = UIScreen.main.bounds
scrollView.delegate = self
scrollView.maximumZoomScale = 2.0
scrollView.minimumZoomScale = 0.5
IMg.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(close))
IMg.addGestureRecognizer(tap)
}
/// 點選圖片關閉控制器
@objc private func close(){
PictureVisitDelegate?.TapPhotoCloseDismiss(cell: self)
}
private lazy var scrollView:UIScrollView = UIScrollView()
lazy var IMg:UIImageView = UIImageView()
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension PictureVisitControlCell:UIScrollViewDelegate{
//告訴系統需要縮放的view
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return IMg;
}
//重新調整配圖的位置
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
var offSetX = (UIScreen.main.bounds.width - (view?.frame.width)!) * 0.5
var offSetY = (UIScreen.main.bounds.height - (view?.frame.height)!) * 0.5
offSetX = offSetX < 0 ? 0: offSetX
offSetY = offSetY < 0 ? 0: offSetY
scrollView.contentInset = UIEdgeInsets(top: offSetY, left: offSetX, bottom: offSetY, right: offSetX)
}
}