Dynamic font size in UIWebView - ios

I have in my application a UIWebView that is it used often to display informatin to the user.
I have a requirement that is that the user should be able to change the font size of that web view to display the text bigger or smaller.
What I've done is to hook up two buttons in my ViewController that calls a JS script in my web view that changes the HTML body font size.
It is working nice, but if the user changes in the iPhone Settings the text size it doesn't affect my web view fonts.
Is it possible to use something like the methods preferredFontForTextStyle in a UIWebView natively?

NSString *jsForTextSize = [[NSString alloc] initWithFormat:#"document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust= '%f%%'", changeFontSize*100/defaultFontSize];
[self.webView stringByEvaluatingJavaScriptFromString:jsForTextSize];

Related

How to get iOS font size and set it to all labels of the app?

I want to make an app, where font size increase or decrease according to font size maintained in iOS in Settings. If you change font size of your iOS from settings, whatsapp font size displayed accordingly, I want same functionality.
The iOS functionality you're looking for is the Dynamic Type that only works for text with implemented text styles.
Basically, you must :
Use the text styles but beware, their availability depends on your iOS version.
Tick the adjustsFontForContentSizeCategory property (since iOS 10) in your interface builder or implement it in code so as to tell the system to handle automatically the Dynamic Type for the object it belongs to (text styles must be used of course).
Adapt all your constraints to the different sizes your app may encounter.
You can also follow the notifications related to the Dynamic Typeevents as indicated below :
Everything is well explained in this WWDC video detailed summary where all the contents and their video timelapses are indicated to reach rapidly the information.
There's also the possibility of adapting the graphical elements size as well with a Dynamic Type implementation.
All you have to do if to use Dynamic Type for your labels. This means not to set it explicitly but to use styles like Header 1 or caption. This styles are depends on user setting in Accessibility and will change automatically. https://www.raywenderlich.com/77092/text-kit-tutorial-swift
You can use system default sizes for Texts, like,
self.label.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
Please find documentation here.
For other components you can use like labelFontSize() and many more,
+ (CGFloat)labelFontSize;//Returns the standard font size used for labels.
+ (CGFloat)buttonFontSize;//Returns the standard font size used for buttons.
+ (CGFloat)smallSystemFontSize;//Returns the size of the standard small system font.
+ (CGFloat)systemFontSize;//Returns the size of the standard system font.

How to make iOS UIWebView display a mobile website correctly?

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.

UIWebView with dynamic height leads to memory crash

I've a native iOS screen with UITableView inside that displays some article. Some cells in this table display article image, title, author, comments, etc. But there is a single cell with UIWebView inside that displays article content. This cell has dynamic height depending on the content size. Article content goes from the server as html string in JSON response and may contain images, videos and other things that supports HTML format. I can edit this string using regular expressions depending on some requirements (for example increase font size depending on app settings). Here is an image representing my UI structure:
The problem is that once the article content is very large, UITableView cell with UIWebView inside becomes also very large in height and this leads to memory crash. In my case this crash happens only on iPhone 6 Plus. On all of the other devices including iPhone (5, 5S, 6), iPad (2, 3, 4) (and probably other devices that supports iOS 7) app works correctly. As I suspect the reason is that iPhone 6 Plus has a high resolution screen and only 1 Gb of memory. So rendering the same content with the same amount of memory as in other devices, but in larger resolution, leads to memory crash.
I've created two test applications with UI as in the image below:
Both apps load the same HTML content in a single UIWebView. There is no other ui or logic in both apps.
In case a) all works correctly, scroll indicator appears and only visible content are rendered. When I'm scrolling fast, I can see white space that after a moment replaces with rendered content.
In case b) UIWebView stretches to fit content size. Test app is crashes (as my real app). As I suspect in this case even invisible content rendered and that leads to memory crash.
So my question is:
How can I fix this bug without scrolling inside UIWebView? Only UITableView should be scrollable
Make your UITableViewCell reusable. i-e(UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];).
one thing very important don't use [UIimage imagenamed:#"Imagename.jpg"] which leads you to a memory crash, you can use [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Imagename" ofType:#"png"]];.
I hope it might help.
You can give webview constant height. it has scrollviewer inside. otherwise it is really hard to render large content at once. if you give webview constant size(max value) white spaces will be removed too.
edit: webviews own scrollview should work fine with tableviews scrollview bu i am not sure

How to calculate scrollWidth of HTML page for fixed height without using UIWebView

We can use the following to calculate the scrollWidth of an HTML page in a UIWebView with a fixed height.
[webView stringByEvaluatingJavaScriptFromString:#"document.documentElement.scrollWidth"]
Is it possible to do this evaluation on local HTML pages without loading a request into a UIWebView?
Would like this to occur on a separate thread.
No(sort of). The html would need to be rendered in some capacity to be able to get any kind of measurements. The reason for this is inherent in the way html/css/javascript work together (javascript modifies html/css properties, css modifies html). If you had to get the width without using a UIWebView, you would be stuck with one of two options:
Render the page yourself, whether it's with your custom code (thousands of man hours, don't do this) or some open source library. I doubt this will be any faster than UIWebView, and will likely introduce unexpected bugs.
Measure the page in the background, and store that value somewhere. This would basically be a form of caching for the size. If the pages are static from when you ship, just do it manually, and hard code it. If they are dynamic, write a class to measure them on startup and store the value. The dynamic measurement would require UIWebView
EDIT:
Are you trying to do this because UIWebView is blocking you're main thread, causing jerkiness in your app? If so, have you considered trying something like this?:
UIWebView *webview = [[UIWebView alloc] initWithFrame:CGRectMake(0,0,320,460)];
webview.delegate = self;
[webview loadRequest: [NSURLRequest requestWithURL:[NSURL urlFromString:#"/path/to/file.html"]]];
... and then later on...
- (void) webViewDidFinishLoad:(UIWebView *)webView
{
// run your code to get scroll width of page
}

iOS: Web preferences for UIWebView?

On Mac OS/X, you can programmatically set the default font and many other values in a WebView by settings its web preferences.
Thanks.
To set the font you could just use CSS and JavaScript. Do the following in the UIWebView page loaded delegate event to set the default font size on any page:
NSInteger fontSizePercent = 150;
NSString *script = [NSString stringWithFormat:#"document.getElementsByTagName('head')[0].innerHTML += '<style>body {font-size: %i%% !important}</style>'", fontSizePercent];
[webView stringByEvaluatingJavaScriptFromString:script];
Only problem is that you may get a flash of the normal font size briefly before your script is run.

Resources