swift微博第9天(自定義微博首頁(yè)的菜單)

效果圖: 純代碼

自定義微博首頁(yè)的菜單

1.自定義繼承于UIPresentationController的控制器

import UIKit

class PopoverPresentationController: UIPresentationController{

// 定義一個(gè)presentFrame 來(lái)動(dòng)態(tài)改變展示視圖的frame
var presentFrame = CGRect.zero

/**
 實(shí)例化負(fù)責(zé)轉(zhuǎn)場(chǎng)的控制器
 
 :param: presentedViewController  被展現(xiàn)的控制器
 :param: presentingViewController 發(fā)起轉(zhuǎn)場(chǎng)的控制器, xocde6是nil, xocde7是野指針
 
 :returns: 負(fù)責(zé)轉(zhuǎn)場(chǎng)的控制器
 */
override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {
    
    super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
}

/*
 即將布局容器視圖上得子視圖時(shí)調(diào)用
 containerView 容器視圖, 放置展現(xiàn)出來(lái)的視圖
 presentedView 被展現(xiàn)的視圖
 */
override func containerViewWillLayoutSubviews() {
    
    // 1.添加遮蓋
    containerView?.addSubview(coverView)
    containerView?.insertSubview(coverView, at: 0)
    coverView.frame = (containerView?.frame)!
    
    // 把菜單的frame做活
    if presentFrame == CGRect.zero {
        
        /*
         *  這個(gè)是默認(rèn)菜單高度
         */
        // 2.調(diào)整被展示視圖的大小
        presentedView?.frame = CGRect(x:JKscreenW/2.0-100,y:56,width:200,height:200)
        // 2.1.被展示視圖上面的子視圖大小的調(diào)整
        // 背景圖片
        presentedView?.subviews[0].frame =  CGRect(x:0,y:0,width:200,height:200)
        // tableview
        presentedView?.subviews[1].frame = CGRect(x:20,y:20,width:presentedView!.width-40,height:presentedView!.height-40)
        
    }else{
    
        /*
         *  這個(gè)是外面自定義的菜單高度
         */
        
        // 2.調(diào)整被展示視圖的大小
        presentedView?.frame = presentFrame
        // 2.1.被展示視圖上面的子視圖大小的調(diào)整
        // 背景圖片
        presentedView?.subviews[0].frame =  CGRect(x:0,y:0,width:presentFrame.width,height:presentFrame.height)
        // tableview
        presentedView?.subviews[1].frame = CGRect(x:20,y:20,width:presentFrame.width-40,height:presentFrame.height-40)
    
    }
    
    
    
}

/**
 關(guān)閉彈窗
 */
func close(){
    
    presentedViewController.dismiss(animated: true, completion: nil)
}

// MARK: - 懶加載
lazy var coverView: UIView = {
    // 1.創(chuàng)建蒙版
    let view = UIView()
    view.backgroundColor = UIColor(white: 0.0, alpha: 0.2)
    // 2.注冊(cè)監(jiān)聽(tīng)
    let tap = UITapGestureRecognizer(target: self, action: #selector(PopoverPresentationController.close))
    view.addGestureRecognizer(tap)
    return view
}()

}

2.自定義一個(gè)管理動(dòng)畫(huà)的對(duì)象類PopoverAnimator繼承于NSObject,遵守UIViewControllerTransitioningDelegate,UIViewControllerAnimatedTransitioning協(xié)議

import UIKit

// 定義常量保存通知的名稱
   let JKPopoverAnimatorWillshow = "JKPopoverAnimatorWillshow"
   let JKPopoverAnimatorWilldismiss = "JKPopoverAnimatorWilldismiss"

/*
 * 負(fù)責(zé)轉(zhuǎn)場(chǎng)的類
 */
class PopoverAnimator: NSObject,UIViewControllerTransitioningDelegate,UIViewControllerAnimatedTransitioning{

// 記錄當(dāng)前菜單是否展開(kāi)
var isPresent: Bool = false

var presentFrame = CGRect.zero

// MARK: 只要實(shí)現(xiàn)了一下方法,那么系統(tǒng)自帶的默認(rèn)動(dòng)畫(huà)就沒(méi)有了莱革,所有東西都需要程序員自己來(lái)實(shí)現(xiàn)
// 實(shí)現(xiàn)代理方法峻堰,告訴系統(tǒng)誰(shuí)來(lái)負(fù)責(zé)轉(zhuǎn)場(chǎng)動(dòng)畫(huà)
// UIPopoverPresentationController ios8推出專門負(fù)責(zé)轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController?{
    
    let pc = PopoverPresentationController(presentedViewController: presented, presenting: presenting)
    // 傳frame,設(shè)置菜單的大小
    pc.presentFrame = presentFrame
    return pc
    
}
// 告訴系統(tǒng)誰(shuí)來(lái)負(fù)責(zé)Modal的展現(xiàn)動(dòng)畫(huà)
// presented  : 被展現(xiàn)的視圖
// presenting : 發(fā)起的視圖
// returns : 誰(shuí)來(lái)負(fù)責(zé)
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning?{
    
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: JKPopoverAnimatorWillshow), object: self)
    
    isPresent = true
    return self
}
// 告訴系統(tǒng)誰(shuí)來(lái)負(fù)責(zé)modal的消失動(dòng)畫(huà)
// dismissed 被關(guān)閉的視圖
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?{
    
    
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: JKPopoverAnimatorWilldismiss), object: self)
    isPresent = false
    return self
}

