I want to import a document into my application. I have created a Demo to import Document. A demo is working. below is the code of the Demo to open UIDocumentPickerViewController.
-(IBAction) btnOpenClicked{
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:[self allowedUTIs] inMode:UIDocumentPickerModeImport];
documentPicker.delegate = self;
[self presentViewController:documentPicker animated:true completion:nil];
}
-(NSArray*)allowedUTIs{
return #[#"public.data",#"public.content",#"public.audiovisual-content",#"public.movie",#"public.audiovisual-content",#"public.video",#"public.audio",#"public.text",#"public.data",#"public.zip-archive",#"com.pkware.zip-archive",#"public.composite-content",#"public.text"];
}
The same code is implemented in my actual project. UIDocumentPickerViewController open and App is able to import file but the issue is that in the actual app I am not able to see any buttons in the header. thought there is action happen but buttons are not visible. Please check screenshot of the Demo and actual app.
Your app is probably setting a global UINavigationBar tint color appearance. You can just reset the appearance for UIDocumentPickerViewController only by putting this code somewhere in your application:didFinishLaunchingWithOptions: function and the bar buttons will return to their original blue.
if #available(iOS 11.0, *) {
UINavigationBar.appearance(whenContainedInInstancesOf: [UIDocumentBrowserViewController.self]).tintColor = nil
}
For Objective C:
-> by putting this code somewhere in your application:didFinishLaunchingWithOptions:
[[UINavigationBar
appearanceWhenContainedInInstancesOfClasses:
#[[UIDocumentBrowserViewController class]]] setTintColor: nil];
Related
I have an issue with UIDocumentInteractionController which is used to open a PDF document.
The problem at this point is when user interacts with the menu my clicking on the Open in {app_name} action, the menu itself fails to close after user interaction leaving the menu open when user comes back to the app.
Dismissing the menu at this point requires user to tap twice on the X in order for menu to be dismissed.
I also tried to close the menu dynamically when app returns to active state by running dismissMenuAnimated on UIDocumentInteractionController instance but it does not work in this case, it does however dismiss the dialog if no interaction was made on it and the method is called.
One note, this issue is only present on never iOS version 13+. On older OS the menu is closed after interaction as expected.
We tried using this code other than all react-native stuff we tried:
#property (nonatomic, strong) UIDocumentInteractionController *documentInteractionController;
#property (atomic) CGRect rect;
RCT_EXPORT_METHOD(openDocumentInteractionControllerWithFileURL:(NSURL *)fileURL){
if (!fileURL) {
// Return NO because there was no valid fileURL.
return;
}
UIViewController *rootCtrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
// Open "Open in"-menu
self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:fileURL];
self.documentInteractionController.delegate = self;
BOOL sucess; // Sucess is true if it was possible to open the controller and there are apps available
sucess = [self.documentInteractionController presentOpenInMenuFromRect:self.rect inView:rootCtrl.view animated:YES];
if(!sucess){
// Inform app that the activity has finished
// Return NO because the service was canceled and did not finish because of an error.
// http://developer.apple.com/library/ios/#documentation/uikit/reference/UIActivity_Class/Reference/Reference.html
}
}
RCT_EXPORT_METHOD(dismissDocumentInteractionController){
// Hide menu
[self.documentInteractionController dismissMenuAnimated:YES];
}
But without success.
You need to close the interaction controller menu after user performs his selection in this menu.
You can do it in UIDocumentInteractionControllerDelegate like this:
- (void)documentInteractionController:(UIDocumentInteractionController *)controller willBeginSendingToApplication:(NSString *)application {
[self.documentInteractionController dismissMenuAnimated:YES];
}
I'm trying to pick file from Files App using UIDocumentPickerViewController but I can't see Select button for multiple selection in picker. Why this is happening? am i doing anything wrong? Can anyone help?
Code snippet :
NSArray *arrContents = #[#"public.content",#"public.item",#"public.composite-content",#"public.data",#"public.database",#"public.calendar-event",#"public.message",#"public.presentation",#"public.contact",#"public.archive",#"public.disk-image",#"public.text",#"public.plain-text",#"public.utf8-plain-text",#"public.utf16-external-plain-text",#"public.utf16-plain-text",#"com.apple.traditional-mac-plain-text",#"public.rtf"];
UIDocumentPickerViewController *dvc = [[UIDocumentPickerViewController
alloc]initWithDocumentTypes:arrContents inMode:UIDocumentPickerModeImport];
dvc.delegate = self;
[self presentViewController:dvc animated:true completion:nil];
set dvc.allowsMultipleSelection = true; after initialising UIDocumentPickerViewController.
I have a SFSafariViewController opening at the click of a button inside a UIActionSheet. It has been working fine and is still working fine on all the versions of iOS except iOS 11. Is there something they have changed regarding the SFSafariViewController in iOS 11 or in Xcode 9.0 that might have caused this issue?
UPDATE - So it seems like its Xcode 9.0 that is causing this issue. I have tried running it on different iOS versions and all of them seem to be giving this issue. It used to work fine when I ran it using Xcode 8.3.3, something I don't have anymore :(
Here's the code -
- (void)presentWebView:(NSString *)url {
url = [url stringByReplacingOccurrencesOfString:#" " withString:#"+"];
url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *URL = [NSURL URLWithString:url];
if (URL) {
if ([SFSafariViewController class] != nil) {
SFSafariViewController *sfvc = [[SFSafariViewController alloc] initWithURL:URL];
sfvc.delegate = self;
[self.tabBarController presentViewController:sfvc animated:YES completion:nil];
} else {
if (![[UIApplication sharedApplication] openURL:URL]) {
NSLog(#"%#%#",#"Failed to open url:",[url description]);
}
}
} else {
// will have a nice alert displaying soon.
}
}
I've managed to fix this in my code. I hope this helps anyone else with a similar problem.
I had the exact same problem as described here. I tried everything above and unfortunately nothing worked.
In my app there were different windows. The fix was to ensure the window that would show SFSafariViewController was 'key' before presenting it. For example:
class MyViewController: UIViewcontroller {
func showSafariViewController() {
// imagine we have 2 windows, one for 'normal' content (key window) and one for 'other' content. lets say we're showing the 'other' content window, and have hidden the 'normal' window. you can see the 'other' content window in the app, but it won't be the key window!
let window = // get the 'other' content window
// make sure we make it the key window before presenting safari
window.makeKey()
// now present safari and celebrate victory by triumphantly slurping on your hot black coffee
let mySafariViewController = SFSafariViewController(...)
self.present(mySafariViewController ...)
}
}
I suspect Apple are searching for a SFSafariViewController instance in the window UIApplication.shared.keyWindow. Perhaps they're adding a child view from somewhere else. In the documentation it states The user's activity and interaction with SFSafariViewController are not visible to your app, so perhaps it's the bug is something related to an added level of security https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller
I have tried to do it using delay and make view of controller loading.Both are working for me.
Method 1. Using delay.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
let controller = SFSafariViewController(url: url)
controller.modalPresentationStyle = .overFullScreen
self.present(controller, animated: true, completion: nil)
controller.delegate = self
}
Method 2. Loading view.
let controller = SFSafariViewController(url: url)
let _ = controller.view
controller.modalPresentationStyle = .overFullScreen
self.present(controller, animated: true, completion: nil)
controller.delegate = self
Very similar to https://openradar.appspot.com/29108332
To fix it, you can disable the lazy loading of the view:
SFSafariViewController *viewController = [[SFSafariViewController alloc] init...];
(void)viewController.view;
...
[controller presentViewController:viewController animated:YES completion:nil];
Update
Turns out the old answer didn't work, it just worked since I put breakpoints. If I added a thread sleep seems it worked in XCode9, but that's not the best solution. Anyone have another better solution?
SFSafariViewController *sfcontroller = [[SFSafariViewController alloc] initWithURL:url];
if (#available(iOS 11.0, *)) {
[NSThread sleepForTimeInterval:0.5f];
}
sfcontroller.delegate = self;
[controller presentViewController:sfcontroller animated:NO completion:nil];
Old Answer
I have the same issue as genaks and tinkered around with SFViewController.
Seems like this code works for me
SFSafariViewController *sfcontroller = [[SFSafariViewController alloc] initWithURL:url];
if (#available(iOS 11.0, *)) {
SFSafariViewControllerConfiguration *config = [[SFSafariViewControllerConfiguration alloc] init];
config.barCollapsingEnabled = NO;
sfcontroller = [[SFSafariViewController alloc] initWithURL:url configuration: config];
} else {
// Fallback on earlier versions
}
sfcontroller.delegate = self;
[controller presentViewController:sfcontroller animated:YES completion:nil];
In ios 11, they introduce SFSafariViewControllerConfiguration, and by default the barCollapsingEnabled is true and it seems the one that causing my blank SafariView. Hope this solves yours too
We had this issue: our URL was https://our-side.com/index.html (an Angular site that would redirect to the /account route). When we removed the index.html, the SFSafariViewController loaded correctly!
The only thing that has worked so far for me is to make the SafariViewController the rootviewcontroller in the following manner -
((XYZAppDelegate *)[UIApplication sharedApplication].delegate).window.rootViewController = self.svc;
[((XYZAppDelegate *)[UIApplication sharedApplication].delegate).window makeKeyAndVisible];
I've been working with the Apple sample code for viewing documents from here:
https://developer.apple.com/library/ios/samplecode/DocInteraction/Listings/ReadMe_txt.html
I have removed all the bits I don't need and got it working pretty much how I would like it to. The problem is I don't want users to have access to the "Actions" menu on the top right of the Document Controller. This appears every time you select a document from the list:
Ideally I would like to remove the button all together, though if I could disable it or disable all the options inside it that would also suffice. I found this question:
Open in + UIDocumentInteractionController : how to filter options in SDK iOS 6 (canPerformActions is deprecated)
But I couldn't figure out how to use the suggestion to disable the options inside the menu. I have uploaded the modified sample code here:
http://plasma.servebeer.com/DocSampleCode.zip
One final note is this will not be going on the App Store it is for private, personal use, so if there is an unofficial way then I would be interested in knowing that too.
Any help would be greatly appreciated, thanks in advance.
Plasma
Use UINavigationControllerDelegate
#interface DITableViewController () <UIDocumentInteractionControllerDelegate, UINavigationControllerDelegate>
Assign navigationController delegate to self
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.delegate = self;
}
Change documentInteractionControllerViewControllerForPreview
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)interactionController {
return self.navigationController;
}
Add this UINavigationControllerDelegate method
// Called when the navigation controller shows a new top view controller via a push, pop or setting of the view controller stack.
- (void)navigationController:(UINavigationController*)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ([viewController isKindOfClass:[QLPreviewController class]]) {
viewController.navigationItem.rightBarButtonItem = nil;
}
}
Update for MP4 files
In MP4 files the action button is on the UIToolbar
- (void)navigationController:(UINavigationController*)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ([viewController isKindOfClass:[QLPreviewController class]]) {
viewController.navigationItem.rightBarButtonItem.customView = [[UIView alloc] init];
UIBarButtonItem *item = viewController.toolbarItems.firstObject;
item.customView = [[UIView alloc] init];
}
}
N.B. This might not work in future versions of iOS
After creating QLPreviewController class you would need to set rightBarButtonItem to nil. Code snippet:
QLPreviewController *previewController = [[QLPreviewController alloc] init];
previewController.navigationItem.rightBarButtonItem = nil;
I did download project and after execution "Action" button was shown not in the top navigation item, but in the toolbar. Then in this case you would need to subclass QLPreviewController and override viewWillAppear as shown below.
#implementation ExViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSMutableArray *a = [NSMutableArray arrayWithArray:#[]];
for (NSUInteger i = 0; i < self.toolbarItems.count; i++) {
if (i == 0) {
continue;
}
[a addObject:self.toolbarItems[i]];
}
}
#end
If you want to hide button the give answers will not work for iOS 10.0 and above in Swift language. You can use WKWebView. Hope it will save your time.
I am trying to print a txt file from within a iPad 8.x application. So, I have this code:
- (void)onOpenWith:(UIButton *)theButton path:(NSString *)path
{
NSURL *URL = [NSURL fileURLWithPath:path];
if (URL) {
self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:URL];
self.documentInteractionController.delegate = self;
[self.documentInteractionController presentPreviewAnimated:YES];
}
}
#pragma mark - UIDocumentInteractionControllerDelegate
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller
{
return self;
}
- (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller
{
return self.view;
}
- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller
{
return self.view.frame;
}
Now everything is going as expected, I see a preview of the file, then I touch the icon on the top right corner of the screen and I am able to share the document in those applications that can handle it. However, if I touch PRINT I get this error message:
Application tried to present inside popover with transition style
other than UIModalTransitionStyleCoverVertical
and the app crashes. Sure, i understand it, but to which viewcontroller should I apply this transition? I have no control on the popover showing the print dialog...
In iOS 7 (real iPad not simulator) everything works...
Can anybody help me?
Thanks
Fabio
I also came across this issue, and the solution was that I had to build and run my app with Xcode 6 installed.
On my older machine, I have Xcode 5.1.1, and when run from there, this same issue appeared, and some more issues from this view (like cannot dismiss mail controller when opened from the top right corner).