美文网首页
[技术文档][技术中心][iOS部][114啦]全局菜单

[技术文档][技术中心][iOS部][114啦]全局菜单

作者: Zongzi_599 | 来源:发表于2017-11-30 12:17 被阅读0次

    菜单类型

    1、首页点击更多按钮弹起的菜单:FunctionView

    2、详情页点击更多按钮弹出的菜单:YYWMenuView

    3、长按webview中的链接弹出的菜单:YYWContextMenuHelp.swift

    具体实现

    • FunctionView
      界面由nib搭建。view加在mainviewcontroller的view中。
      通过以下代码来隐藏和显示,有动画效果。
      部分按钮在首页时置灰不可点击。
      该菜单的具体功能实现全由PageViewManager代理实现。
    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上的,因此全局调用一次show方法即可显示出来。
      该枚举代表显示的位置,不同类型显示不同的菜单项。
    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
        }
    

    各菜单项对应的title与image已经预先定义好。

    init(defaultType: YYWMenuItemType) {
        type = defaultType
        switch type {
        case .accountStatus:
          title = NSLocalizedString("未登录", comment: "")
          image = UIImage(named: "menu_visitor")!
        case .setting:
          title = NSLocalizedString("设置", 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("复制链接", 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("字体设置", comment: "")
            image = UIImage(named: "menu_font")!
        case .feedback:
            title = NSLocalizedString("意见反馈", comment: "")
            image = UIImage(named: "menu_edit")!
        case .itemType:
          assert(true, "itemType 不是默认类型, 使用上面那个方法初始化。")
          title = ""
          image = UIImage()
        }
        super.init()
      }
    

    因此初始化时指定type,显示方向type,以及一个block。

    init(archorView: UIView, contentType ctype: contentType, directionType dtype: directionType, action: @escaping YYWMenuAction)
    // block定义 回调时返回点击的type项,根据该type处理事件。
    typealias YYWMenuAction = (YYWMenuItemType) -> Void
    
    • YYWContextMenuHelp
      该弹层使用系统自带的UIAlertController实现。
      根据以下方法获取的webview元素决定显示哪些弹层。
    userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
    
    YYWContextMenuHelp.Elements(link: linkURL, image: imageURL, imageUrls: self.allImagesUrl, linkText: linkText)
    

    创建代码

    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 {//长按链接与图片
                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 {///长按链接
                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 {//长按图片
                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)
            }
        }
    

    旋转屏幕时会将弹出收起。模仿UC做法。

    相关文章

      网友评论

          本文标题:[技术文档][技术中心][iOS部][114啦]全局菜单

          本文链接:https://www.haomeiwen.com/subject/vcqvbxtx.html