问题
I am subclassing QLPreviewController in my application and using the following code.
QLPreviewControllerSubClass* preview = [[QLPreviewControllerSubClass alloc] init];
[self presentViewController:preview
animated:YES
completion:^()
{
// do more stuff here
}];
I want to hide the right bar button .Tried
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self navigationItem].rightBarButtonItems = nil;
}
But its not hiding.Any help will be appreciable
回答1:
I'm dealing the same problem also.
I made the rightBarButton hidden, but may have some problem when the loading of pdf lasts for a long time.
Below is my process.
1.Make a sub class of QLPreviewController.
2.Add a timer to repeats setting the rightBarButton to nil when the class init.
_hideRightBarButtonTimmer = [NSTimer scheduledTimerWithTimeInterval:0.01
target:self
selector:@selector(hideRightButton)
userInfo:nil
repeats:YES];
3.Invalidate the timer in viewDidAppear.
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(cancelTimmer) userInfo:nil repeats:NO];
And I found the rightBarButton is setup while the loading of pdf file is finished. If we can detect the event the solution will be much easier and clearer.
Hopes it will be helpful.
回答2:
I have found a solution to disable (not hide) therightBarButtonItem
in QLPreviewController
The solution works fine for me in iOS8 and iOS9
You simply need to subclass QLPreviewController
and override the following methods, then use your subclass instead of the original QLPreviewController
- (void)viewDidLoad {
[super viewDidLoad];
// When coming back from background we make sure the share button on the rightbBarButtonItem is disabled
__weak typeof(self) weakSelf = self;
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
weakSelf.navigationItem.rightBarButtonItem.enabled = NO;
}];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationItem.rightBarButtonItem.enabled = NO; // Disable the share button
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.navigationItem.rightBarButtonItem.enabled = NO; // Disable the share button
}
回答3:
Tested on iOS 9 with swift.
Recently had to solve this issue and had trouble finding a way to hide this dang button. I finally managed to hide the right share button using an answer from this stackoverflow post.
Basically, you want to subclass QLPreviewController and call the inspectSubviewForView() function in your viewWillAppear() function. Once you find the navigation item containing the share button, you can remove it:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
// ** traverse subviews until we find the share button ** //
inspectSubviewForView(self.view)
}
func inspectSubviewForView(view: UIView) {
for subview in view.subviews {
if subview is UINavigationBar {
// ** Found a Nav bar, check for navigation items. ** //
let bar = subview as! UINavigationBar
if bar.items?.count > 0 {
if let navItem = bar.items?[0] {
// ** Found the share button, hide it! ** //
hideRightBarItem(navItem)
}
}
}
if subview.subviews.count > 0 {
// ** this subview has more subviews! Inspect them! ** //
inspectSubviewForView(subview)
}
}
}
func hideRightBarItem(navigationItem: UINavigationItem) {
// ** Hide/Remove the Share button ** //
navigationItem.setRightBarButtonItem(nil, animated: false)
}
The previous poster from the above link warned that this may not get through apple's review process as you are accessing private APIs, so use at your own risk! Also if Apple updates the QLPreviewController in later versions of iOS this code may no longer work.
Still, this is the only solution that has worked for me. I hope it works for you too!
回答4:
Thanks to Matthew Kostelecky, i was able to hide the share button but i would like to add some details for those need this in universal apps with multiple files.
Firstly Matthew's answer works if you use QLPreviewController modally. If you push QLPreviewController from your navigation controller like this;
navigationController?.pushViewController(quickLookController, animated: true)
It wont be able to find any NavigationBar or ToolBar. You should call QLPreviewController modally like this;
presentViewController(quickLookController, animated: true, completion: nil)
Also if you are developing universal app and you have list of files to play. There will be another button(List Button);
In iPhones if you have multiple files, QLPreviewController will create toolbar to show "List Button" and "Share Button" and both of these will be on ToolBar.
In iPads both of these buttons are on NavigationBar and there is no ToolBar.
So addition to Matthew's answer you should search toolBar if you have multiple files in iphone;
func inspectSubviewForView(view: UIView) {
for subview in view.subviews {
if subview is UINavigationBar {
// ** Found a Nav bar, check for navigation items. ** //
let bar = subview as! UINavigationBar
if bar.items?.count > 0 {
if let navItem = bar.items?[0] {
navItem.setRightBarButtonItem(nil, animated: false)
}
}
}
if subview is UIToolbar {
// ** Found a Tool bar, check for ToolBar items. ** //
let bar = subview as! UIToolbar
if bar.items?.count > 0 {
if let toolBarItem = bar.items?[0] {
toolBarItem.enabled = false
}
}
}
if subview.subviews.count > 0 {
// ** this subview has more subviews! Inspect them! ** //
inspectSubviewForView(subview)
}
}
}
This piece of code will hide share button on iPad and disable share button on iPhone.
Hope it helps to those still need it.
回答5:
Simple solution for this is add one dummy view to current viewController and Add QLPreviewControlle.view
to dummy view .
previewController = [[QLPreviewController alloc] init];
previewController.dataSource = self;
previewController.delegate = self;
previewController.currentPreviewItemIndex = 0;
[self.ContentView addSubview:previewController.view];
- (IBAction)removeQPView:(id)sender {
[previewController.view removeFromSuperview];
}
回答6:
Another way to achieve this is by subclassing UIToolbar and overriding setItems(_:animated:)
. You can return an empty array if you want to remove all or return only buttons you want to keep. Here is an example PreviewControllerHideBottomButtons
回答7:
Go for subclassing the QLPreviewController
and use the below-mentioned code, that only works fine for me using Xcode 8.3
.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let firstView = self.childViewControllers.first {
for view in firstView.view.subviews {
if view.isKind(of: UIToolbar.self) {
view.removeFromSuperview()
}
}
}
}
回答8:
Its simple and working well import quicklook and create a class of QL-Click here for Result which u all need, working well
import UIKit
import QuickLook.
class QLSubclass: QLPreviewController , QLPreviewControllerDataSource {
var p = NSURL()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidLayoutSubviews() {
navigationItem.rightBarButtonItems?[0] = UIBarButtonItem()
}
func show(controller: UIViewController, url: NSURL) {
// Refreshing the view
p = url
self.dataSource = self
self.reloadData()
// Printing the doc
if let navController = controller.navigationController {
navController.pushViewController(self, animated: true)
}
else {
controller.show(self, sender: nil)
}
}
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
let doc = p
return doc
}
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
return 1
}
}
after then in your view controller class-
class PatternVC: UIViewController, UIDocumentInteractionControllerDelegate , UINavigationControllerDelegate {
var link = ""
override func viewDidLoad() {
super.viewDidLoad()
let url = "YOUR_URL_LINK"
//check file exist in local or not------
if isFileExist(imgURL: url) {
//Found then show
let loadPath = loadDataFromDirectory(imgURL: url)
showFileWithPath(path: loadPath)
}else {
//save in local
saveDataOnDocumentDirectory(imgURL: url)
}
}
override func viewDidLayoutSubviews() {
self.navigationController?.setNavigationBarHidden(true, animated: false)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}//Open data
func showFileWithPath(path: String){
let isFileFound:Bool? = FileManager.default.fileExists(atPath: path)
if isFileFound == true{
QLSubclass().show(controller: self, url: URL(fileURLWithPath: path) as NSURL)
}else{}}
Also add a function for save in local in your view controller- //downloading request-----
private var downloadTask: URLSessionDownloadTask?
func saveDataOnDocumentDirectory(imgURL: String) {
//let url = URL(string: imgURL)
let escapedAddress = imgURL.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
let url2 = URL(string: escapedAddress!)
let sessionConfig = URLSessionConfiguration.default
//let sessionConfig = URLSessionConfiguration.background(withIdentifier: "backgroundSession")
let session: URLSession! = URLSession(configuration: sessionConfig, delegate: self, delegateQueue: nil)
downloadTask = session.downloadTask(with: url2!)
downloadTask?.resume()
DispatchQueue.main.async {
}
}}
After that includes a extension on view extension PatternVC: URLSessionDelegate, URLSessionDownloadDelegate{
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
if error != nil {
// lbl.text = "Download failed"
}
resetView()
}
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
let fileManager = FileManager.default
do {
let requestURL = downloadTask.currentRequest?.url
let documentDirectory = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:true)
let fileURL = documentDirectory.appendingPathComponent(getImageNameFromUrl(imgURL: requestURL!))
do {
try fileManager.moveItem(at: location, to: fileURL)
print("save item: \(fileURL)")
} catch (let writeError) {
print("Error creating a file \(fileURL) : \(writeError)")
}
} catch {
print(error)
}
DispatchQueue.main.async {
//self.loadDirectory()
self.resetView()
}
}
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
// 1
//guard let _ = downloadTask.originalRequest?.url, let download = model?.imagePath else { return }
let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
DispatchQueue.main.async {
//self.radialView.ringProgress = CGFloat(progress * 100)
}
print("-URL: \(downloadTask.currentRequest?.url?.relativePath ?? "") ----Per: \(CGFloat(progress * 100))")
}
func resetView() {
downloadTask!.cancel()
}
func isFileExist(imgURL: String) -> Bool{
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let url = NSURL(fileURLWithPath: path)
let escapedAddress = imgURL.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
let url2 = URL(string: escapedAddress!)
if let pathComponent = url.appendingPathComponent(getImageNameFromUrl(imgURL: url2!)) {
let filePath = pathComponent.path
let fileManager = FileManager.default
if fileManager.fileExists(atPath: filePath) {
print("FILE AVAILABLE")
return true
} else {
print("FILE NOT AVAILABLE")
let url = APIConstant.videoJpgUrl + link
//self.loadUrl (urlString:url)
return false
}
} else {
print("FILE PATH NOT AVAILABLE")
return false
}
}
func loadDataFromDirectory(imgURL: String) -> String
{
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let url = NSURL(fileURLWithPath: path)
let escapedAddress = imgURL.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
let url2 = URL(string: escapedAddress!)
if let pathComponent = url.appendingPathComponent(getImageNameFromUrl(imgURL: url2!)) {
let filePath = pathComponent.path
let fileManager = FileManager.default
if fileManager.fileExists(atPath: filePath) {
print("FILE AVAILABLE")
return filePath
} else {
print("FILE NOT AVAILABLE")
let url = APIConstant.videoJpgUrl + link
self.loadUrl (urlString:url)
return filePath
}
}else
{
return "ERROO"
}
}
func getImageNameFromUrl(imgURL: URL) -> String{
let name = imgURL.lastPathComponent
let result = name.substring(from: name.index(name.startIndex, offsetBy: 5))
return result
}
来源:https://stackoverflow.com/questions/22953117/hide-right-button-n-qlpreviewcontroller