Eddie
Eddie

Reputation: 323

Trying to create an iOS WKWebView with a size smaller than the screen programmatically

Im starting with a simple app that just shows a web view using WKWebView. Everything builds, and works okay, except that it is always fullscreen. Ideally it would not extend under the iOS status bar at the top. It needs to be lowered by 20px to be below it. I have searched extensively for a solution but nothing changes the size. Nothing is setup in InterfaceBuilder, I'm doing everything programmatically. Using Swift.

This seems like something basic that many apps with a WKWebView would do. It should be simple. I'm probably missing something obvious. Any help is appreciated. Thanks in advance.

This is what I have so far:

import UIKit
import WebKit
class ViewController: UIViewController, UIGestureRecognizerDelegate , UIWebViewDelegate, WKNavigationDelegate  {

    let url = NSURL(string:"http://stackoverflow.com")
    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        webView = WKWebView(frame: CGRect( x: 0, y: 20, width: 380, height: 150 ), configuration: WKWebViewConfiguration() )
        self.view = webView
        self.view.frame = webView.frame
        let req = NSURLRequest(URL:url!)
        webView.loadRequest(req)
        self.webView.allowsBackForwardNavigationGestures = true
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

Many thanks Emilio!! The adjusted code works perfectly!

import UIKit
import WebKit
class ViewController: UIViewController, UIGestureRecognizerDelegate , UIWebViewDelegate, WKNavigationDelegate  {

    let url = NSURL(string:"http://stackoverflow.com")
    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        webView = WKWebView(frame: CGRect( x: 0, y: 20, width: self.view.frame.width, height: self.view.frame.height - 20 ), configuration: WKWebViewConfiguration() )
        self.view.addSubview(webView)
         let req = NSURLRequest(URL:url!)
        webView.loadRequest(req)
        self.webView.allowsBackForwardNavigationGestures = true
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

Upvotes: 15

Views: 17472

Answers (3)

Shrikant Phadke
Shrikant Phadke

Reputation: 418

The above solutions Didn't Work for me.

So I tried the following solution and it worked.

import SwiftUI
import WebKit

struct WebView: UIViewRepresentable {
    
    var url: URL
    
    func makeUIView(context: Context) -> WKWebView {
        
        return WKWebView(frame: CGRect(x: 0,y: 0 , width: UIScreen.main.bounds.size.width, height:200))
    }
    
    func updateUIView(_ webView: WKWebView, context: Context) {
        let request = URLRequest(url: url)
        webView.load(request)
    }
}

And Call from your struct.

struct TermsOfService: View {
    var body: some View {
        VStack {
            WebView(url: URL(string: "https://in.search.yahoo.com")!)
        }
    }
}

Upvotes: 1

Wil
Wil

Reputation: 380

I hat make room for some icon's and spend a lot of time fixing this. the solution was placing the adjustment in the viewDidAppear function.

import UIKit
import WebKit

class ViewController: UIViewController {
    let webView  = WKWebView()
    let url_base = "http://www.ztatz.nl"

     override func loadView() {
         self.view = webView
         webView.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), 
         options: .new, context: nil)
     }

      override func observeValue(forKeyPath keyPath: String?, of object: Any?, 
        change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "estimatedProgress" {
            print(Float(webView.estimatedProgress))
        }
    }

     override func viewDidLoad() {
        super.viewDidLoad()
        webView.load( url_base )
     }

     override func viewDidAppear(_ animated: Bool) {
        self.webView.frame   = CGRect(x: 0, y: 0, width: self.view.frame.width, 
        height: self.view.frame.height - 100)
        }

   }

   extension WKWebView {
       func load(_ urlString: String) {
          if let url = URL(string: urlString) {
           let request = URLRequest(url: url)
           load(request)
        }
       }
    }

Upvotes: 0

EmilioPelaez
EmilioPelaez

Reputation: 19912

Your problem is that UIViewControllers presented in certain ways will manage the frame of their view. If you present it modally, as the root controller, or in a navigation bar, for example, setting the fame manually won't have an effect. (Those are only a few examples).

If you want to manage the frame of the view, you can add the webView as a subview to your view controller's view. Modifying it's frame will work then.

One thing I'd like to point out is that calling self.view.frame = webView.frame after calling self.view = webView is redundant, because they are both the same object, so what you are effectively doing is:

self.view.frame = self.view.frame

Upvotes: 4

Related Questions