swift 面向協(xié)議點(diǎn)擊顯示大圖--帶縮放功能

直接上代碼

首先定義一個顯示大圖的協(xié)議

protocol ShowImageProtocol {}

然后添加協(xié)議extension---
1.第一個是不帶動畫的直接模態(tài)顯示出大圖控制器界面
2.第二個是帶動畫的協(xié)議擴(kuò)展诊杆,類似于微信朋友圈顯示大圖妓灌,但是此時需要顯示的圖片所在的控制器準(zhǔn)守UIViewControllerTransitioningDelegate協(xié)議;并且為了使動畫開始frame是從所點(diǎn)擊的imageView展開顯示的率触,所以需要外界傳入一個imageView终议,用來獲取初始frame

extension ShowImageProtocol where Self: UIViewController {
    /**
     不帶動畫的顯示大圖
     
     - parameter dataSource:   數(shù)據(jù)源
     - parameter currentIndex: 第幾個
     */
    func showImages(with dataSource: [String], currentIndex: Int) {
        
        guard dataSource.count - 1 >= currentIndex else {
            return
        }
        let vc = ShowImagesController(dataSource: dataSource, currentIndex: currentIndex)
        vc.modalTransitionStyle = .CrossDissolve
        presentViewController(vc, animated: true, completion: nil)
    }
}

extension ShowImageProtocol where Self: UIViewController, Self: UIViewControllerTransitioningDelegate {
    /**
     帶動畫的顯示大圖---必須遵循UIViewControllerTransitioningDelegate
     
     - parameter dataSource:   數(shù)據(jù)源
     - parameter currentIndex: 第幾個
     - parameter imageView:    要顯示的imageView,主要是為了獲取frame
     */
    func showImages(with dataSource: [String], currentIndex: Int, delegate: ModalAnimationDelegate?) {
        guard let delegate = delegate else {
            fatalError("does not have delegate")
        }
        guard dataSource.count - 1 >= currentIndex else {
            return
        }
        let vc = ShowImagesController(dataSource: dataSource, currentIndex: currentIndex)
        vc.transitioningDelegate = delegate
        vc.modalPresentationStyle = .Custom
        presentViewController(vc, animated: true, completion: nil)
    }
}

外界調(diào)用時,需要首先準(zhǔn)守ShowImageProtocol協(xié)議
1.不帶動畫的直接調(diào)用第一個方法即可

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        guard let cell = collectionView.cellForItemAtIndexPath(indexPath) as? PicCollectionViewCell else { return }
     showImages(with: viewModel.dataSource, currentIndex: indexPath.item)
}

2.帶動畫的還需要準(zhǔn)守UIViewControllerTransitioningDelegate協(xié)議穴张。同時控制器設(shè)置屬性

private var delegate: ModalAnimationDelegate?

然后细燎,在需要顯示大圖的地方,先把delegate置為nil陆馁,再創(chuàng)建delegate---因?yàn)榇朔椒ㄐ枰粋€imageView屬性找颓,所以最好把屬性設(shè)置為可選,然后先置為nil叮贩,再創(chuàng)建delegate

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        guard let cell = collectionView.cellForItemAtIndexPath(indexPath) as? PicCollectionViewCell else { return }
        delegate = nil
        delegate = ModalAnimationDelegate(originalView: cell.picV)
            showImages(with: viewModel.dataSource, currentIndex: indexPath.item, delegate: delegate)
    }

同時

在這里有一個地方需要特別注意的---那就是顯示大圖的控制器collectionviewcell之間有間距的設(shè)置方法:
把collectionView和cell的寬設(shè)置為屏寬加固定的間距并且cell之間間距為0击狮,同時開始開啟pagingEnabled = true,當(dāng)然cell上的scrollview需距離到contentView右側(cè)邊距為我們設(shè)置的間距大小益老。

/// 滾動時彪蓬,cell所顯示的間距大小
private let cellMargin: CGFloat = 20
//這個是顯示大圖的控制器vc的初始化類方法
convenience init(dataSource: [String], currentIndex: Int) {
        let layout = UICollectionViewFlowLayout()
        layout.itemSize = CGSize(width: UIScreen.mainScreen().bounds.width + cellMargin, height: UIScreen.mainScreen().bounds.height)
        layout.minimumLineSpacing = 0
        layout.minimumInteritemSpacing = 0
        layout.scrollDirection = .Horizontal
        self.init(collectionViewLayout: layout)
        self.dataSource = dataSource
        self.currentIndex = currentIndex
    }

然后在viewDidLoad()里面設(shè)置collectionview的frame

collectionView?.frame = UIScreen.mainScreen().bounds
        collectionView?.frame.size.width = UIScreen.mainScreen().bounds.size.width + cellMargin
        
        collectionView?.alwaysBounceHorizontal = true
        collectionView?.pagingEnabled = true
        collectionView?.showsHorizontalScrollIndicator = false
        
        collectionView?.registerClass(PicuterCell.self, forCellWithReuseIdentifier: reuseIdentifier)
        collectionView?.scrollToItemAtIndexPath(NSIndexPath(forItem: currentIndex, inSection: 0), atScrollPosition: .Left, animated: false)

同時為了大圖需要帶有縮放功能,我們需要在cell上放置一個scrollview捺萌,然后scrollview上再放置UIimageview档冬。這里沒有使用第三方布局,而是使用代碼約束控件

