I have html text returned from the server and I am using a UITextView on the IOS client to render the text. I am first converting the html string to attributed string and then enumerating over the attributes and changing the font, foreground color of the text as needed. Finally I am setting the attributed text of UiTextView. However, when the html contains images and I see that they get cut off when rendered in UITextView.
Any pointers on how I could change the width and height of images contained in the html text in order to fit my phone screen width?
I use SwiftSoup to extract data from html or edit the HTML string. I also have found that when images are present it's easier to manage the layout and format inside a WKWebView.
This example also helps to add support for dark mode in your WKWebView.
var newsRssBody: String = ""
let css = "#media (prefers-color-scheme: dark) {body { background-color: rgb(38,38,41); color: white; } a:link { color: #0096e2; } a:visited { color: #9d57df; } }"
try doc.head()?.append("<style>\(css)</style>")
self.newsRssBody = "\(doc)"
The headerString line helps with content sizing based on the device.
let headerString = "<header><meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'></header>"
self.webView.loadHTMLString(headerSting + self.newsRssBody, baseURL: nil)
Related
I want to change all dataDetectorType Colour in UIWebView including PhoneNo , emailID , Calendar and every dataDetctorType. I also need Tappable link for that dataDetector link.
Adding some CSS to set the link color works, but for auto-detected links and e-mails etc it is necessary to add !important for the color to be applied.
<style>a { color: red !important; }</style>
For UITextView, you can use linkTextAttributes for this, but there is no such thing for UIWebView. You will have to add CSS to the content you are loading to style the automatically inserted A tags.
CSS example to change the detected link color:
NSString *html = #"<style>a:link { color: red; }</style> <h3>detected phone number: 111122223333</h3> <a href='www.google.com'>google link</a>";
[webView loadHTMLString:html baseURL:nil];
The result in WebView:
I find that if I use WKWebView with
viewport-fit=cover
and
body :{height:100%}
the height of html body still can not reach the bottom of iPhone X and is equal to the height of safeArea, However, the background-color can cover the fullscreen.
https://ue.qzone.qq.com/touch/proj-qzone-app/test.html
I load this page in a fullscreen WKWebView to reproduce the problem.
I was able to fix the issue with (ObjC / Swift):
if (#available(iOS 11.0, *)) {
webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
or
if #available(iOS 11.0, *) {
webView.scrollView.contentInsetAdjustmentBehavior = .never;
}
This setting seems to have the same effect as viewport-fit=cover, thus if you know your content is using the property, you can fix the bug this way.
The env(safe-area-inset-top) CSS declarations still work as expected. WKWebView automatically detects when its viewport intersects with blocked areas and sets the values accordingly.
Documentation for contentInsetAdjustmentBehavior and its parameter values and kudos to #dpogue for the answer where I found the solution.
I found setting height in CSS on the html element to be height: 100vh (rather than height: 100%) worked
In your code, if you add
opacity: 0.5;
to the html and body tags you'll see that the body tag does take the full screen while the html tag height is only as tall as the safe area.
If you just want the html area to reach the edges you can explicitly set:
<html style='height: 812px;'>
This will make the content within the html properly fit the full screen as long as you also add:
<meta name="viewport" content="initial-scale=1.0, viewport-fit=cover">
Not the most elegant solution of course, but it does work.
I cam across this issue in my Cordova app.
Samantha's solution worked for me to an extent but having a height of 812px set in the html tag was causing issues whilst in landscape and with other devices. Eventually I found that targeting just the iPhone X sized screen with css media queries for both landscape and portrait did the trick.
The width and height pixel values needed to be declared as important in order for the iPhone to accept them.
#media only screen
and (device-width : 375px)
and (device-height : 812px)
and (-webkit-device-pixel-ratio : 3)
and (orientation : portrait) {
html {
height: 812px !important;
width: 375px !important;
}
}
#media only screen
and (device-width : 375px)
and (device-height : 812px)
and (-webkit-device-pixel-ratio : 3)
and (orientation : landscape) {
html {
width: 812px !important;
height: 375px !important;
}
}
You need to set UIEdgeInsets for your web view to stretch all the way to bottom (covering the notch).
You can achieve this by creating a subclass of WKWebView!
Check this out.
Here's a UILabel which says "About". Set at exactly 17.7 in iOS.
Below it a UIWebView which also says "About". Also set at exactly 17.7 using css.
They don't match.
How to fix this correctly?
It is bizarre that in Apple's own UIWebView, the size basis is different?
Html to test...
<html><head>
<style type='text/css'>
body {
margin: 0px;
font-family: 'SourceSansPro-Light';
font-size: FONTPOINTSpt;
}
html { -webkit-text-size-adjust:none; }
</style></head>
<body leftmargin=0 topmargin=0>
About
</body></html>
Behavior is identical on device or simulator.
(Note, from here I learned the ratio is, perhaps 72.0/96.0.)
If you want a 1 to 1 relationship between the font size that the UILabel uses and the font size that the UIWebView uses (via CSS) you have to use px instead of pt when defining the font size in your CSS.
Checkout this example HTML / CSS:
<html>
<head>
<style type='text/css'>
body {
font-family: 'SourceSansPro-Regular';
padding: 0
}
.point {
font-size: 17pt
}
.pixel {
font-size: 17px
}
</style>
</head>
<body>
<p class="point">About (17pt)<p>
<p class="pixel">About (17px)</p>
</body>
</html>
When you add a UIWebView and a UILabel to your UIViewController and load the above HTML to the UIWebView and set the same font to the UILabel:
override func viewDidLoad() {
super.viewDidLoad()
let webView = UIWebView(frame: CGRect(x: 25, y: 50, width:325 , height: 90))
view.addSubview(webView)
let filePath = NSBundle.mainBundle().URLForResource("test", withExtension: "html")
webView.loadRequest(NSURLRequest(URL: filePath!))
let label = UILabel(frame: CGRect(x: 25, y: 150, width: 325, height: 40))
label.font = UIFont(name: "SourceSansPro-Regular", size: 17)
label.text = "About (UILabel set to 17)"
view.addSubview(label)
}
You get the following output:
I think your confusion was because CSS pt is a typographic point (1/72 in), but Apple's iOS documentation uses "point" (e.g. UIFont.pointSize) as "virtual pixel", which corresponds to CSS px. Judging from #joern's answer, it looks like UIWebView uses 1 css px = 1 ios virtual px. (I have not tested this.) However, in my tests with WKWebView, it looks like CSS px is equal to one device pixel. So for WKWebView, you want:
let fontSize = UIScreen.main.scale * label.font.pointSize
let cssStr = String(format:"font-size: %.1fpx;", fontSize)
Yep, its a parent font-size issue:
You should always set the font-size for body to 16px (one can set it higher if a larger base font is required, the standard is 16px).
Then, set font sizes using 16px as the base.
body {
font-size: 16px;
}
h1 {
font-size: 24px;
}
If you want both the body and the h1 font-sizes to be the same then simply set the body font-size and don't set the font-size of the h1 (it will inherit the body font-size all on its own... aka... cascading).
body {
font-size: 16px;
}
h1 {
}
What you have done is set the body font-size to a value... then set the h1 font-size to that same value, the problem is that h1 inherits the font-size from body and then goes even bigger when you assign a font-size to h1.
Hope this makes sense and helps.
My Application is using custom font ("Roboto"), I am opening a HTML page( this web page is also using Roboto font in CSS) in UIWebView within application, in which font of web page is bold.
can anyone help?, what could be the problem.
You have following solution may be any one help you.
1) Add in .css and meta tags as follow.
html {
-webkit-text-size-adjust: none; /* Never autoresize text */
}
and meta tags as follow
<meta name='viewport' content='width=device-width; initial-scale=1.0; maximum-scale=1.0;'>
2) You can also inject both into an existing website, using this javascript code as follow.
var style = document.createElement(\"style\");
document.head.appendChild(style);
style.innerHTML = "html{-webkit-text-size-adjust: none;}";
var viewPortTag=document.createElement('meta');
viewPortTag.id="viewport";
viewPortTag.name = "viewport";
viewPortTag.content = "width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;";
document.getElementsByTagName('head')[0].appendChild(viewPortTag);
and Use UIWebViewDelegate (webViewDidFinishLoad) method
- (void)webViewDidFinishLoad:(UIWebView *)webView{
NSString *javascript = #"var style = document.createElement(\"style\"); document.head.appendChild(style); style.innerHTML = \"html{-webkit-text-size-adjust: none;}\";var viewPortTag=document.createElement('meta');viewPortTag.id=\"viewport\";viewPortTag.name = \"viewport\";viewPortTag.content = \"width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;\";document.getElementsByTagName('head')[0].appendChild(viewPortTag);";
[webView stringByEvaluatingJavaScriptFromString:javascript];
}
you can implement webView delegate and change font when load webView.
func webViewDidStartLoad(webView : UIWebView) {
//your code
}
I am using a split view controller with a UIWebView in the details view. On the iPhone 6 Plus, in landscape orientation, when I dismiss the master view to expand the details view to fit the whole screen, the content of the UIWebView gets stretched rather than resized to take advantage of the additional real estate.
How can I get the UIWebView to adjust the width of the content rather than stretching/zooming it when the the popover is dismissed?
(I was originally using a UITextView in the details view and converting the HTML string to an NSAttributedString. I didn't have the stretching issue with that, but the scrolling was choppy, etc., with large amounts of text. The UITextView works much better in this regard, with the stretching being the only issue.)
Prior to dismissing popover:
After dismissing popover:
EDIT: Here the string format I am using for the content displayed in the UIWebVIew:
private static let formatStringForUIWebView: NSString =
"<html>" +
"<head>" +
" <title></title>" +
" <meta name=\"viewport\" content=\"width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0\" />" +
" <style type=\"text/css\">" +
" pre { width: auto; white-space: pre-wrap; }" +
" </style>" +
"</head>" +
"<body>" +
" <div style='color: #555555; font-size: 12px; font-family: Helvetica;'>%#</div>" +
"</body>" +
"</html>";
This might be what you're looking for. It prevents font scaling.
-webkit-text-size-adjust: none;
Here is a reference link to this css property.
https://developer.mozilla.org/en-US/docs/Web/CSS/text-size-adjust
In your HTML content, define a meta tag that will instruct it to have a view port with the width of the device width:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">