【问题标题】:How to hide share button in QLPreviewController using swift?如何使用 swift 在 QLPreviewController 中隐藏共享按钮?
【发布时间】:2016-03-28 06:14:52
【问题描述】:

我正在使用下面的代码来使用 QLPreviewcontroller 在我的应用中显示一些文档,

let ql = QLPreviewController()
ql.dataSource = self
//ql.navigationItem.rightBarButtonItems = nil
ql.navigationItem.rightBarButtonItem = nil
presentViewController(ql, animated: true, completion: nil)

我不希望 QLPreviewcontroller 右上角的共享按钮。我尝试将 rightBarButtonItem 设置为零,但它不起作用。

我该如何隐藏它?

【问题讨论】:

标签: ios swift qlpreviewcontroller rightbarbuttonitem


【解决方案1】:

这些解决方案都不适用于 Swift 3 for iOS 10。问题是 Share 按钮是在 viewDidAppear 方法之后创建的。

以下是我删除分享按钮的步骤:

1) 子类化我的 QLPreviewController

2) 在这个子类中创建了一个方法来打开我的文档:

func show(controller: UIViewController, url: NSURL) {
    // Refreshing the view
    self.reloadData()
    // Printing the doc
    if let navController = controller.navigationController {
        navController.pushViewController(self, animated: true)
    }
    else {
        controller.show(self, sender: nil)
    }
}

3) 在我的 viewDidLayoutSubviews 中,我创建了一个虚拟按钮项来替换共享按钮:

 override func viewDidLayoutSubviews() {
    navigationItem.rightBarButtonItems?[0] = UIBarButtonItem()
}

4) 当我想在另一个 VC 中打开一个文档时,我这样称呼它:

 QLSubclass().show(controller: self, url: path as NSURL)

注意:始终以这种方式调用它,而不是使用您实例化的全局变量,因为您总是会在共享按钮消失之前看到它。

【讨论】:

  • 虽然这在 iPad 上效果很好.. iPhone 上的分享按钮不在 nabber 上,而是在底部。知道如何删除它吗?我试图删除工具栏按钮,但共享按钮仍然存在
  • 另一个对我很有效的解决方案是创建您自己的 VC 并将 QLPreviewController 的视图添加为子视图,这样您就可以摆脱共享按钮 :)
  • 在 ios 11 中,当用户点击导航栏时隐藏,当您再次点击时,它会出现分享按钮!有什么解决办法吗?
  • 你为什么要传递 url?好像没用过!
  • 如何在 iOS12.0 中隐藏所有新的 AR Quicklook?
【解决方案2】:
  1. 创建QLPreviewController的子类

  2. 添加以下代码

斯威夫特:

var toolbars: [UIView] = []

var observations : [NSKeyValueObservation] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationItem.setRightBarButton(UIBarButtonItem(), animated: false)

    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        navigationController?.toolbar.isHidden = true

        if let navigationToobar = navigationController?.toolbar {
            let observation = navigationToobar.observe(\.isHidden) {[weak self] (changedToolBar, change) in

                if self?.navigationController?.toolbar.isHidden == false {
                     self?.navigationController?.toolbar.isHidden = true
                }
            }
            observations.append(observation)
        }

        toolbars = toolbarsInSubviews(forView: view)

        for toolbar in toolbars {

            toolbar.isHidden = true

            let observation = toolbar.observe(\.isHidden) { (changedToolBar, change) in
                if let isHidden = change.newValue,
                    isHidden == false {
                    changedToolBar.isHidden = true
                }
            }

            observations.append(observation)
        }
    }

    private func toolbarsInSubviews(forView view: UIView) -> [UIView] {

        var toolbars: [UIView] = []

        for subview in view.subviews {
            if subview is UIToolbar {
                toolbars.append(subview)
            }
            toolbars.append(contentsOf: toolbarsInSubviews(forView: subview))
        }
        return toolbars
    }

【讨论】:

  • 如果你想要 iOS13 隐藏 rightBarButtonItem 需要在“覆盖函数 viewDidLoad()”中添加这个navigationItem.rightBarButtonItem = UIBarButtonItem()
【解决方案3】:
let previewController = QLPreviewController()
previewController.navigationItem.rightBarButtonItem = UIBarButtonItem()
self.present(previewController, animated: true, completion: { })

【讨论】:

  • 我认为他们试图传达的是,如果您将 rightBarbuttonItem 分配给 UIBarButtonItem 的新实例(无需任何进一步配置),它将达到结果。
  • IMO 这是一个很好的答案!
  • 不起作用。如果您应用此代码,则 QLPreviewController 将在底部显示一个工具栏,其中包含您刚刚从导航栏右上角删除的相同共享按钮。
【解决方案4】:

我知道这是一个老问题,但我花了很多时间寻找解决方案并想出了一些可行的方法。

所以,对于任何与我寻找相同事物的人。这是我的解决方案。

代码在 Objective-c 中,但它可以简单地转换为 Swift

首先我们创建 QLPreviewController 的子类,并在子类中覆盖以下方法

编辑

斯威夫特:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationItem.rightBarButtonItem = nil
    //For ipads the share button becomes a rightBarButtonItem
    self.navigationController?.toolbar?.isHidden = true
    //This hides the share item
    self.navigationController?.toolbar?.addObserver(self, forKeyPath: "hidden", options: NSKeyValueObservingOptionPrior, context: nil)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    self.navigationController?.toolbar?.removeObserver(self, forKeyPath: "hidden")
}

