[技術(shù)文檔][技術(shù)中心][iOS部][114啦]全局菜單

菜單類型

1、首頁(yè)點(diǎn)擊更多按鈕彈起的菜單:FunctionView拣展。

2拜银、詳情頁(yè)點(diǎn)擊更多按鈕彈出的菜單:YYWMenuView

3阴汇、長(zhǎng)按webview中的鏈接彈出的菜單:YYWContextMenuHelp.swift数冬。

具體實(shí)現(xiàn)

  • FunctionView
    界面由nib搭建。view加在mainviewcontroller的view中搀庶。
    通過(guò)以下代碼來(lái)隱藏和顯示拐纱,有動(dòng)畫效果。
    部分按鈕在首頁(yè)時(shí)置灰不可點(diǎn)擊哥倔。
    該菜單的具體功能實(shí)現(xiàn)全由PageViewManager代理實(shí)現(xiàn)秸架。
func showFunctionBar(_ sender: UIButton)
    {
        guard self.functionView.isAnimatting == false else {
            return
        }
 
        self.mainViewController().view.bringSubview(toFront: self.functionView)
        
        let show = self.functionView.contentViewBottomAL.constant < 0
        self.functionView.isHidden = false
        self.functionView.isAnimatting = true
        if show
        {
            self.functionView.showAnimation()
            MobClick.event("homeToolBar_showMenu")
            let enabled = MainViewFacade.sharedInstance.isNotHomeWebPage()
            self.setUpButtonEnabled(functionView.addBookmarkButton, label: functionView.addBookmarkLabel, enabled: enabled)
            self.setUpButtonEnabled(functionView.shareBtn, label: functionView.shareLabel, enabled: enabled)
            self.setUpButtonEnabled(functionView.webSnapShotButton, label: functionView.webSnapShotLabel, enabled: enabled)
            self.setUpButtonEnabled(functionView.refreshBtn, label: functionView.refreshLabel, enabled: enabled)
        }
        else
        {
            self.functionView.hideAnimation()
        }
        self.functionView.contentView.layoutIfNeeded()
    }
  • ** YYWMenuView**
    該菜單是添加在window上的,因此全局調(diào)用一次show方法即可顯示出來(lái)咆蒿。
    該枚舉代表顯示的位置东抹,不同類型顯示不同的菜單項(xiàng)。
enum contentType: Int {
    case home = 0//
    case web
    case card
  }
switch ctype {
    case .home:
      self.menuItems = [
        YYWMenuItem(defaultType: .accountStatus),
        YYWMenuItem(defaultType: .bookmarkHistiry),
        YYWMenuItem(defaultType: .setting)
      ]
      break
    case .web:
      self.menuItems = [
        YYWMenuItem(defaultType: .accountStatus),
        YYWMenuItem(defaultType: .setting),
        YYWMenuItem(defaultType: .capture),
        YYWMenuItem(defaultType: .copyLink),
        YYWMenuItem(defaultType: .bookmarkHistiry),
        YYWMenuItem(defaultType: .addBookmark)
      ]
    case .card:
      self.menuItems = [
        YYWMenuItem(defaultType: .setFont),
        YYWMenuItem(defaultType: .feedback)
      ]
      break
    }

各菜單項(xiàng)對(duì)應(yīng)的title與image已經(jīng)預(yù)先定義好沃测。

init(defaultType: YYWMenuItemType) {
    type = defaultType
    switch type {
    case .accountStatus:
      title = NSLocalizedString("未登錄", comment: "")
      image = UIImage(named: "menu_visitor")!
    case .setting:
      title = NSLocalizedString("設(shè)置", comment: "")
      image = UIImage(named: "menu_setting")!
    case .darkModel:
      title = NSLocalizedString("夜間模式", comment: "")
      image = UIImage(named: "menu_night")!
    case .capture:
      title = NSLocalizedString("截圖", comment: "")
      image = UIImage(named: "menu_screenshot")!
    case .copyLink:
      title = NSLocalizedString("復(fù)制鏈接", comment: "")
      image = UIImage(named: "menu_copy")!
    case .cloudOof:
      title = NSLocalizedString("收藏到115", comment: "")
      image = UIImage(named: "menu_star")!
    case .bookmarkHistiry:
      title = NSLocalizedString("書簽/歷史", comment: "")
      image = UIImage(named: "menu_sc")!
    case .addBookmark:
      title = NSLocalizedString("添加書簽", comment: "")
      image = UIImage(named: "menu_bookmark")!
    case .setFont:
        title = NSLocalizedString("字體設(shè)置", comment: "")
        image = UIImage(named: "menu_font")!
    case .feedback:
        title = NSLocalizedString("意見(jiàn)反饋", comment: "")
        image = UIImage(named: "menu_edit")!
    case .itemType:
      assert(true, "itemType 不是默認(rèn)類型, 使用上面那個(gè)方法初始化缭黔。")
      title = ""
      image = UIImage()
    }
    super.init()
  }

