自定義彈出視圖

工作中經(jīng)常會遇到彈出視圖的需求芭逝,通常還會要求有一些動效塌碌,之前使用OC寫代碼的時候,使用的是STModal旬盯,現(xiàn)在使用Swift台妆,就決定自己來寫一個。目前僅僅是寫了一個彈出視圖的控制器胖翰,還非常的簡陋,后期再來添加自定義Alert視圖等功能萨咳。

很多地方參考了STModal搂漠,當然也做了一些修改和優(yōu)化。

STModal 自定義彈出視圖-OC

GJModal 自定義彈出視圖-Swift

兩種實現(xiàn)方式某弦,核心代碼是一樣的桐汤,不同點在于:

  1. GJModal定義為單例,這種方式適用于靶壮,所有的彈出視圖的彈出方式都是一樣的怔毛。
  2. GJModalWindow定義為單例,這種方式適用于腾降,彈出視圖有多種彈出方式拣度。

效果圖:

效果圖

使用方式

  • 第一種實現(xiàn)方式
    GJModal.modal.isHideWhenTouchOutside = true
    GJModal.modal.show(contentView: view, animated: true)
  • 第二種實現(xiàn)方式
    let modal = GJModal.init(isHideWhenTouchOutside: false)
    modal.show(contentView: view, animated: true)

核心代碼

初始化

    init(isHideWhenTouchOutside: Bool) {
        containerView.addSubview(bgView)
        self.isHideWhenTouchOutside = isHideWhenTouchOutside
        if isHideWhenTouchOutside {
            let tap = UITapGestureRecognizer(target: self, action: #selector(backgroundTaped))
            bgView.addGestureRecognizer(tap)
        }
        
    }

彈出視圖

    func show(contentView: UIView, animated: Bool) {
        self.contentView = contentView
        containerView.addSubview(self.contentView)
        self.contentView.center = containerView.center
        
        window.modalsStack.append(self)
        window.addSubview(containerView)
        
        if isShowBgView {
            window.isHidden = false
            UIView.animate(withDuration: bgViewShowDuration, animations: {
                self.bgView.backgroundColor = UIColor.black
                self.bgView.alpha = self.bgViewAlpha
            })
        }
        isShowAnimated = animated
        showAnimation()
    }
    
    private func showAnimation() {
        if isShowAnimated {
            let d1 = 0.2
            let d2 = 0.15
            
            let animation2 = CABasicAnimation(keyPath: "transform")
            animation2.autoreverses = true
            animation2.duration = d1
            animation2.beginTime = 0
            animation2.fromValue = NSValue(caTransform3D: CATransform3DMakeScale(0.4, 0.4, 1))
            animation2.toValue = NSValue(caTransform3D: CATransform3DMakeScale(1.2, 1.2, 1))
            
            let animation3 = CABasicAnimation(keyPath: "transform")
            animation3.autoreverses = true
            animation3.duration = d2
            animation3.beginTime = d1
            animation3.fromValue = NSValue(caTransform3D: CATransform3DMakeScale(1.2, 1.2, 1))
            animation3.toValue = NSValue(caTransform3D: CATransform3DMakeScale(1, 1, 1))
            
            let group = CAAnimationGroup()
            group.duration = d2+d1
            group.animations = [animation2,animation3]
            self.contentView.layer.add(group, forKey: nil)
            
            UIView.animate(withDuration: bgViewShowDuration, animations: {
                self.contentView.alpha = 1
            })
            
        } else {
            UIView.animate(withDuration: bgViewShowDuration, animations: {
                self.contentView.alpha = 1
            })
        }
    }

移除視圖

    func hide(animated: Bool) -> Void {
        if contentView != nil {
            isHideAnimated = animated
            hideAnimation()
        }
    }
    private func hideAnimation() {
        if isHideAnimated {
            let d1 = 0.2
            let d2 = 0.15
            UIView.animate(withDuration: d1, animations: {
                self.contentView.transform = CGAffineTransform.init(scaleX: 1.2, y: 1.2)
            }) { (finished) in
                UIView.animate(withDuration: d2, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
                    self.contentView.alpha = 0
                    self.contentView.transform = CGAffineTransform.init(scaleX: 0.2, y: 0.2)
                }, completion: { (finished) in
                    self.window.isHidden = true
                    self.containerView.removeFromSuperview()
                    self.window.modalsStack.removeAll()
                })
            }
        } else {
            UIView.animate(withDuration: bgViewShowDuration, animations: {
                self.contentView.alpha = 0
                self.containerView.removeFromSuperview()
                self.window.modalsStack.removeAll()
            })
        }
        
        if isShowBgView {
            UIView.animate(withDuration: bgViewShowDuration, animations: {
                self.bgView.backgroundColor = UIColor.clear
                self.bgView.alpha = 0
            })
        }
    }