private func setUpUI() {
        contentView.addSubview(scrollView)
        // 關(guān)閉autoresizing 不關(guān)閉否則程序崩潰
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        let topConstraint = NSLayoutConstraint(item: scrollView, attribute: .Top, relatedBy: .Equal, toItem: contentView, attribute: .Top, multiplier: 1, constant: 0)
        let leftConstraint = NSLayoutConstraint(item: scrollView, attribute: .Left, relatedBy: .Equal, toItem: contentView, attribute: .Left, multiplier: 1, constant: 0)
        let bottomConstraint = NSLayoutConstraint(item: scrollView, attribute: .Bottom, relatedBy: .Equal, toItem: contentView, attribute: .Bottom, multiplier: 1, constant: 0)
        let rightConstraint = NSLayoutConstraint(item: scrollView, attribute: .Right, relatedBy: .Equal, toItem: contentView, attribute: .Right, multiplier: 1, constant: -cellMargin)
        contentView.addConstraints([topConstraint, leftConstraint, bottomConstraint, rightConstraint])

        scrollView.minimumZoomScale = 1
        scrollView.maximumZoomScale = 3
        scrollView.delegate = self
        
        scrollView.addSubview(picV)
        picV.contentMode = .ScaleAspectFit
        
        picV.translatesAutoresizingMaskIntoConstraints = false
        let centerXCon = NSLayoutConstraint(item: picV, attribute: .CenterX, relatedBy: .Equal, toItem: scrollView, attribute: .CenterX, multiplier: 1, constant: 0)
        let centerYCon = NSLayoutConstraint(item: picV, attribute: .CenterY, relatedBy: .Equal, toItem: scrollView, attribute: .CenterY, multiplier: 1, constant: 0)
        
        let leftCon = NSLayoutConstraint(item: picV, attribute: .Left, relatedBy: .Equal, toItem: scrollView, attribute: .Left, multiplier: 1, constant: 0)
        let rightCon = NSLayoutConstraint(item: picV, attribute: .Right, relatedBy: .Equal, toItem: scrollView, attribute: .Right, multiplier: 1, constant: 0)
        
        let heightCon = NSLayoutConstraint(item: picV, attribute: .Height, relatedBy: .Equal, toItem: scrollView, attribute: .Height, multiplier: 1, constant: 0)

        scrollView.addConstraints([heightCon, leftCon, rightCon, centerYCon, centerXCon])
        
        let tap = UITapGestureRecognizer(target: self, action: #selector(tapAction))
        picV.userInteractionEnabled = true
        picV.addGestureRecognizer(tap)
    }

然后桃纯,我們需要在滑動到下一個cell時酷誓,使上一個cell里面的圖像復(fù)原,這里需要用到collectionview的代理方法--cell滑動消失時觸發(fā)

override func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
        guard let cell = cell as? PicuterCell else {
            return
        }
        cell.reset()
    }

//這個是cell里的方法态坦,設(shè)置scrollview的縮放為1.0
func reset() {
        scrollView.setZoomScale(1.0, animated: false)
    }

demo地址:https://github.com/guijie20140501/ShowBigImage.git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盐数,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子伞梯,更是在濱河造成了極大的恐慌玫氢,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谜诫,死亡現(xiàn)場離奇詭異漾峡,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)喻旷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進(jìn)店門生逸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人且预,你說我怎么就攤上這事牺陶。” “怎么了辣之?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長皱炉。 經(jīng)常有香客問我怀估,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任多搀,我火速辦了婚禮歧蕉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘康铭。我一直安慰自己惯退,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布从藤。 她就那樣靜靜地躺著催跪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪夷野。 梳的紋絲不亂的頭發(fā)上懊蒸,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天舍咖,我揣著相機(jī)與錄音予弧,去河邊找鬼事镣。 笑死另玖,一個胖子當(dāng)著我的面吹牛冒滩,可吹牛的內(nèi)容都是我干的谐算。 我是一名探鬼主播沈撞,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼蜈垮,長吁一口氣:“原來是場噩夢啊……” “哼灌曙!你這毒婦竟也來了菊碟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤平匈,失蹤者是張志新(化名)和其女友劉穎框沟,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體增炭,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡忍燥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了隙姿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片梅垄。...
    茶點(diǎn)故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖输玷,靈堂內(nèi)的尸體忽然破棺而出队丝,到底是詐尸還是另有隱情,我是刑警寧澤欲鹏,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布机久,位于F島的核電站,受9級特大地震影響赔嚎,放射性物質(zhì)發(fā)生泄漏膘盖。R本人自食惡果不足惜胧弛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望侠畔。 院中可真熱鬧结缚,春花似錦、人聲如沸软棺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽喘落。三九已至茵宪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間揖盘,已是汗流浹背眉厨。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留兽狭,地道東北人憾股。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像箕慧,于是被迫代替她去往敵國和親服球。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫颠焦、插件斩熊、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,058評論 4 62
  • 阿明和我是初中同學(xué)粉渠。上學(xué)時他學(xué)習(xí)非常努力認(rèn)真,每次考試穩(wěn)坐班里的第一把交椅圾另,是個十足的學(xué)霸霸株。 這兩日他到我的城市出...
    商小茉閱讀 1,279評論 0 5
  • 接受顛覆 現(xiàn)在出來一些事情會顛復(fù)我們的一些正常思路,在貌似不可思議的思維后他就擺在你面前,讓你接受他是如而且他...
    易凡風(fēng)順閱讀 216評論 0 0
  • 小時候媽媽常說,女孩子要學(xué)會笑集乔。大概看不過我經(jīng)常和弟弟生氣吧去件。還是個青少年時,有好多理由開心和不開心扰路,說來就來的情...
    買基金的Gargamel閱讀 175評論 0 0