How to set initial zoom on UIWebView in xcode - objective-c

I'm wondering how to set an initial zoom on a PDF document loaded in a UIWebView in XCode. It is a table, and I want the web view to load zoomed in on a specific column (or part of a column which I can then scroll up and down). I've been reading and some people have pointed to this method - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script but I don't know exactly how this works.
And while we're on the subject of PDFs, is there any way to scrape the PDF and turn it into usable strings?
Edit: For reading a pdf, PDFBox is one possible solution. You have to import JAR files into your Xcode project. Here is a tutorial: http://www.oreillynet.com/pub/a/mac/2005/01/07/ipod_reader.html

UIWebView *webV = [[UIWebView alloc] init];
webV.scrollView.zoomScale = 4.0;

Related

How do I locate a UILabel in Xcode

I am working on someone else's project and I can't for the life of me find where the text "Frame2" is used. I ran the simulator and the debugger spit out this:
Printing description of $147:
<UILabel: 0x7f7ff655a260; frame = (0 3.5; 105 21.5); text = 'Frame2'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7f7ff65586a0>
Can that printout reveal the location?
I would create a symbolic breakpoint for setTitle on UILabel and trace where it gets called. You can follow this link for instructions on how to do that: https://www.bignerdranch.com/blog/xcode-breakpoint-wizardry/
I think we should assume that this text is set in the storyboard. The simple way to deal with this is to open the storyboard as text. It is a simple XML file, and you will then easily be able to search it and find the text "Frame2".

How to add the iOS "Open In..." feature to an app

I would like to know how to present the "Open In..." Action Sheet (iPhone) / Popover (iPad) from my app, preferably an IBAction
I would hope that it'd be similar to declaring a file type then creating the view and opening the app selected by the user, but I know it is more complicated then that.
I realize that a similar question has been asked on StackOverflow, but I cannot make sense of the answer that was accepted: How to use "open in..." feature to iOS app?, and I have found some Apple Documentation on Document Interaction Programming. But, I can't really make sense of these.
Create a UIDocumentInteractionController by using the interactionControllerWithURL: class method (pass the URL of the file you want to open in another app).
Then call either presentOpenInMenuFromRect:inView:animated: or presentOpenInMenuFromBarButtonItem:animated:. The controller takes care of presenting the popover with available apps for that file type and opening the selected app.
If you want to know when the menu was dismissed and which app was selected, you need to implement the UIDocumentInteractionControllerDelegate protocol.
omz makes some good points on how to do that in his answer, however this procedure is much easier with the introduction of new APIs in iOS 6. Here's a simple and efficient way to show the UIActionSheet Open-In-Menu in iOS 6 and up:
NSArray *dataToShare = #[contentData]; //Or whatever data you want to share - does not need to be an NSArray
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:dataToShare applicationActivities:nil];
[self presentViewController:activityViewController animated:YES completion:nil];
Also, if your app is compatible with versions of iOS lower than 6.0 you may want to check if the Share Service exists:
if ([UIActivityViewController class])
Once you present the sheet, iOS will automatically handle the rest for you. It will display a beautiful uiactionsheet with icons showing each app or service the user can open / share your data with:
Note that depending on the contents of the data, iOS will show different services in the Share Sheet
EDIT: The method above shares the file content, but not the file itself. Refer to omz's answer for more on that.
I've personally never had to do this, but your answer can most certainly be found in this Apple Documentation: http://developer.apple.com/library/ios/#documentation/FileManagement/Conceptual/DocumentInteraction_TopicsForIOS/Articles/PreviewingandOpeningItems.html#//apple_ref/doc/uid/TP40010410-SW1.