遇到的問題

  1. 把視圖添加到window上以后,視圖的點擊效果無法觸發(fā)螃壤。自己感覺可能是因為點擊手勢的Targetwindow之間不存在引用關系抗果,然后就在GJModalWindow里加了一個modalsStack的屬性,用來添加GJModal奸晴。不知道具體原因是不是我想的這個冤馏,最終結果是實現(xiàn)了想要的點擊效果。
  2. 在做視圖彈出動畫的時候寄啼,本來想簡單的使用Viewtransform屬性來實現(xiàn)逮光,但是發(fā)現(xiàn)如果你要彈出的視圖是使用Autolayout來布局的話代箭,彈出后會造成布局混亂的問題,所以最后采用了CAAnimation動畫涕刚。
  3. 在使用CAAnimation動畫的時候嗡综,發(fā)現(xiàn)動畫總是同時觸發(fā),不是我想要的一個動畫結束后再執(zhí)行另一個動畫杜漠。然后采用了CAAnimationGroup來實現(xiàn)動畫組极景,通過設置AnimationbeginTime來控制動畫的執(zhí)行。

版本記錄

  • V1.0 僅實現(xiàn)了彈出視圖控制器驾茴。 2017.7.24
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末戴陡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子沟涨,更是在濱河造成了極大的恐慌恤批,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件裹赴,死亡現(xiàn)場離奇詭異喜庞,居然都是意外死亡,警方通過查閱死者的電腦和手機棋返,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門延都,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人睛竣,你說我怎么就攤上這事晰房。” “怎么了射沟?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵殊者,是天一觀的道長。 經(jīng)常有香客問我验夯,道長猖吴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任挥转,我火速辦了婚禮海蔽,結果婚禮上,老公的妹妹穿的比我還像新娘绑谣。我一直安慰自己党窜,他們只是感情好,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布借宵。 她就那樣靜靜地躺著幌衣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪暇务。 梳的紋絲不亂的頭發(fā)上泼掠,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天怔软,我揣著相機與錄音垦细,去河邊找鬼择镇。 笑死,一個胖子當著我的面吹牛括改,可吹牛的內容都是我干的腻豌。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼嘱能,長吁一口氣:“原來是場噩夢啊……” “哼吝梅!你這毒婦竟也來了?” 一聲冷哼從身側響起惹骂,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤苏携,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后对粪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體右冻,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年著拭,在試婚紗的時候發(fā)現(xiàn)自己被綠了纱扭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡儡遮,死狀恐怖乳蛾,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情鄙币,我是刑警寧澤肃叶,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站十嘿,受9級特大地震影響被环,放射性物質發(fā)生泄漏。R本人自食惡果不足惜详幽,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一筛欢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧唇聘,春花似錦版姑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至宪肖,卻和暖如春表制,著一層夾襖步出監(jiān)牢的瞬間健爬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工么介, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留娜遵,地道東北人。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓壤短,卻偏偏與公主長得像设拟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子久脯,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內容

  • 翻譯自“View Controller Programming Guide for iOS”纳胧。 1 彈出視圖控制器...
    lakerszhy閱讀 3,481評論 2 20
  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫、插件帘撰、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,059評論 4 62
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,756評論 25 707
  • 30歲來臨之際所感受的焦慮 恐怕也是對當下狀態(tài)不滿意的表現(xiàn) 于是 我專升本 健身 從堅持21天背單詞開始 我知道我...
    露天電影院閱讀 109評論 0 0
  • 【它總是悄悄潛入我的情緒中跑慕,蓄勢待發(fā)】 我又被它控制了。 這一次只是因為媽媽不經(jīng)意的一句話摧找。 我告訴媽媽我想養(yǎng)一只...
    姚伊益閱讀 371評論 0 0