iOS UIWebView PDF Not Showing First Time - ios

I have a UIViewController with a UIWebView where I'm placing a PDF.
The issue I'm facing is when I click on a table cell to show the PDF it does not show the first time however if i go back to the table and click on the cell again it appears.
I call the PDF to get loaded using the following:
if ([indexPath row] == 2)
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"myFirstPdf" ofType:#"pdf"];
NSURL *url = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webViewVC.webView loadRequest:request];
webViewVC.parent = _parent;
[_parent pushViewController:webViewVC];
}
The webViewVC itself I allocate using an initWithNib which has the UIWebView - nothing fancy there, simply a UIWebView with a IBOutlet.
Any ideas?

I think you should try 2 things:
(1) First, try loading the PDF from the web view controller. This is really the standard way to do this, rather than doing a load request for a web view that is not even on screen yet. All outlets are guaranteed to be loaded only in viewDidLoad of the controller.
(2) Second, try making use of the UIWebViewDelegate. For example, you could call setNeedsDisplay on the web view once loading is finished.

My idea : the first time you try the action your "webViewVC" hasn't been loaded yet, so webViewVC.webView is nil
the second time as you have displayed the webViewVC in your first attempt, it has been loaded, so webViewVC.webView isn't nil;
create a property on your webViewVC where you will set your request
and on your webViewVC viewWillAppear method do your [self.webView loadRequest:self.request];

Related

Xcode : Change WebView Url on tableview item click

I got a static tableList of Categories on a view controller (called CategoriesViewController ) in main storyboard, this contain the categories of the Blog shown in a webView in fistViewController.
When I click (or tap) in a Category it must to send me to webView Page and change the URL (eg mainpage is www.example.com and category is www.example.com/category)
I've just made a simple webView in first page view like:
- (void)viewDidLoad {
[super viewDidLoad];
NSString *fullURL = #"http://www.example.com";
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[_webView loadRequest:requestObj];
}
How can I interact with elements in another controller and change NSURLRequest appending the category after slash?
Should I get the elements on the Table View as ID?
And what's the code to archieve this?
As I understood that is a TableView. So you need to implement the method didSelectRowAtIndexPath and I believe you have an array of those categories. so you need to get the indexPath.row (indexPath is an argument in this method) and pass it along to the next view controller by appending it to the initial URL.

webView - how to stop reloading