override func observeValue(forKeyPath keyPath: String, ofObject object: Any, change: [AnyHashable: Any], context: UnsafeMutableRawPointer) {
    var isToolBarHidden: Bool? = self.navigationController?.toolbar?.isHidden
    // If the ToolBar is not hidden
    if isToolBarHidden == nil {
        DispatchQueue.main.async(execute: {() -> Void in
            self.navigationController?.toolbar?.isHidden = true
        })
    }
}

self.navigationController?.pushViewController(qlPreviewController, animated: true)

目标-C:

-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.navigationItem.rightBarButtonItem = nil; //For ipads the share button becomes a rightBarButtonItem
    [[self.navigationController toolbar] setHidden:YES]; //This hides the share item
    [[self.navigationController toolbar] addObserver:self forKeyPath:@"hidden" options:NSKeyValueObservingOptionPrior context:nil];
}

移除 viewWillDisappear 上的观察者

-(void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[self.navigationController toolbar] removeObserver:self forKeyPath:@"hidden"];
}

观察者方法:必需,因为当您单击图像以隐藏导航栏和工具栏时,分享按钮在点击时再次可见。

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

    BOOL isToolBarHidden = [self.navigationController toolbar].hidden;
    // If the ToolBar is not hidden
    if (!isToolBarHidden) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [[self.navigationController toolbar] setHidden:YES];
        });
    }
}

PreviewController 必须从您现有的 navigationController 中推送

[self.navigationController pushViewController:qlPreviewController animated:YES];

而且我们还必须使用子类而不是 QLPreviewController。

【讨论】:

  • 为我工作。您是否也找到了隐藏整个工具栏的方法?这只会隐藏共享图标。
  • 这里有一个关于 SO 的帖子link。删除工具栏,但共享按钮变为可见。检查一下,如果您想出解决方案,请同时发布您的解决方案。
  • 这似乎只是 ios 10 中的一个问题,也许是一个将被修复的错误。在 10 点之前它是隐藏的。
  • 在 ios 11 中,当用户点击导航栏时隐藏,当您再次点击时,它会出现分享按钮!有什么解决办法吗?
【解决方案5】:

如果仍然有人想要删除共享选项或想要自定义 QLPreviewController 的导航栏,那么他们可以尝试创建 UIViewController 并根据要求对其进行自定义,然后创建 QLPreviewController 对象并将其添加为子视图控制器。

这将使您摆脱共享按钮并自定义导航栏颜色等。这对我有用。

要知道如何添加子视图控制器可以参考this

【讨论】:

    【解决方案6】:

    Swift 5 解决方案:

    子类 QLPreviewController:

    final class CustomQLPreviewController: QLPreviewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            navigationItem.rightBarButtonItem = UIBarButtonItem()
        }
    
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
            (children[0] as? UINavigationController)?.setToolbarHidden(true, animated: false)
        }
    
        override func viewDidLayoutSubviews() {
            super.viewDidLayoutSubviews()
            (children[0] as? UINavigationController)?.setToolbarHidden(true, animated: false)
        }
    }
    

    然后在你想要的地方展示这个子类:

    let previewController = QLVideoController()
    present(controller, animated: true, completion: nil)
    
    • 使用此方法,您将在瞬间设置分享按钮

    【讨论】:

    • 6s ,iOS 13.5 ,children[0] 会崩溃,所以我将其更改为children.first,但似乎代码未执行,并且工具栏显示
    • 不工作,分享按钮仍然可见和工作
    【解决方案7】:
    override func viewDidLoad() {
        super.viewDidLoad()
        /* Move "Share" Button to bottom */
        navigationItem.rightBarButtonItem = UIBarButtonItem()
    }
    
    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        /* Hide toolbar to hide "Share" button  */
        self.navigationController?.toolbar.isHidden = true
    }
    

    【讨论】:

    • 覆盖 func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() navigationController?.toolbar.isHidden = true navigationItem.rightBarButtonItem = nil }
    • 欢迎来到 SO 并感谢您的贡献!如果您围绕代码 sn-ps 提供一些额外的上下文来解释它们的作用和/或它们如何回答问题,这通常会很有帮助。对于那些试图让你的代码适应稍微不同的情况的人来说,指向源或参考的链接也很有帮助。
    • 这个答案无效。
    【解决方案8】:

    这是我想出的最佳解决方案。

    诀窍是在隐藏工具栏时将动画设置为true。否则我们会看到分享按钮显示然后消失。

    final class NoSharePreviewController: QLPreviewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            navigationItem.rightBarButtonItem = UIBarButtonItem()
        }
    
        override func viewDidLayoutSubviews() {
            super.viewDidLayoutSubviews()
            navigationController?.setToolbarHidden(true, animated: true)
        }
    }
    

    【讨论】:

      【解决方案9】:

      这对我有用

         class QLSPreviewController : QLPreviewController {
      
              override func viewDidLoad() {
                  super.viewDidLoad()
      
      
      
              }
              override func viewWillAppear(_ animated: Bool) {
                  super.viewWillAppear(animated)
      
              }
              override func viewDidAppear(_ animated: Bool) {
                  super.viewDidAppear(true )
                  //This hides the share item
                  let add =  self.childViewControllers.first as! UINavigationController
                  let layoutContainerView  = add.view.subviews[1] as! UINavigationBar
                   layoutContainerView.subviews[2].subviews[1].isHidden = true
      
              }
          }
      

      【讨论】:

      • 为了向前兼容,强烈建议不要使用子视图索引来引用视图
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多