The problem:
I am trying to resize the text / content that is being displayed in a WKWebView. The content itself is loaded from a remote source (via loadHTMLString), so I cannot change the css.
I already tried most other solutions I could find on stack overflow (like https://stackoverflow.com/a/43694902/1673377), but none seem to work.
Some background:
Xcode 9.2, Swift 4, iOS 10 / 11.
To monitor the content size, I used the code taken from here: https://stackoverflow.com/a/41511422/1673377
lazy var webView: WKWebView = {
//Javascript string
let source = "window.onload=function () {window.webkit.messageHandlers.sizeNotification.postMessage({justLoaded:true,height: document.body.scrollHeight});};"
let source2 = "document.body.addEventListener( 'resize', incrementCounter); function incrementCounter() {window.webkit.messageHandlers.sizeNotification.postMessage({height: document.body.scrollHeight});};"
//UserScript object
let script = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
let script2 = WKUserScript(source: source2, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
//Content Controller object
let controller = WKUserContentController()
//Add script to controller
controller.addUserScript(script)
controller.addUserScript(script2)
//Add message handler reference
controller.add(self, name: "sizeNotification")
//Create configuration
let configuration = WKWebViewConfiguration()
configuration.userContentController = controller
return WKWebView(frame: CGRect.zero, configuration: configuration)
}()
To disable zooming, I also evaluate the following JavaScript:
"var meta = document.createElement('meta');meta.setAttribute('name', 'viewport');meta.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no');document.getElementsByTagName('head')[0].appendChild(meta);"
(I tried playing around with the values for initial-scale and maximum-scale, but to no avail.)
Any help would be greatly appreciated!
Basic Goal
If you want to change the font size, you somehow need CSS. Your goal therefore should be to inject the following 2 lines somewhere in the html header:
<link rel='stylesheet' href='style.css' type='text/css'>
<meta name='viewport' content='initial-scale=1.0'/> // This may help with scale
If you add a style.css file to your project, it now should be respected.
Actual implementation
I don't know how the html you receive from the server is configured, but you could try to manipulate it a bit like this before loading it onto the WKWebView:
let customHeader = <link rel='stylesheet' href='style.css' type='text/css'><meta name='viewport' content='initial-scale=1.0'/>
let newHtml = serverHtml.replacingOccurrences(of: "<head>", with: "<head>" + customHeader)
Related
In Webview props I set the scalesPageToFit prop to false.
In android OS I get nice and good view of the webview.
but on IOS I get small view of the webview as shown in desktop, because this prop is not supported in IOS.
I tried to add the property contentMode={'mobile'} but no change.
is there any other prop that might do the job or is there anything else that could help?
Environment:
OS: Ios
OS version: *
react-native version: 0.63.4
react-native-webview version: 10.9.2, 11.0.0
I used injectedJavaScriptBeforeContentLoaded as prop of the webview and injected meta label to the head tag of the html.
this is the code I injected
setTimeout(function () {
var met = document.createElement('meta');
met.content = 'width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1';
met.charset = 'UTF-8';
met.name = 'viewport';
var head = document.getElementsByTagName("head")[0];
head.append(met);
}, 500)
Uri's example worked and as I dug into this more to find out why I simplified the solution for my project. I had control of the html the device was trying to show so I changed the meta tag to:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
I found this on w3 schools article on viewports https://www.w3schools.com/css/css_rwd_viewport.asp
You could use Uri's meta code to insert the above if needed.
Here's what worked for me:
My webview:
<View style={styles.viewWrapper}>
<WebView onNavigationStateChange={this.onNavigationStateChange} ref=.
{this.WEBVIEW_REF} style={styles.webviewStyle} source={{ uri:
this.state.link }} />
</View>
My styles:
import {
Dimensions
} from 'react-native';
const deviceHieght = Dimensions.get('window').height;
const webViewHieght = deviceHieght-80;
viewWrapper: {
height: webViewHieght
},
webviewStyle: {
width: '100%',
height: 50000,
flex: 1
},
The reason why I'm subtracting 80 from deviceHeight is because of the size of my header. I've set the height of my webviewStyle very high because I have a long webpage that I want people to be able to scroll down. The page this webview is in has an outer view with a flex of 1.
So basically, for your needs I would just modify this to be whatever height and width you want.
I'm loading Youtube video inside UIWebView using following code.
let videoUrl = "https://www.youtube.com/embed/F9GujgK0y2M"
let embedHTML = "<iframe width=\(self.webView.frame.size.width)\" height=\(self.webView.frame.size.height)\" src=\(videoUrl)?&playsinline=1\" frameborder=\"0\" allowfullscreen></iframe>"
Starting thumbnail for video is very large. I need to fit it according to size of UIWebView. Please help me, How can I change it ?
maybe this code can help you:
let yourVideoID = "F9GujgK0y2M"
let css = ".video-container {position:relative;padding-bottom:56.25%;height:0;overflow:hidden;} .video-container iframe, .video-container object, .video-container embed { position:absolute; top:0; left:0; width:100%; height:100%; }"
let url = "https://www.youtube.com/embed/\(yourVideoID)?playsinline=1&modestbranding=1&showinfo=0&rel=0&showsearch=0&loop=1&iv_load_policy=3"
let htmlString = "<html><head><style type=\"text/css\">\(css)</style></head><body><div class=\"video-container\"><iframe src=\"\(url)\" frameborder=\"0\"></iframe></div></body></html>"
yourWebView.scalesPageToFit = false
yourWebView.allowsInlineMediaPlayback = true;
yourWebView.loadHTMLString(htmlString, baseURL: nil)
Try this:
webView.scalesPageToFit = true
From Apple Documentation, setting this to true scales the webpage to fit the screen.
For me, removing the height and width properties in the iframe HTML tag made the frame fit the page width altogether.
I am trying to embed a video from youtube with the following code:
func setUpVideo() {
let width = webView.frame.width
let height = webView.frame.height
let frame = 0
bmiWebView.allowsInlineMediaPlayback = true
let videoUrl = "https://www.youtube.com/embed/GCALWdwKr48"
let htmlUrl = "<html><body><iframe width=\(width) height=\(height) src=\(videoUrl)?&playsinline = 1 frameborder=\(frame) allowfullscreen></iframe></body></html>"
webView.loadHTMLString(htmlUrl, baseURL: NSBundle.mainBundle().bundleURL)
}
I'm able to load the video initially with white background but when it loads it looks like below. I'm not sure why there is a white background. If someone can tell me how to remove that will be really helpful. Thank you.
The white background is the margin on the body of the HTML of your UIWebView.
Add some CSS to set the margin to 0 like so:
<html>
<head>
<style>body{margin:0px;}</style>
</head>
<body>
<iframe width=\(width) height=\(height) src=\(videoUrl)?&playsinline = 1 frameborder=\(frame) allowfullscreen></iframe>
</body>
</html>
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
}
How can I avoid fullscreen when playing a video in Swift 2.0?
let Code:NSString = "<iframe width=255 height=135 src=http://www.youtube.com/embed/eVk3TMB1JWY?autoplay=1&fs=0 frameborder=0 allowfullscreen=false></>"
I both tried fs=0 and allowfullscreen=false but neither work.
When the video shows up in my webview, the info about the video is also shown; how can I avoid this too?
From what you're describing, it sounds like you want to play the video "inline." Pass in whatever width and height values you want into the UIWebView constructor to allow inLine playback without the video popping open to its full screen player.
let webView = UIWebView(frame: self.view.frame) // or your custom CGRect
self.view.addSubview(webView)
self.view.bringSubviewToFront(webView)
webView.allowsInlineMediaPlayback = true
webView.mediaPlaybackRequiresUserAction = false
let videoID = "zN-GGeNPQEg" // https://www.youtube.com/watch?v=zN-GGeNPQEg
let embededHTML = "<html><body style='margin:0px;padding:0px;'><script type='text/javascript' src='http://www.youtube.com/iframe_api'></script><script type='text/javascript'>function onYouTubeIframeAPIReady(){ytplayer=new YT.Player('playerId',{events:{onReady:onPlayerReady}})}function onPlayerReady(a){a.target.playVideo();}</script><iframe id='playerId' type='text/html' width='\(self.view.frame.size.width)' height='\(self.view.frame.size.height)' src='http://www.youtube.com/embed/\(videoID)?enablejsapi=1&rel=0&playsinline=1&autoplay=1' frameborder='0'></body></html>"
webView.loadHTMLString(embededHTML, baseURL: NSBundle.mainBundle().resourceURL)
You just need to delete allowfullscreen from the link. Your link will look like this:
http://www.youtube.com/embed/eVk3TMB1JWY?autoplay=1&fs=0 frameborder=0 >