I am developing an app in Xcode but am having trouble with one part.
Basicly on the main app page, there is a small section that contains a web view. Everytime I change to another view controller and back, i see it flicker and reload. Is there a way to prevent it from reloading every time i open the view? instead just reloading every time I open the app.
This is the code:
NSURL *webUrl = [NSURL URLWithString:#"myurl.com"];
NSURLRequest *webrequestUrl = [NSURLRequest requestWithURL:webUrl];
[webView loadRequest:webrequestUrl];
webView.scrollView.scrollEnabled = NO;
webView.scrollView.bounces = NO;
Your webview is reloading every time you go to that screen is probably because you added it to either viewDidAppear: or viewWillAppear.
Add your block of code to the viewDidLoad method so it only gets executed when the view is loaded (aka when it's shown for the first time).
- (void)viewDidLoad:(BOOL)animated {
NSURL *webUrl = [NSURL URLWithString:#"myurl.com"];
NSURLRequest *webrequestUrl = [NSURLRequest requestWithURL:webUrl];
[webView loadRequest:webrequestUrl];
webView.scrollView.scrollEnabled = NO;
webView.scrollView.bounces = NO;
}
Edit: Oh by going to another view and back you meant going back on the navigation stack (or switching the navigation stack). In that case, you can keep a strong reference to your view controller with the webview and reuse it. Though I wouldn't suggest it doing it this was, unless that screen is the most important screen of your application.
Hope you are having your logic in other than the method
- (void)viewDidLoad
move your code to - viewDidLoad
even if your are having trouble then pass the preloaded UIWebView when ever you are navigating.

PreLoad UIWebView on a not yet displayed UIViewController

I have an app where on the very last UIViewController there is a UIWebView... the user navigates through the app and at the very end they can transition (modal) to the final UIViewController with a UIWebView... in it's viewDidLoad I have the UIWebView load the page.
The problem is it takes about 8 seconds to load this page and that annoys users.
How can I load the UIWebView way ahead of time (like when the app is first launched!) if that UIViewController hasn't even been presented yet?
I had your same problem for UIWebView inside a UIPageViewController and I found a better solution.
If you are in FirstViewController and you have your webView in your SecondViewController put the loadHTMLString or loadRequest method in the viewDidLoad of your SecondViewController and call [secondViewController.view layoutSubviews] for start loading in your FirstViewController.
Ex:
FirstViewController
-(void)viewDidLoad{
[super viewDidLoad];
// _secondViewController -> An instance of SecondVieController
[_secondViewController.view layoutSubviews];
}
SecondViewController
-(void)viewDidLoad{
[super viewDidLoad];
NSURL *url =[NSURL URLWithString:#"http://www.google.it"];
NSURLRequest *request =[NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
}
What u can do is, load the html string
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:self.path ofType:#"htm"];
NSError * error;
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:&error];
and when u display the webView load this content in your webView
[self.webView loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] bundleURL]];
then your webview need only render your content and doesn't load the data
/// In Swift 2.0
do{
let path = NSBundle.mainBundle().pathForResource("theName", ofType: "html")!
let html = try String(contentsOfFile: path, encoding: NSUTF8StringEncoding)
webView.loadHTMLString(html, baseURL: nil)
}catch{
print("Error is happend")
}
Note: It works the same way for WKWebView
Not sure how much work you want to do for this but I think you could cache/store the data from the URL in something like a NSDictionary, or something similar, using [NSUserDefaults standardUserDefaults] and use that information before actually loading the page.
So, load the first time you use it, after it has been seen then store the data using NSUserDefaults. Next time you go to this page, load from the NSUserDefaults first and call the URL/API in the back ground then update NSUserDefaults with this new data.
If you are requesting or pulling specific information each time, then I don't think this will work. If that is your case, you can probably try loading the data/website in an earlier view controller (probably one that takes the user a while to navigate to) and then send that data to the webview. Something like delegate/protocol or maybe even NSNotificationCenter. Hope this helps.
UIWebView is very tricky object. Simple answer would be: no you can't.
UIWebView won't load a document or an URL if it is not in views hierarchy.
Don't try doing it in different thread/queue either.
What you can do is to add UIWebView to the views hierarchy at the very beginning (as you've mentioned) and then pass it to the last view controller with preloaded data. This may work, but it's not an elegant way.
Side questions is: why does it take 8 secs to load a page? Maybe you can download the content of this page earlier? Is it static or dynamic?

Using TableView to display PDF's in xcode

I am using storyboard in xcode to desgin my app instead of xibs. This is my first time using them and i have a question. Right now I have multiple TableViews all with multiple cells inside. What i am trying to achieve is to click on the cell and that will then load a PDF. Each cell has a pdf that it should open. Instead of using segues and linking each tableview cell to its OWN view controller which would be very redundant. Is there some code i could put it a (I think UIWebView) that would let me see what cell was clicked and load the respective PDF. Is this possible? THank you!
You can use the master detail view controller template for this, which will be easiest to set up, then you can disable the edit and the add buttons and set up your list of PDF's with an array.
Once they are all set up it will set the detail items automatically, if you don't have core data enabled you can access it by:
[self.detailItem description];
This gives you the name of the row that was clicked, which then you can use that to load the PDF to the UIWebView. The web view can load the PDF to view with:
NSString *pdfName = [NSString stringWithFormat:#"%#", [self.detailItem description]];
NSString *path = [[NSBundle mainBundle] pathForResource:pdfName ofType:#"pdf"];
NSURL *url = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[pdfViewer loadRequest:request];
[pdfViewer setScalesPageToFit:YES];
Just be sure to declare pdfViewer as your UIWebView in the detail view controller

Displaying a PDF with UIWebView Not Working

So, I realize that there have been many questions regarding using a UIWebView to display a PDF in an app (on the iPad). I have reviewed everything I can find but I can't seem to find any satisfaction.
What I'm trying to do is very basic so I really don't know why it's not working. All I need to do is display a locally stored PDF in the UIWebView. Essentially, all I'm getting is a black screen. If someone could take a look at my code, I'd really appreciate it. Thanks.
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Segue to the materials screen.
if ([segue.identifier isEqualToString:#"materials"]) {
PDFViewController *pdfViewController = [segue destinationViewController];
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
int row = [path row];
Lesson *selected = [purchasedLessons objectAtIndex:row];
pdfViewController.selectedLesson = selected ;
//Start Load PDF in UIWebView
pdfViewController.pdfWindowTitle.title = selected.titleAndSubtitle;
pdfViewController.pdfWebView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 1024, 704)];
NSString *urlAddress = [[NSBundle mainBundle] pathForResource:#"moonlightSonataFirstMovement" ofType:#"pdf"];
NSURL *url = [NSURL fileURLWithPath:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[pdfViewController.pdfWebView loadRequest:requestObj];
//End Load PDF
}
}
I've checked to see if my object is bring passed into the scene properly (and it is) and if I am getting a proper request out; i'm getting:
<NSURLRequest file://localhost/Users/MYCOMPUTER/Library/Application%20Support/iPhone%20Simulator/5.0/Applications/AB161E57-D942-44C2-AA75-030087820BED/iLessons%20Piano.app/moonlightSonataFirstMovement.pdf>
Also, I've have this error message:
iLessons Piano[23080:f803] DiskImageCache: Could not resolve the absolute path of the old directory.
Additionally, the NSLog message gets printed out 8 times for some reason.
The only thing I can think of is that I need to do this loading when I call my prepareForSegue function in the previous scene. That or use a different method like Quartz. But I'd rather use a UIWebView since all I really need to do is display and allow scrolling.
DiskImageCache: Could not resolve the absolute path of the old
directory.
This one isn't the real reason the app crashes. This warning can be fixed by assigning the view in the Storyboard. It seems like it's connected already but it's grey. So assign it again and it will be fine.
The real issue for me was that the PDF images were 300 DPI and it took too long to load the application. Since the debugger keeps the app from crashing it seems to work fine but the loading will take too long without the debugger and will result in a timeout crash.
There's a few things you can do. You can downscale your PDF which might be a good thing anyway since older device are even slower and it's nice to support those as well. But what really fixes it is by delaying the PageView initialization. Here's what I did:
In the RootViewController I moved the code from the viewDidLoad to a new function setupPageViewer.
And put this in the viewDidLoad:
[self performSelector:#selector(setupPageViewer) withObject:nil afterDelay:0.0f];
The delay 0.0 means it will be taken care of in the next frame which gives you the opportunity to show a loading indicator.
Enjoy!
im not sure about whats going on .. you view and webView both holding nil value.. as i told you im not involved in the storyBoard yet .. but you as a workaround solution maybe this fix your problem
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1027, 768)];
pdfViewController.view = view;
pdfViewController.pdfWebView = [[UIWebView alloc] initWithFrame:pdfViewController.view.frame];
NSString *urlAddress = [[NSBundle mainBundle] pathForResource:#"moonlightSonataFirstMovement" ofType:#"pdf"];
NSURL *url = [NSURL fileURLWithPath:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[pdfViewController.view addSubview:pdfViewController.pdfWebView];
[pdfViewController.pdfWebView loadRequest:requestObj];
As a workaround, you can disable or remove your 'All Exceptions' breakpoint. This might make debugging a little more difficult, but it's not as bad as having to relaunch the application all the time.
This is the breakpoint causing the issue. I had set it so long ago that I'd forgotten it was there

Resources