/*
 * UIViewControllerAnimatedTransitioning 下面的2個(gè)方法是這個(gè)協(xié)議產(chǎn)生的
 * 返回動(dòng)畫(huà)時(shí)長(zhǎng)
 * transitionContext : 上下文里面包含了所有需要的參數(shù)
 * returns: 動(dòng)畫(huà)時(shí)長(zhǎng)
 *
 */
public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
    
    return 0.5
}

/*
 * 告訴系統(tǒng)如何動(dòng)畫(huà),無(wú)論是展現(xiàn)還是
 *
 *
 */
public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    
    // 1.拿到展現(xiàn)的視圖
    // let toVc = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
    // let fromVc = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
    // 通過(guò)打印發(fā)現(xiàn)需要修改的是 toVc上面的view
    
    print(isPresent)
    
    if isPresent {
        
        
        let toView = transitionContext.view(forKey: UITransitionContextViewKey.to)
        // 注意: 一定要把視圖添加到view上
        transitionContext.containerView.addSubview(toView!)
        
        // 把 transform設(shè)置為 x:1.0,y: 0
        toView?.transform = CGAffineTransform(scaleX: 1.0, y: 0)
        // 設(shè)置錨點(diǎn)
        toView?.layer.anchorPoint = CGPoint(x:0.5, y: 0)
        
        //print(toView!.layer.anchorPoint)
        
        // 2.執(zhí)行動(dòng)畫(huà)
        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
            // 2.1.清空transform
            toView?.transform = CGAffineTransform.identity
            
        }) { (_) in
            
            // 2.2.動(dòng)畫(huà)執(zhí)行完畢盅视,一定要告訴系統(tǒng),如果不寫可能產(chǎn)生一些未知的錯(cuò)誤
            transitionContext.completeTransition(true)
        }
    }else{
        
        let fromView = transitionContext.view(forKey: UITransitionContextViewKey.from)
        
        // 2.執(zhí)行動(dòng)畫(huà)
        UIView.animate(withDuration: transitionDuration(using: transitionContext)-3, animations: {
            // 把 transform設(shè)置為 x:1.0,y: 0,由于CGFloat是不準(zhǔn)確的捐名,所以寫0.0是沒(méi)有動(dòng)畫(huà)的
            fromView?.transform = CGAffineTransform(scaleX: 1.0, y: 0.000001)
            
        }) { (_) in
            
            // 2.2.動(dòng)畫(huà)執(zhí)行完畢,一定要告訴系統(tǒng),如果不寫可能產(chǎn)生一些未知的錯(cuò)誤
            transitionContext.completeTransition(true)
        }
        
    }
    
  }
}

提醒動(dòng)畫(huà)執(zhí)行完畢闹击,一定要告訴系統(tǒng),如果不寫可能產(chǎn)生一些未知的錯(cuò)誤

 transitionContext.completeTransition(true)

3.動(dòng)畫(huà)實(shí)現(xiàn)的操作

    // 1.創(chuàng)建控制器對(duì)象
    let popoverViewController = PopoverViewController()
    // 2.設(shè)置轉(zhuǎn)場(chǎng)代理, 告訴系統(tǒng)誰(shuí)來(lái)負(fù)責(zé)轉(zhuǎn)場(chǎng) popoverAnimator: 是負(fù)責(zé)轉(zhuǎn)場(chǎng)的
    popoverViewController.transitioningDelegate = popoverAnimator
    // 3.設(shè)置轉(zhuǎn)場(chǎng)模式
    popoverViewController.modalPresentationStyle = UIModalPresentationStyle.custom
    present(popoverViewController, animated: true, completion: nil)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末镶蹋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子赏半,更是在濱河造成了極大的恐慌贺归,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件断箫,死亡現(xiàn)場(chǎng)離奇詭異拂酣,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)瑰枫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門踱葛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人光坝,你說(shuō)我怎么就攤上這事尸诽。” “怎么了盯另?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵性含,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我鸳惯,道長(zhǎng)商蕴,這世上最難降的妖魔是什么叠萍? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮绪商,結(jié)果婚禮上苛谷,老公的妹妹穿的比我還像新娘。我一直安慰自己格郁,他們只是感情好腹殿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著例书,像睡著了一般锣尉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上决采,一...
    開(kāi)封第一講書(shū)人閱讀 49,730評(píng)論 1 289
  • 那天自沧,我揣著相機(jī)與錄音,去河邊找鬼树瞭。 笑死拇厢,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的晒喷。 我是一名探鬼主播旺嬉,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼厨埋!你這毒婦竟也來(lái)了邪媳?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤荡陷,失蹤者是張志新(化名)和其女友劉穎雨效,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體废赞,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡徽龟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了唉地。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片据悔。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖耘沼,靈堂內(nèi)的尸體忽然破棺而出极颓,到底是詐尸還是另有隱情,我是刑警寧澤群嗤,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布菠隆,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏骇径。R本人自食惡果不足惜躯肌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望破衔。 院中可真熱鬧清女,春花似錦、人聲如沸晰筛。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)传惠。三九已至,卻和暖如春稻扬,著一層夾襖步出監(jiān)牢的瞬間卦方,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工泰佳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盼砍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓逝她,卻偏偏與公主長(zhǎng)得像浇坐,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子黔宛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

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