I need to download a file from api like
http://52.76.226.179/aapc-social-web/sites/default/files/media_docs/2009/content-601938936.ppt
and display a preview of that in my ios app.
Please help.
I have used the quick look framework and UIDocumentInteractionController show me something like this. please see the image and suggest something.
import this pkg
#import <QuickLook/QuickLook.h>
Use this code in View controller.
QLPreviewController *previewController=[[QLPreviewController alloc]init];
previewController.delegate=self;
previewController.dataSource=self;
previewController.view.frame = self.conditionsofUseView.bounds;
[self.conditionsofUseView addSubview:previewController.view];
[self addChildViewController:previewController];
[previewController didMoveToParentViewController:self];
[previewController.navigationItem setRightBarButtonItem:nil];
Add These Delegate methodes
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller
{
return 1;
}
- (id <QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
{
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"docFileName" ofType:#"file type"]; //doc,ppt,pdf etc
return [NSURL fileURLWithPath:filePath];
}
[UIDocumentInteractionController][1] Is what you are looking for.
The main difference respect QLPreviewController, is that it can display a preview and also it can display a UiActionSheet or popover showing the applications compatible with that format and delegate the display of the document to them.
It's super easy to use it. Check here
.
If you just want to view the Office files, have a look at:
Document Interaction Programming Topics for iOS: Quick Look Framework.
Quick Look Framework Reference
Quick Look Framework supports a lot of file formats as you can see in the links above. It is available in iOS 4.0 and later.
You can also use UIWebView to display them. See Using UIWebView to display select document types.
Related
I am using the UIDocumentationInteractionController to show the sharing options for a PDF document. (See image below) Everything is working as expected except for the Add Tags option
Tapping on it immediately dismisses the controller modal view instead of showing another popup for selecting the tags.
I also see this error on the console when I perform the above workflow.
DocInteractionTest[7132:5381612] Warning: Attempt to present <_UIRemoteViewController: 0x118003a00> on <UIActivityContentViewController: 0x116000000> whose view is not in the window hierarchy!
I believe that this happens as the modal view gets dismissed before the Add Tags modal is getting added on the view hierarchy stack. However, I am unable to understand why is this happening? Has anyone else also seen this similar issue in the past?
It would also be fine for me to hide that option (Add Tags) but I doubt that is possible since Apple doesn't expose any APIs to do this.
Here is some sample code that I have to launch the document interaction controller modal view (I have only included the relevant parts)
#interface ViewController () < UIDocumentInteractionControllerDelegate>
#property (nonatomic, strong) UIDocumentInteractionController *shareDocumentInteractionController;
#end
#implementation ViewController
- (void) showShareMenu:(id) sender {
NSURL* url = [NSURL fileURLWithPath:[self getPDFPath]]; // pdf document path on disk
self.shareDocumentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:url];
self.shareDocumentInteractionController.delegate = self;
self.shareDocumentInteractionController.UTI = #"com.adobe.pdf";
[self.shareDocumentInteractionController presentOpenInMenuFromBarButtonItem:sender animated:YES];
}
#end
It would also be fine for me to hide that option (Add Tags) but I doubt that is possible since Apple doesn't expose any APIs to do this.
With regards to the above comment from me in my question, I happen to stumble upon this apple post which talks about best practices as to where should you save the app documents for your app. Reading this post led me to realize that we can show a different modal menu depending on where we save the PDF document and reference it for the UIDocumentInteractionController.
When I posted the sample code above, I was saving the PDF document in the NSDocumentDirectory. However, changing it to NSCachesDirectory shows me a different menu (without the Show Tags option which is what I want). Also, for my specific use case, saving the PDF document temporarily in the Caches directory is just perfect.
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
New Modal Menu:
It would be great if someone would still be able to answer why the modal disappears but I am fine with hiding this Show Tags option for now.
I am struck with this past two days i don't find any proper documents relating to CGPDF. I tried every possible way but i failed. Here is what i am trying to do. I have a PDF to display and i am displaying it in a UIWebView. I have created a CORE GRAPHICS PDF document reference using the path where the pdf is located (NSURL). I created a UIView over it and handled a single touch event. When the PDF loads and user clicks the view i want the page to scroll to a specific page. I know this can be done via calculating Page height and width. I wanted to know if there is a Way in CGPDF to pass a page number and it scroll to the relevant page. Below is my Code
- (void)viewDidLoad
{
[super viewDidLoad];
// set the pdfPafeHeight to -1 so it gets calculated.
self.pdfPageHeight = -1;
// set the delegate of the UIWebView's underlying UIScrollView to self.
self.webView.scrollView.delegate = self;
// create an NSURLRequest to load the PDF file included with the project
_filePath = [[NSBundle mainBundle] pathForResource:#"Sample" ofType:#"pdf"];
_url = [NSURL fileURLWithPath:_filePath isDirectory:NO];
_urlRequest = [NSURLRequest requestWithURL:_url];
// create a Core Graphics PDF Document ref using the same NSURL
_pdf = CGPDFDocumentCreateWithURL((CFURLRef) _url);
// use CGPDFDocumentGetNumberOfPages to get the number of pages in the document
self.pdfPageCount = (int)CGPDFDocumentGetNumberOfPages(_pdf);
// load the PDF file into the UIWebVie
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleFingerTap];
[self.webView loadRequest:_urlRequest];
}
HERE IS HOW I WANTED HANDLE SINGLE TAP ON UIVIEW. I just wanted to know if there is any method in CGPDF to scroll to specific page when i pass a page number to it
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
}
There's no API for what you're trying to achieve, and even if you're able to use private API if this app is just for Enterprise install and doesn't need to go to the App Store - this will be tricky and any workaround will likely break with a major iOS version update. If you want to go this route, you can introspect the view controller hierarchy and will find that Apple internally has a framework called CorePDF which has an internal private API that you might be able to access - but be careful and know that this is not a solution for App Store apps.
The alternative is to start from scratch and use CGContextDrawPDFPage to draw PDF pages, building your own cache, scroll views and view controllers+gesture handling. We did that with the commercial PSPDFKit SDK which I work on since 2010 - it's more work than you'd think. We also eventually moved on and use a custom renderer to improve compatibility with the wide range of PDF files available and to offer a better performance than Apple's renderer, however not every use case might require this.
I am trying to create an Appcelerator IOS module, basically its a conversion of an App in Native to Appc module.
The Native Project has been created using XIBs.
So far i created a Proxy and used that view proxy to fetch the XIB using
[[ViewController alloc] initWithNibName:#"ViewController" bundle: bundle];
I have converted the xibs to Nibs and have put them in the Asset folder of the Project invoking the module.
By doing all this i have been able to render the ViewController screen.But no events are working on this screen.
Here is the code rendering the second xib :
- (IBAction)handleStinkyClick:(id)sender {
firstScreen *fs=[[firstScreen alloc]initWithNibName:#"firstScreen" bundle:nil];
fs.modalTransitionStyle=UIModalTransitionStyleFlipHorizontal;
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]);
[self presentViewController:fs animated:YES completion:nil];
}
Is there anything i am missing?
Any help will be appreciated.
I will ask an iOS engineer of use to have a look, but you might be interested in trying out Hyperloop for iOS, which lets you require XIBs and mix and match Ti.UI.View and native code.
http://labs.appcelerator.com/project/55f74a9f421c44837717716b/Hyperloop-Module
I am new to iOS app development and I just tried using UIWebView to display a mobile website in my app and was not quite successful.
What I did is just some minimal Xcode project configuration and coding that I found during some Googling efforts:
Create a new iOS application project in Xcode using the Single View
Application template.
Drag a Web View from the Object Library to the View Controller
scene of Main.storyboard.
While holding down the Control key, drag the Web View from the View
Controller scene to the ViewController.h editor, resulting a
source code line like this:
#property (weak, nonatomic) IBOutlet UIWebView *myWebView;
Add the following code in ViewController.m:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSURL *url = [NSURL URLWithString:#"http://www.amazon.com"];
[self.myWebView loadRequest:[NSURLRequest requestWithURL:url]];
}
This is all what I did (and also everything those tutorials told me). After I built and ran the app (on simulator and on real iphone device), the site did load in the app's view (and did load the mobile version instead of the PC version), but it displayed the site as if the view were much larger than the actual iphone screen. Here is a screeshot (Amazon in this case but basically the same for other sites):
What should I do to make the iOS UIWebView display a mobile website correctly?
Just tried Dipen Chudasama's suggestion of disabling the "User Size Classes" option, for the first time of all those suggestions, the result did change a little bit (from left-align to sort of center-align), but still not what I am looking for. Here is the screenshot:
EDIT:
Thanks for all the suggestions given by you enthusiastic people. Loading a site like amazon.com in a UIWebView should be a rather easy task as I understand, nevertheless, I didn't succeed with any of the suggestions.
It would be great if anyone could share with me (via Github or alike) just an sample xcode project (starting from scratch with the latest version of xcode tool chain) with nothing but a UIWebView that could load amazon.com correctly. That way I can do a line by line diff and may be able to find what I did wrong in my own project.
The UIWebView has a property called "scalesPageToFit":
self.myWebView.scalesPageToFit = YES;
self.myWebView.contentMode = UIViewContentModeScaleAspectFit;
should do the trick.
You can scale the page to fit the screen width with this UIWebview property webView.scalesPageToFit = YES;
Otherwise you can run a js command in the UIWebView to do the scale:
NSString *js = [NSString stringWithFormat:#"document.body.style.zoom = 0.8;"];
[webView stringByEvaluatingJavaScriptFromString:js];
I got it..you just set iPhone size view in storyboard instead of any size, means disable Use Size Classes Check box and see, this will work..:)
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:#"http://www.amazon.com"];
[self.myWebView loadRequest:[NSURLRequest requestWithURL:url]];
}
Thats it, Try this one only.
OR
you have to set appropriate constraint for this.
I had the same issue as you #goodbyeera, and then realized I hadn't set the AutoLayout constraints on the UIWebView. Therefore, when the WebView loaded it was too big for the iphone screen. By adding the constraints to fit the UIWebView to the screen fixed it all. Hope this might help you.
I want to allow a user to associate a zoom factor with a document and use it as a starting point when displaying that document inside a UIWebView. It seems, however, that webViewDidFinishLoad: only indicates the end of in-memory loading, not including rendering or layout. Here's sample code to demonstrate the problem:
- (void)viewDidLoad {
[super viewDidLoad];
UIWebView *webView = (UIWebView *)self.view;
webView.delegate = self;
webView.scalesPageToFit = YES;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSString *urlString = [[NSBundle mainBundle] pathForResource:#"Doc" ofType:#"pdf"];
NSURL *file = [NSURL fileURLWithPath:urlString];
[(UIWebView *)self.view loadRequest:[NSURLRequest requestWithURL:file]];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if (!webView.isLoading) {
[webView.scrollView setZoomScale:1.5 animated:YES];
}
}
The call to setZoomScale: executes with no effect (i.e. the file is displayed with a zoom factor of 1.0), apparently because it happens before the scroll view is in some state where it can deal with it. If I change the final method above to what follows, everything works as I'd hoped.
- (void)delayedZoomMethod {
[((UIWebView *)self.view).scrollView setZoomScale:1.5 animated:YES];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[self performSelector:#selector(delayedZoomMethod) withObject:nil afterDelay:1.0];
}
This, of course, is a bad idea because the 1.0 delay is arbitrary, probably too long for the vast majority of cases, and will likely be too short under some unknown set of conditions.
The docs say, "Your application can access the scroll view if it wants to customize the scrolling behavior of the web view." Does anyone know of a notification, or property in the web view or its scroll view, that I could observe to be told when that statement becomes true?
If you have control of the html code this may help. I've been able to have html events trigger objC methods in the following manner.
html event triggers javascript that writes a string to window.location
the uiwebview then uses uiwebviewdelegate to receive the string with this function
webView:shouldStartLoadWithRequest:navigationType:
It's kind of hacky.
But I don't think there is a way to know the web view has finished rendering, unless you wrote the html page and can put a js function in to execute at the end of the page.
If you are using UIWebView to preview PDF files, then it may not be the best way. There is a QLPreViewController (from iOS 4.0) that is intended for this purpose. A Quick Look preview controller can display previews for the following items:
iWork documents
Microsoft Office documents (Office ‘97 and newer)
Rich Text Format (RTF) documents
PDF files
Images
Text files whose uniform type identifier (UTI) conforms to the
public.text type (see Uniform Type Identifiers Reference)
Comma-separated value (csv) files
If I change the final method above to what follows, everything works
as I'd hoped.
This, of course, is a bad idea because the 1.0 delay is arbitrary,
probably too long for the vast majority of cases, and will likely be
too short under some unknown set of conditions.
The docs say, "Your application can access the scroll view if it wants
to customize the scrolling behavior of the web view."
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if (!webView.isLoading) //WEBDIDFINISHLOAD? {
[webView.scrollView setZoomScale:1.5 animated:YES];
}
}
look, the didFinishLoadMethod is called by an asynchronous notification from NSURLConnection,
its not necessarily in the main thread (since your UI update is not working)
The performSelector..after delay method is fine. The delay doesnt even really mean anything,
You are just jumping to the main thread to do your UI update and allowing the
NSURLConnection notification to complete.
It probably wouldnt matter if you said afterDelay:0.0
This is a common situation in iOS and OSX, you have to figure out what threads are capable of updating the UI, GCD, NSOperationQueues, and background runLoops on created threads all complicate this.
You found your solution, but you need to know what it means. Do the call to performSelector on mainThread, set a short delay and its fixed.