因此初始化時(shí)指定type,顯示方向type蒂破,以及一個(gè)block馏谨。

init(archorView: UIView, contentType ctype: contentType, directionType dtype: directionType, action: @escaping YYWMenuAction)
// block定義 回調(diào)時(shí)返回點(diǎn)擊的type項(xiàng),根據(jù)該type處理事件附迷。
typealias YYWMenuAction = (YYWMenuItemType) -> Void
  • YYWContextMenuHelp
    該彈層使用系統(tǒng)自帶的UIAlertController實(shí)現(xiàn)惧互。
    根據(jù)以下方法獲取的webview元素決定顯示哪些彈層哎媚。
userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)

YYWContextMenuHelp.Elements(link: linkURL, image: imageURL, imageUrls: self.allImagesUrl, linkText: linkText)

創(chuàng)建代碼

func contextMenuHelper(_ elements: Elements,  cookie:String?, gestureRecognizer: UILongPressGestureRecognizer) {
        // locationInView can return (0, 0) when the long press is triggered in an invalid page
        // state (e.g., long pressing a link before the document changes, then releasing after a
        // different page loads).
        guard let navigationController = UIApplication.shared.delegate?.window??.rootViewController as? UINavigationController else { return }
        guard let mainViewController = navigationController.viewControllers.first as? MainViewController else { return }
        let view = MainViewFacade.sharedInstance.currentPageView()
        let touchPoint = view.tabWebView!.gestureRecognizer.location(in: view)
        guard touchPoint != CGPoint.zero else { return }
        
        let touchSize = CGSize(width: 0, height: 16)
        
        let actionSheetController = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertControllerStyle.actionSheet)
        var dialogTitle: String?
        
        if let url = elements.link, let imageUrl = elements.image {//長(zhǎng)按鏈接與圖片
            dialogTitle = url.absoluteString
            if dialogTitle?.hasPrefix("javascript:") == true {
                return
            }
            if dialogTitle?.characters.count > 0{
                if !view.isPushPageView {
                    actionSheetController.addAction(openNewTabAction(url, mainViewController))
                }
                actionSheetController.addAction(copyAction(url))
                actionSheetController.addAction(shareAction(url.absoluteString,elements.linkText ?? ""))
                actionSheetController.addAction(saveImageAction(imageUrl, cookie ?? ""))
                actionSheetController.addAction(shareImageAction(imageUrl, cookie ?? ""))
                actionSheetController.addAction(browserImageAction(imageUrl, elements, cookie ?? "", mainViewController))
//                if let _ = UserDefaults.standard.object(forKey: "defaults_user_authdata"), !imageUrl.absoluteString.hasPrefix("data:image/") {
//                    actionSheetController.addAction(cloudImageAction(imageUrl))
//                }
            }
            
        } else if let url = elements.link {///長(zhǎng)按鏈接
            dialogTitle = url.absoluteString
            if dialogTitle?.hasPrefix("javascript:") == true {
                return
            }
            
            if dialogTitle?.characters.count > 0{
//                actionSheetController.addAction(openNewTabAction(url, mainViewController))
                if !view.isPushPageView {
                    if (yywFunctionMatch != "" &&  url.absoluteString.hasPrefix(yywFunctionMatch) == true)
                       {
                            var originalString = url.absoluteString
                            let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
                            originalString = "http://115.com/lx?mag="
                            originalString = originalString + (escapedString ?? "")
                            if let strUrl = URL(string: originalString){
                                actionSheetController.addAction(openNewTabAction(strUrl, mainViewController))
                            }
                    } else {
                        actionSheetController.addAction(openNewTabAction(url, mainViewController))
                    }
                }
                actionSheetController.addAction(copyAction(url))
                actionSheetController.addAction(copyLinkTextAction(elements.linkText ?? ""))
                actionSheetController.addAction(shareAction(url.absoluteString,elements.linkText ?? ""))
            }
        } else if let imageUrl = elements.image {//長(zhǎng)按圖片
            if dialogTitle == nil {
                dialogTitle = imageUrl.absoluteString
            }
            dialogTitle = ""
            actionSheetController.addAction(browserImageAction(imageUrl, elements, cookie ?? "", mainViewController))
            actionSheetController.addAction(saveImageAction(imageUrl, cookie ?? ""))
            actionSheetController.addAction(shareImageAction(imageUrl, cookie ?? ""))
//            if let _ = UserDefaults.standard.object(forKey: "defaults_user_authdata"), !imageUrl.absoluteString.hasPrefix("data:image/") {
//                actionSheetController.addAction(cloudImageAction(imageUrl))
//            }
        }
        
        // If we're showing an arrow popup, set the anchor to the long press location.
        if let popoverPresentationController = actionSheetController.popoverPresentationController {
            popoverPresentationController.delegate = self
            popoverPresentationController.sourceView = view
            popoverPresentationController.sourceRect = CGRect(origin: touchPoint, size: touchSize)
            popoverPresentationController.permittedArrowDirections = .any
        }
        
        if dialogTitle != nil && dialogTitle?.characters.count > 0 {
            actionSheetController.title = dialogTitle?.ellipsize(maxLength: 120)
        }
        let cancelAction = UIAlertAction(title: "取消", style: UIAlertActionStyle.cancel, handler: nil).changeAlertActionTextColor()
        
        actionSheetController.addAction(cancelAction)
        if let navVc = mainViewController.presentedViewController as? UINavigationController {
            navVc.present(actionSheetController, animated: true, completion: nil)
        } else {
            mainViewController.present(actionSheetController, animated: true, completion: nil)
        }
    }

