[英]How to hide share button in QLPreviewController using swift?
我正在使用下面的代码来使用 QLPreviewcontroller 在我的应用程序中显示一些文档,
let ql = QLPreviewController()
ql.dataSource = self
//ql.navigationItem.rightBarButtonItems = nil
ql.navigationItem.rightBarButtonItem = nil
presentViewController(ql, animated: true, completion: nil)
我不希望 QLPreviewcontroller 右上角的共享按钮。 我尝试将rightBarButtonItem
为 nil,但它不起作用。
我怎么能隐藏它?
在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)
注意:始终以这种方式调用它,而不是使用您实例化的全局变量,因为您将始终在共享按钮消失之前看到它。
创建QLPreviewController
的子类
将以下代码添加到它
迅速:
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
}
let previewController = QLPreviewController()
previewController.navigationItem.rightBarButtonItem = UIBarButtonItem()
self.present(previewController, animated: true, completion: { })
我知道这是一个老问题,但我花了很多时间寻找解决方案并想出了一些可行的方法。
因此,对于任何与我寻找相同事物的人。 这是我的解决方案。
代码在 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。
如果仍然有人想要删除共享选项或想要自定义QLPreviewController
的导航栏,那么他们可以尝试创建UIViewController
并根据需要对其进行自定义,然后创建QLPreviewController
对象并将其添加为子视图控制器。
这将使您摆脱共享按钮并自定义导航栏颜色等。这对我有用。
要知道如何添加子视图控制器可以参考这个
斯威夫特 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)
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
}
这是我想出的最佳解决方案。
诀窍是在隐藏工具栏时将动画设置为true
。 否则,我们将看到显示的共享按钮然后消失。
final class NoSharePreviewController: QLPreviewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
navigationController?.setToolbarHidden(true, animated: true)
}
}
这对我有用
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
}
}
Swift5优雅的解决方案:
class QLPreviewVC: QLPreviewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let add = self.children.first as? UINavigationController {
if let navBar = add.view.subviews.compactMap({ $0 as? UINavigationBar }).first {
navBar.topItem?.rightBarButtonItem?.isHidden = true
}
}
}
}
private extension UIBarButtonItem {
var isHidden: Bool {
get {
return !isEnabled && tintColor == .clear
}
set {
tintColor = newValue ? .clear : nil
isEnabled = !newValue
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.