How to create Multiple Themes/Skins for iphone apps? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I have an iphone app ready and approved by the app store. Now I want to create different themes for my app. Can someone please help me out, with info/links/steps on how to create themes for my app?
I want to create a Metal theme for the Boys and a Pink theme for the Girls. Again by theme I mean, the whole app(features and functionality) is gonna stay the same, but depending on who the user is(boy or girl), he/she can choose the theme they wish to see. And when the theme changes, only the images/Background/music will change according to the applied theme.
Thanks a lot!
This is quite difficult as apps don't have the equivalent of a css stylesheet.
First you need to work out what parts of the app you want to skin, and when you want to allow the user to swap skins.
I'm going to assume that you want to change images and font colours, and that it's okay if the user has to relaunch the app to change the skin (that will make things simpler for now).
Create a plist containing all your skinnable images and colours. The plist will be a dictionary with sensible, theme neutral key names for the images and colours (e.g. don't have a colour called "red", call it "primaryHeadingColor"). Images will be file names, and colours can be hex strings, e.g. FF0000 for red.
You'll have one plist for each theme.
Create a new class called ThemeManager and make it a singleton by adding the following method:
+ (ThemeManager *)sharedManager
{
static ThemeManager *sharedManager = nil;
if (sharedManager == nil)
{
sharedManager = [[ThemeManager alloc] init];
}
return sharedManager;
}
The ThemeManager class will have an NSDictionary property called "styles", and in the init method you will load the theme into your styles dictionary like this:
- (id)init
{
if ((self = [super init]))
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *themeName = [defaults objectForKey:#"theme"] ?: #"default";
NSString *path = [[NSBundle mainBundle] pathForResource:themeName ofType:#"plist"];
self.styles = [NSDictionary dictionaryWithContentsOfFile:path];
}
return self;
}
(Note: some people don't like doing a lot of work inside an init method. I've never found it to be an issue, but if you prefer, create a separate method to load the themes dictionary and call it from your app's setup code).
Notice how I'm getting the name for the theme plist from user defaults. That means the user can select a theme in your preferences and save it and the app will load that theme next time it is launched. I've put in a default theme name of "default" if no theme is selected, so make sure you have a default.plist theme file (or change the #"default" in the code to whatever your default theme plist is actually called).
Now that you've loaded your theme you need to use it; I'm assuming your app has various images and text labels. If you're loading and laying those out in code then this part is easy. If you are doing it in nibs then it's a bit trickier but I'll explain how to handle that later.
Now normally you would load an image by saying:
UIImage *image = [UIImage imageNamed:#"myImage.png"];
But if you want that image to be themable, you'll now need to load it by saying
NSDictionary *styles = [ThemeManager sharedManager].styles;
NSString *imageName = [styles objectForKey:#"myImageKey"];
UIImage *image = [UIImage imageNamed:imageName];
That will look in your theme file for the themed image that matches the key "myImageKey" and will load it. Depending on which theme file you've loaded you'll get a different style.
You'll be using those three lines a lot so you may want to wrap them up in a function. A great idea would be to create a category on UIImage that declares a method called something like:
+ (UIImage *)themeImageNamed:(NSString *)key;
Then to use it you can just replace any calls to [UIImage imageNamed:#"foo.png"]; with [UIImage themeImageNamed:#"foo"]; where foo is now the theme key instead of the actual image name.
Okay, so that's it for theming your images. To theme your label colours, suppose you're currently setting your label colours by saying:
someLabel.color = [UIColor redColor];
You would now replace that with:
NSDictionary *styles = [ThemeManager sharedManager].styles;
NSString *labelColor = [styles objectForKey:#"myLabelColor"];
someLabel.color = [UIColor colorWithHexString:labelColor];
Now you may have noticed that UIColor doesn't have a method "colorWithHexString:" - you'll have to add that using a category. You can Google for "UIColor with hex string" solutions to find code to do that, or I've written a handy category that does that and a bit more here: https://github.com/nicklockwood/ColorUtils
If you've been paying attention you'll also be thinking that instead of writing those three lines over and over, why not add a method to UIColor called:
+ (UIColor *)themeColorNamed:(NSString *)key;
Just like we did with UIImage? Great idea!
So that's it. Now you can theme any image or label in your app. You could use the same trick to set the font name, or any number of other potentially themable visual properties.
There's just one tiny thing we've forgotten...
If you've built most of your views as nibs (and I see no reason why you wouldn't) then these techniques aren't going to work because your image names and font colours are buried inside impenetrable nib data and aren't being set in your source code.
There are a few approaches to solve this:
1) You could make duplicate themed copies of your nibs and then put the nib names in your theme plist and load them from your theme manager. That's not too bad, just implement the nibName method of your view controllers like this:
- (NSString *)nibName
{
NSDictionary *styles = [ThemeManager sharedManager].styles;
return [styles objectForKey:NSStringFromClass([self class])];
}
Notice my neat trick of using the class name of the view controller as the key - that will save you some typing because you can just make a base ThemeViewController with that method and have all your themable view controllers inherit from it.
This approach does mean maintaining multiple copies of each nib though, which is a maintenance nightmare if you need to change any screens later.
2) You could make IBOutlets for all of the imageViews and labels in your nibs, then set their images and colors in code in your viewDidLoad method. That's probably the most cumbersome approach, but at least you don't have duplicate nibs to maintain (this is essentially the same problem as localising nibs btw, and pretty much the same solution options).
3) You could create a custom subclass of UILabel called ThemeLabel that automatically sets the font color using the code above when the label is instantiated, then use those ThemeLabels in your nib files instead of regular UILabels by setting the class of the label to ThemeLabel in Interface Builder. Unfortunately if you have more than one font or font colour, you'll need to create a different UILabel subclass for each different style.
Or you could be devious and use something like the view tag or accessibilityLabel property as the style dictionary key so that you can have a single ThemeLabel class and set the accessibility label in Interface Builder to select the style.
The same trick could work for ImageViews - create a UIImageView subclass called ThemeImageView that, in the awakeFromNib method replaces the image with a theme image based on the tag or accessibilityLabel property.
Personally I like option 3 best because it saves on coding. Another advantage of option 3 is that if you wanted to be able to swap themes at runtime, you could implement a mechanism where your theme manager reloads the theme dictionary, then broadcasts an NSNotification to all the ThemeLabels and ThemeImageViews telling them to redraw themselves. That would probably only take about an extra 15 lines of code.
Anyway, there you have a complete iOS app theming solution. You're welcome!
UPDATE:
As of iOS 5, it's now possible to set custom attributes by keyPath in Interface Builder, meaning that it's no longer necessary to create a view subclass for each themable property, or abuse the tag or accessibilityLabel for selecting styles. Just give your UILabel or UIImageView subclass a string property to indicate which theme key it should use from the plist, and then set that value in IB.
UPDATE 2:
As of iOS 6, there is now a limited skinning system built into iOS that allows you to use a property called the UIAppearance proxy to skin all instances of a given control class at once (there's a good tutorial about the UIAppearance APIs here). It's worth checking if this is sufficient for your skinning needs, but if not, the solution I outlined above still works well, and can be used instead, or in combination with UIAppearance.

How does iBooks do this?

I am currently displaying text in a uiwebview. However, I would like to allow a user to select text and perform some action with the selected text (google it). Apple has done this sort of thing with iBooks. When you click on a word you can choose to look up the word in a dictionary. How can I do the same thing with Webview?
UIMenuController seems to be what I need to look at. But I couldn't find any sample code on how to do this. I'm new to iPhone development please help.
Starting in iOS 3.2 you can use UIMenuController to add additional UIMenuItems to the system menu that appears when selecting text in a UIWebView. Here's a simple example:
- (void)viewDidLoad {
[super viewDidLoad];
UIMenuItem *defineItem = [[[UIMenuItem alloc] initWithTitle:#"Define" action:#selector(defineSelection:)] autorelease];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObject:defineItem]];
}
- (void)defineSelection:(id)sender {
NSString *selection = [webView stringByEvaluatingJavaScriptFromString:#"window.getSelection().toString()"];
// Do something with the selection
}
Apple describes how this works in the Adding Custom Edit Menu Items section of the Device Features Programming Guide.
This recent blog post from a developer would seem to suggest that at least in the iPad iOS branch, some iBooks functionality is based on private APIs.

Cocoa button won't display image

Just started exploring Cocoa so pretty much a total noob.
I've written a very simple game. Set it up in Interface Builder and got it working fine.
It contains a number of buttons and I'm now trying to get the buttons to display images.
To start with I'm trying to get an image displayed on just one of the buttons which is called tile0 .
The image file (it's nothing but a green square at the moment, but I'm just trying to get that working before I attempt anything more exotic) is sitting in the same directory as the class file which controls the game.
I have the following code sitting in my wakeFromNib method:
NSString *myImageFileName = [[NSString alloc] init];
myImageFileName = #"greenImage.jpg";
NSImage *myImage = [[NSImage alloc] initByReferencingFile:myImageFileName];
[tile0 setImage: myImage];
Trouble is, the game runs fine, but the image isn't appearing on my button.
Is there someone who could kindly tell me if I'm doing something obviously wrong?
Many Thanks.
The first problem is you allocate a string but then replace it with a string constant. That isn't causing your image problem but it is a memory leak.
I've never used initByReferencingFile, I usually just use imageNamed:. There is an example of using imageNamed here.