How to vertically center the text in WKWebView? - ios

I am using WKWebView in my iOS (swift) app and i am using loadHTMLString(string, baseURL: ). Now the problem is that I want the HTML to be vertically centered in the frame. The text is variable in length. How can I do that?
This is the screenshot of the HTML from Xcode:
This is image of the output. The top HTML is on the upper side, I want it to be centrally aligned in its view (the view is 300 points from the top):

Try using this HTML with inline CSS, you can replace the stuff in between the divs that you want centered:
<div style="display:flex;align-items:center;height:100%;justify-content:center;">
<p>You content here</p>
</div>
This code works for me using Swift 3.0 on an iPhone 6 simulator
import UIKit
import WebKit
class ViewController: UIViewController {
var webView:WKWebView?
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
webView = WKWebView(frame: self.view.frame)
self.view.addSubview(webView!);
addHTML()
}
func addHTML() {
let html = "<html><body><div style='height:100%;background-color:black;display:flex;align-items:center;justify-content:center;'><p style='color:white;font-size:100px;'>Asleepace</p></div></body></html>";
webView!.loadHTMLString(html, baseURL: nil)
}
}
Example Output

Related

Preventing WKWebView from automatically highlighting plain text as clickable URL

I have the following HTML content to be rendered in a WKWebView:
<html>
<body>
<div>Here goes plain text google.com type of content</div>
</body>
</html>
If I load it in Safari, it's rendered as expected:
But if I load it in my iOS app in a WKWebView using webview.loadHTMLString method, it automatically highlights the url and makes it clickable:
webview.loadHTMLString("<html><body><div>Here goes plain text google.com type of content</div></body></html>", baseURL: nil)
How can I prevent this behavior?
You either create your wkwebview from your own empty configuration like below
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate {
var webView: WKWebView!
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
webView.loadHTMLString("<html><body><div>Here goes plain text google.com type of content</div></body></html>", baseURL: nil)
}
}
Or you if you are using storyboard, please disable link detector in xcode attributes inspector

How to make transparent background WKWebView in Swift

I want a transparent web page in swift, so I have tried the below code according to this answer. Still, I am not getting a transparent web page. nothing changes in webview colour.. may I know why??
where am I going wrong? please help me in below code.
Total code:
import UIKit
import WebKit
class WebviewViewController: UIViewController {
#IBOutlet weak var testWebView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
guard let url = URL(string: "https://developer.apple.com/swift/") else { return }
let request = URLRequest(url: url)
testWebView.load(request)
// Do any additional setup after loading the view.
self.testWebView = WKWebView()
self.testWebView!.isOpaque = false
self.testWebView!.backgroundColor = UIColor.clear
self.testWebView!.scrollView.backgroundColor = UIColor.clear
}
}
Please help me with the code.
the code to make transparent background is as follow what you already added.
self.testWebView!.backgroundColor = UIColor.clear
now question is you added right code already then why you are not getting reliable output ..?
Also , if you try
self.testWebView!.alpha with any value, it will affect all of WebPages as WkWebView is a single view and changing it's alpha will also affect the components within...
it happened because the page you load in WebViewController has some HTML and CSS code, you make your WebViewController transparent but because of that HTML &CSS you can't see it's transparency as each webpage has it's own background color settings (which is merely impossible to change for each webpage)
I hope you will understand and it will help you ...:)
as I see, you use storyboard (#IBOutlet) and you can use Storyboard for setting your WKWebView:
And about code. This is enough for the result. You shouldn't set again self.testWebView = WKWebView(), because you use storyboard and you can set isOpaque with storyboard. As result:
class ViewController: UIViewController, WKNavigationDelegate {
#IBOutlet var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self
let url = URL(string: "https://developer.apple.com/swift/")!
webView.load(URLRequest(url: url))
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
let js = "(function() { document.body.style.background='transparent'; })();"
webView.evaluateJavaScript(js) { (_, error) in
print(error)
}
}
}
and evaluateJavaScript helped to add transparency for background:

How do I make my ImageView scrollable without affecting the rest of the view?

How Do I add multipleImages for the top part and have it scrollable without moving the rest of the content? Also, how do I have the little dots at the bottom to indicate which image I'm on? My code for the image is down below.
import SDWebImage
#IBOutlet weak var headerImage: UIImageView!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let imageUrl:NSURL? = NSURL(string: headerPhoto!)
if let url = imageUrl {
headerImage.sd_setImage(with: url as URL!)
}
}
You are looking for something called image slide show or image slider.
Instead of creating them by yourself which requires lots of effort, here is a GitHub library that is easy to use.
Basicly the way slider works is that it is a horizontal scroll view and each cell in the scroll view is an image so that you can scroll. Then, put a fixed page index element on the bottom of the scroll view to tell you which image you are currently at.
To use it, create a UIView in your viewcontroller and set both class and module to ImageSlideshow. Then connect it to your ViewController.swift as IBOutLet.
Then create an array of image urls
let alamofireSource = [AlamofireSource(urlString: "imgurl1")!, AlamofireSource(urlString: "imgurl2")!, AlamofireSource(urlString: "imgurl3")!]
And finally in your viewDidLoad() function:
override func viewDidLoad() {
super.viewDidLoad()
slideshow.backgroundColor = UIColor.white
slideshow.slideshowInterval = 5.0
slideshow.pageControlPosition = PageControlPosition.underScrollView
slideshow.pageControl.currentPageIndicatorTintColor = UIColor.lightGray
slideshow.pageControl.pageIndicatorTintColor = UIColor.black
slideshow.contentScaleMode = UIViewContentMode.scaleAspectFill
slideshow.setImageInputs(alamofireSource)
}