旋轉(zhuǎn)屏幕時(shí)會(huì)將彈出收起。模仿UC做法壹哺。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末抄伍,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子管宵,更是在濱河造成了極大的恐慌截珍,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件箩朴,死亡現(xiàn)場(chǎng)離奇詭異岗喉,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)炸庞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門钱床,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人埠居,你說(shuō)我怎么就攤上這事查牌。” “怎么了滥壕?”我有些...
    開(kāi)封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵纸颜,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我绎橘,道長(zhǎng)胁孙,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任称鳞,我火速辦了婚禮涮较,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘冈止。我一直安慰自己狂票,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布熙暴。 她就那樣靜靜地躺著苫亦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪怨咪。 梳的紋絲不亂的頭發(fā)上屋剑,一...
    開(kāi)封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音诗眨,去河邊找鬼唉匾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的巍膘。 我是一名探鬼主播厂财,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼峡懈!你這毒婦竟也來(lái)了璃饱?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤肪康,失蹤者是張志新(化名)和其女友劉穎荚恶,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體磷支,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谒撼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了雾狈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片廓潜。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖善榛,靈堂內(nèi)的尸體忽然破棺而出辩蛋,到底是詐尸還是另有隱情,我是刑警寧澤移盆,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布悼院,位于F島的核電站,受9級(jí)特大地震影響味滞,放射性物質(zhì)發(fā)生泄漏樱蛤。R本人自食惡果不足惜钮呀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一剑鞍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧爽醋,春花似錦蚁署、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至遂赠,卻和暖如春久妆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背跷睦。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工筷弦, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓烂琴,卻偏偏與公主長(zhǎng)得像爹殊,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子奸绷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

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

  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線程梗夸,因...
    小菜c閱讀 6,419評(píng)論 0 17
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,144評(píng)論 25 707
  • 知道為什么qq下面的評(píng)論越來(lái)越煽情了嗎 ,全是卸載了網(wǎng)易云跑過(guò)來(lái)的号醉。至少人家不擔(dān)心版權(quán)反症,至少人家播放列表不會(huì)一片灰色。
    賈志清閱讀 168評(píng)論 0 0
  • 文/周九 圖/網(wǎng)絡(luò) 馮小剛?cè)昴ヒ粍垩ⅲ段也皇桥私鹕彙肺从诚然鸲杳保群髷孬@國(guó)際A類電影節(jié)——西班牙圣塞巴斯蒂安最佳...
    文物志閱讀 341評(píng)論 2 0
  • 2017年11月25日 星期六 天氣晴 前幾天同事約好我們兩家今晚去天沐洗澡,所以一大早父虑,我把這個(gè)事告...
    二五班馬浩揚(yáng)閱讀 146評(píng)論 0 0