WKWebView on iOS generates LayoutConstraints error when keyboard appears - keyboard

I have built a simple iOS app that displays a full-screen WKWebView. It works fine as long as there is no input that triggers the onscreen keyboard but as soon as the keyboard appears it generates an error "Unable to simultaneously satisfy constraints" and a whole trace of NSAutoresizingMaskLayoutConstraints.
Despite the error, the keyboard appears and I can use the text input.
My app is very simple, it just has this app delegate:
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame:UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = WebViewController()
return true
}
}
and this view controller:
import UIKit
import WebKit
class WebViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let webView = WKWebView()
self.view.addSubview(webView)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
webView.leftAnchor.constraint(equalTo:view.safeAreaLayoutGuide.leftAnchor).isActive = true
webView.rightAnchor.constraint(equalTo:view.safeAreaLayoutGuide.rightAnchor).isActive = true
webView.bottomAnchor.constraint(equalTo:view.safeAreaLayoutGuide.bottomAnchor).isActive = true
let request = URLRequest(url: URL(string: "https://www.google.com/")!)
webView.load(request)
}
}
Is there something wrong with the way I use the anchors on the webview? Or do I need extra constraints to handle the onscreen keyboard?

Related

After iOS 13.4.1 update WKWebView not able to recognise tap gesture

After ios update to 13.4.1 to able to detect tap gesture in WKWebView, my code as follow:
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(viewTap) )
tapGesture.delegate = self
webview.addGestureRecognizer(tapGesture)
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
#objc func viewTap() {
print("tap on viewTap...")
}

How to set statusBar color on iPhoneX?

I use the navigationController, and i hide the navigationBar, how to set statusBar color on iPhoneX?
I do not want to set self.view.backgroundColor
iPhoneX notch color
UIView *statusBar = (UIView *)[[UIApplication sharedApplication] valueForKey:#"statusBar"];
statusBar.backgroundColor = [UIColor greenColor];
Here is a hacky trick to change/set background color for status bar during application launch or during viewDidLoad of your view controller.
extension UIApplication {
var statusBarView: UIView? {
return value(forKey: "statusBar") as? UIView
}
}
// Set upon application launch, if you've application based status bar
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.statusBarView?.backgroundColor = UIColor.red
return true
}
}
or
// Set it from your view controller if you've view controller based statusbar
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.shared.statusBarView?.backgroundColor = UIColor.red
}
}
Here is result:
Swift 4
func setStatusBarBackgroundColor(_ color: UIColor) {
guard let statusBar = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView else { return }
statusBar.backgroundColor = color
}
In Interface Builder, I simply added a view at 0x0, 44px high and the same width as the top-level view, then set this view to the desired background color. This changed the background color of the status bar without affecting the view background color.
In my case, I needed something like this because the top half of my screen is one color and the bottom half is the other. I didn't see another way to make the status bar match the top color and the home button area match the bottom color.
This could easily be done programmatically if the extra view gets in the way on devices other than the iPhone X. In my case it doesn't cause problems on other devices.

WKWebview:Remove Copy,lookup,share button from Menu and show custom

I want to implement my custom MenuController once user selects a text. I am using the below code to do that, I subclassed WKWebview and implemented below
override init(frame: CGRect, configuration: WKWebViewConfiguration) {
super.init(frame: frame, configuration: WKWebViewConfiguration())
enableCustomMenu()
}
func enableCustomMenu() {
let menuController = UIMenuController.shared
let testmenu = UIMenuItem(title: "Test", action: #selector(test))
menuController.menuItems = [testmenu]
}
func test(){
var text = ""
self.evaluateJavaScript("document.getSelection().toString()") { (data, error) in
text = data as! String
}
print(text)
}
override func becomeFirstResponder() -> Bool {
return true
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
switch action {
case #selector(test):
return true
default:
return false
}
}
This used to work fine for UIWebview, but in WKWebview, in the canPerformAction we are no longer getting copy, lookup and share actions so these guys are not getting removed.
I had this problem too, I found that you can customize your WKwebview by overriding the function canPerformAction
here is an article about it .
It worked for me!
Hope that help you.

iOS 9 issues - GameCenter

Since iOS 9 errors are appearing in the console when opening the Game Center View Controller. I have created a bare bones sample project to help diagnose and isolate the issue. My bare bones View Controller contains a UIButton to open the Game Center, and my code is the following:
import UIKit
import GameKit
class ViewController: UIViewController, GKGameCenterControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let localPlayer = GKLocalPlayer()
localPlayer.authenticateHandler = {(viewController, error) -> Void in
if let viewController = viewController {
self.presentViewController(viewController, animated: true, completion: nil)
}else{
print("(GameCenter) Player authenticated: \(GKLocalPlayer.localPlayer().authenticated)")
}
}
}
#IBAction func openGameCenter(sender: AnyObject) {
let gameCenter = GKGameCenterViewController()
gameCenter.gameCenterDelegate = self
self.presentViewController(gameCenter, animated: true, completion: nil)
}
func gameCenterViewControllerDidFinish(gameCenterViewController: GKGameCenterViewController) {
gameCenterViewController.dismissViewControllerAnimated(true, completion: nil)
}
}
When presenting the Game Center View Controller, I see the following errors in the console:
2015-09-21 11:03:41.530 GameCenterTest[1552:415921] - changing property masksToBounds in transform-only
layer, will have no effect 2015-09-21 11:03:41.531
GameCenterTest[1552:415921] - changing
property masksToBounds in transform-only layer, will have no effect
2015-09-21 11:03:41.532 GameCenterTest[1552:415921] - changing property masksToBounds in transform-only
layer, will have no effect
When tapping on Done and closing the Game Center View Cotroller, I see the following error in the console:
2015-09-21 11:03:52.263 GameCenterTest[1552:416142] plugin
com.apple.GameCenterUI.GameCenterDashboardExtension invalidated

Simple Swift WebView not working (Xcode 6 Beta 3)

I was writing a simple WebView in Swift, but everytime I try to launch it in the iOS Simulator I get these errors. What is going wrong?
import UIKit
class ViewController: UIViewController {
#IBOutlet var webview: UIWebView
var urlpath = "http://www.google.de"
func loadAddressURL(){
let requesturl = NSURL(string: urlpath)
let request = NSURLRequest(URL: requesturl)
webview.loadRequest(request)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
loadAddressURL()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Error:
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
self uiwebview.ViewController 0x7987fc70 0x7987fc70
request NSURLRequest * 0x78ebfc40 0x78ebfc40
requesturl NSURL * "" 0x78ec0040
You simply haven't connected your UIWebView to the webview class property
Open the assistant editor, show your xib or storyboard at left, your view controller source file at right, click on the circle at the left of the webview property and drag into the UIWebView control. Once the connection is established, run the app and it should work now
I guess you get a white page because you test on the simulator. If you test on a real device you should be fine.
You need to put "!" after 'UIWebView' and unwrap "requesturl" to get your String value otherwise it's been an optional and you get error.
import UIKit
class WebViewController: UIViewController {
#IBOutlet var webview: UIWebView!
var urlpath: String = "http://www.google.de"
func loadAddressURL(){
let requesturl = NSURL(string: urlpath)
let request = NSURLRequest(URL: requesturl!)
webview.loadRequest(request)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
loadAddressURL()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Resources