WKWebView displays content wrong after orientation change

I am fairly new to iOS development and I'm using a WKWebView to display a page that plays a video using the Vimeo Player. When the app starts up, it shows the view correctly, no matter what orientation it is currently in. However, once I change the orientation the view will either look zoomed in or has whitespace below the video.
The annoying thing about this is that it's not consistent. Sometimes the view displays correctly, sometimes it doesn't. If I try to zoom the view in or out or try to scroll when using the app it usually corrects itself, but even that does not seem to be 100% reliable.
Some screenshots (tested on iPad 2):
Landscape orientation (correct):
Portrait orientation (correct):
Landscape orientation (incorrect):
Portrait orientation (incorrect):
And the code used to produce this result:
import Foundation
import UIKit
import WebKit
class VideoViewController : UIViewController, WKScriptMessageHandler {
#IBOutlet var containerView : UIView! = nil
var webView: WKWebView?
override func loadView() {
super.loadView()
self.webView = WKWebView()
let contentController = WKUserContentController();
let scaleToFit = WKUserScript(source: "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width, initial-scale=1.0'); document.getElementsByTagName('head')[0].appendChild(meta);", injectionTime: WKUserScriptInjectionTime.AtDocumentStart, forMainFrameOnly: true)
contentController.addUserScript(scaleToFit)
contentController.addScriptMessageHandler(self, name: "callbackHandler")
self.view = webView!
}
override func viewDidLoad() {
super.viewDidLoad()
refreshUI()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func refreshUI() {
let url = NSURL(string: "https://photofactsacademy.nl/api/vp.asp?id=152839850")
let requestObj = NSURLRequest(URL: url!)
webView!.loadRequest(requestObj)
}
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
if(message.name == "callbackHandler") {
print("JavaScript is sending a message \(message.body)")
}
}
}
I looked through SO for WKWebView and orientation change and didn't find anything that helped me.
Your help is appreciated.
Can you try this
wkWebView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
I was able to solve this problem by injecting a javascript reload call like this:
Swift:
func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animateAlongsideTransition(nil, completion: {
//Reset Frame of Webview
webView.evaluateJavaScript("location.reload();", completionHandler: nil)
}
Objective C:
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
//Reset Frame of Webview
[_webView evaluateJavaScript:#"location.reload();" completionHandler:^(id _Nullable obj, NSError * _Nullable error) {
NSLog(#"error:%#", error);
}];
}
You don't need to reload the entire web page. You just need to reload its input views. Make sure you have set constraints to web view properly and then add below code while changing orientation.
// Reload inputs so that webview can adjust its content according to orientation
[self.webView reloadInputViews];
After few hours of struggling, this is what worked for me:
<header><meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, shrink-to-fit=no'></header><body style='margin: 0px; padding: 0px; width:100%; height:100%;'>...
Set width and height of both body and your video element to 100% and disable user scaling through header tag.

How to make Image page viewer for images swift ios

I wanna display a couple of images from the assets folders, into my application. so I wanna make a page view.
First, images will be inside collection view, then on click, the image will be full screen. Then the user can slide between the images by swiping right and left as shown in the following photo:
I found this tutorial:
PhotosGalleryApp
Updated:
I have this in my storyboard:
Now in GaleryViewController I show the images in cells
when user click on it, I open the image in fullscreen in PhotoViewController.
PhotoViewController.swift :
import UIKit
class PhotoViewController: UIViewController{
#IBOutlet weak var imageView: UIImageView!
var index: Int = 0;
var pageViewController : UIPageViewController?
#IBAction func btnCancelClicked(sender: AnyObject) {
self.navigationController?.popToRootViewControllerAnimated(true);
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
initUI();
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(animated: Bool) {
self.navigationController?.hidesBarsOnTap = true;
self.navigationController?.hidesBarsOnSwipe = true;
displayPhoto()
}
func initUI() -> Void {
// pageViewController = UIPageViewController(transitionStyle: .Scroll, navigationOrientation: .Horizontal, options: nil)
// pageViewController!.dataSource = self
}
func displayPhoto() {
self.imageView.image = UIImage(named: Constants.Statics.images[index])
}
I have the images in static structure so i can access them anywhere:
class Constants {
struct Statics {
static let images = ["1.jpg","2.jpg","3.jpg","4.jpg","5.jpg","7.jpg","8.jpg"]
}
}
My problem is: I want to add the feature that allow me to swipe between pictures inside the PhotoViewController.
Any ideas?
Thank you
You can do one of the following two things to achieve your goal :
Make a modal segue of the cell to the next UICollectionViewController where the images are showed in full screen, and in the prepareForSegue pass all the data (images) you need to show and where exactly you are in this moment (indexOfImage).
You can watch the didSelectItemAtIndexPath and then pass all the data to one instance of the next UICollectionViewController you want to show with the presentViewController func.
But it's very important that in the next UICollectionViewController you have set pageEnabled = true in code or in the Interface Builder (I though is much easy to do.)
UPDATE:
Very good tutorials on how to make a slide show of images using an UIScrollView or an UICollectionView :
How To Use UIScrollView to Scroll and Zoom Content
Creating a Paged Photo Gallery With a UICollectionView
I hope this help you.

Resources