Hello everyone,
I am trying to open pdf file in uiwebview to other app. I can display popup like this.
I write the code like this. I put delegate also. UIDocumentInteractionControllerDelegate
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
//other code
if([fileType isEqualToString:#"pdf"])
{
NSLog(#"It is pdf file.");
//other code to save to nsdocumentdirectory and then get this path
// file://localhost/var/mobile/Applications/024D40FF-4518-4526-BEAB- 2A0679FD6308/Documents/iphone_user_guide.pdf
NSURL *pdfURL = [NSURL fileURLWithPath:pathToDownloadTo];
UIDocumentInteractionController *docController = [UIDocumentInteractionController interactionControllerWithURL:pdfURL];
[docController setDelegate:self];
[docController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
}
}
- (UIViewController *) documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *) controller {
return self;
}
I got this error.
void SendDelegateMessage(NSInvocation *): delegate (webView:didFinishLoadForFrame:) failed to return after waiting 10 seconds. main run loop mode: kCFRunLoopDefaultMode
In some link, it say due to Javascript. I also need to use this. stringByEvaluatingJavaScriptFromString
But I have disabled that function and tested. Then, there is no error but the app crashes.
I would like to know if there is something left to transfer document.
Also, I would like to know how to add Uibarbutton like "Open in ibook or sth" in the uiwebview programmatically with some code as in safari when we open pdf file.
With Regards,
Related
I want to create custom back button on each page in my iOS web-view (objective-C). Can anyone please suggest me how to implement.
Thanks in Advance
I am new to iOS Web-view that is why I posted directly what I want this is my code :
#import "ViewController.h"
#interface ViewController () <UIWebViewDelegate>
#end
#implementation ViewController{
__weak IBOutlet UIImageView *logoImage;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.webView.delegate = self;
NSString *urlString = #"https://www.anything.com";
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:requestObj];
self.webView.hidden = YES;
if ([_webView canGoBack]) {
[_webView goBack];
}}
- (void)webViewDidStartLoad:(UIWebView *)webView {
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
self.webView.hidden = NO;
logoImage.hidden = YES;
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
NSLog(#"%#", error);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I am passing a url of my website and I want to show a back button on every page of my application so that user can go to previous page. I have one more issue that whenever I minimise my application and opens it back from recent apps it get restarted while I want it to be resumed from the same screen
For the UIWebView, check the method - (void)goBack; out.
For the WKWebView, check the method - (WKNavigation *)goBack; and - (WKNavigation *)goBack:(id)sender; out.
UPDATE
// init the back button
[btnBack addTarget:self action:#selector(backButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
- (void)backButtonTapped:(id)sender
{
[self.webview goBack];
}
Assume you have set up your webview and back button (in the navigation bar or somewhere else) in the full code.
The browser could go back when the current (tab) page has a history list and the current page url is not the first and last one.
Make sure you really want to goBack in viewDidLoad, it needs some time to finishing loading the target page you specified (https://www.anything.com) just like you do it in a browser.
The method loadRequest of webview is asynchronous, it pushes the url request to webview and returns it immediately.
Bind the webview's goBack method to your custom back button like the above code snippets.
Try to click a sample link in the initial page (https://www.anything.com), once the new page finishes loading, it could be able to goBack with satisfying [self.webview canGoBack].
Make a breakpoint in the implementation of method backButtonTapped, if needed.
Drop the logoImage or other unrelated code issues in your next question, that makes your question more clear and helpful.
I found this thread which matches my problem: Clicking a link in UIWebView pushes onto the NavigationView stack
However, the following situations are different:
Instead of using a navigationController, I am using a View Based application to manually switch to different viewcontroller when corresponding buttons are pressed.
Rather than using links I am using onClick method to detect when a user clicks on something on a UIWebView and trying to open a new ViewController with a new UIWebView.
Will the same code work or do i have to make some changes?
You will have to do some modifications
1st:
when onClick, you will have to redirect your current page to a new location
This location for example will be MYLocation://GoThere
2nd:
Update the shouldStartLoadWithRequest
-(BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
NSURL *url = request.URL;
NSString *urlString = url.absoluteString;
//Check if special link
if ( [ urlString isEqualToString: #"MYLocation://GoThere" ] ) {
//Here present the new view controller
MyViewController *controller = [[MyViewController alloc] init];
[self presentViewController:controller animated:YES];
return NO;
}
return YES;
}
I think you may use the shouldStartLoadWithRequest as Omar posted.
If the new viewcontroller has a webviewcontroller, then you should pass the url (or even the request) to the new viewcontroller to show the clicked URL.
I use UIDocumentinteractioncontroller to open pdf on other app like ibook.
But it is hard to find the doc about it.
Now I can present the open in part. but when i click on the icon of ibooks. nothing happend.
Do I need to do something in the delegate such as documentInteractionController:willBeginSendingToApplication:???
first you have to add the UIDocumentInteractionControllerDelegate in your .h file
i.e.:
#interface MyDocumentViewController : UIViewController <UIDocumentInteractionControllerDelegate>
in your .m file you add the protocol, which enables you to find out, what happens ...
- (void)documentInteractionController:(UIDocumentInteractionController *)controller willBeginSendingToApplication:(NSString *)application{
NSLog(#"Send to App %# ...", application);
}
- (void)documentInteractionController:(UIDocumentInteractionController *)controller didEndSendingToApplication:(NSString *)application{
NSLog(#"Finished sending to app %# ...", application);
}
- (void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller{
NSLog(#"Bye");
}
of course you have to set the delegate of the UIDocumentInteractionController to this module. I solved it like this:
-(BOOL)canOpenDocumentWithURL:(NSURL*)url inView:(UIView*)view {
BOOL canOpen = NO;
UIDocumentInteractionController* tmpDocController = [UIDocumentInteractionController
interactionControllerWithURL:url];
if (tmpDocController)
{
tmpDocController.delegate = self;
canOpen = [tmpDocController presentOpenInMenuFromRect:CGRectZero
inView:self.view animated:NO];
[tmpDocController dismissMenuAnimated:NO];
}
return canOpen;
}
I was wondering if I could create an app which supports opening .html-pages.
For example, if the app supports .pdf, when opening a .pdf, a small gray box appears with the button "Open in myApp". Can I get something like this, but then for a webpage?
Hmm you are talking about UIDocumentInteractionController then.
Implement UIDocumentInteractionControllerDelegate in your UIViewController
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller { return self; }
- (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller { return self.view; }
- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller { return self.view.frame; }
Then add a button to the navigation bar to popup the options box:
// example: opening a .html file
NSString *index = [[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"];
// self.controller is a UIDocumentInteractionController ivar
self.controller = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:fileToOpen]];
self.controller.delegate = self;
CGRect rect = self.navigationController.navigationBar.frame;
rect.size = CGSizeMake(1500.0f, 40.0f); // move the box right down under the button
[self.controller presentOptionsMenuFromRect:rect inView:self.view animated:YES];
A list of the applications supporting a particular document should appear. If you didn't register your app to support a type of document you still get the option "QuickLook". All this happens on whatever application is interacting with the file (since the files themselves are not exposed on the UI).
I've created a NSWindow with a PDFView in xib file, I created a controller called MainController, there, I created a ibaction -(IBAction) openFileAction:(id) sender, it uses the method
-(void) openFile:(NSString *) path{
NSLog(#"Opening File %#",path);
PDFDocument *pdfDoc = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:path]];
[pdfView setDocument: pdfDoc];
}
I linked the open menu item to openFileAction and pdf file is shown properly in PDFView after the click.
I'm doing a logic to receive a command line argument
-(MainController *) init{
[super init];
NSArray *myArgs = [[NSProcessInfo processInfo] arguments];
NSLog(#"pdf view %#", pdfView);
if ([myArgs count] >= 2 ){
[self openFile:[myArgs objectAtIndex:1]];
}
return self;
}
As you can see, I did an override in default constructor and in this context the pdfView is null then the file is not opened after the application/main Window load.
My question is, how can I open a pdf in a PDFView after the application load? Is there any hook to use after UI load?
If you want to do this when your window opens that your PDFView is in, use the windowDidLoad function in your MainController rather than trying to load it in init.
Thanks slycrel but windowDidLoad is a callback of NSWindowController. I found the solution by myself, the secret is
- (void) awakeFromNib{
//Do something after initialize UI components
}
All the best.