Reputation: 1
I create iPhone app and run it on iPad with iOS18. I have UIViewController which contains WKWebView to open YouTube video as code below. When I open this screen (YoutubeViewController) and then tap on video, it would display video in fullscreen. I close fullscreen and then close this screen (YoutubeViewController) and go to other screens which contains UITextField or UITextView. I tap on UITextField or UITextView but on-screen keyboard doesn't display. I try to debug on observer func for UIResponder.keyboardWillShowNotification but it is not called. I also found that UIScreen.main.bounds get changed to be iPad size.
If I terminate app and launch it again and then open screens which have UITextField or UITextView without opening video in fullscreen mode on YoutubeViewController then on-screen keyboard is displayed normally.
Anyone found this problem before? This problem occurs on iPhone app and run on iPad with iOS18 only.
import UIKit
@preconcurrency import WebKit
class YoutubeViewController: UIViewController, WKNavigationDelegate, WKUIDelegate, WKScriptMessageHandler {
private var webView: WKWebView?
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(self.doneAction))
let config = WKWebViewConfiguration()
config.allowsInlineMediaPlayback = false
config.userContentController.add(self, name: "jsHandler")
webView = WKWebView(frame: self.view.bounds, configuration: config)
webView?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
webView?.isOpaque = false
webView?.backgroundColor = .white
webView?.allowsBackForwardNavigationGestures = true
webView?.navigationDelegate = self
webView?.uiDelegate = self
self.view.addSubview(webView!)
let youtubeHtml = """
<!DOCTYPE html>
<html>
<head>
<style>
.wrapper {
padding: 40px;
}
.embed-container {
position: relative;
padding-bottom: 56.25%;
height: 0;
overflow: hidden;
max-width: 100%;
}
.embed-container iframe,
.embed-container object,
.embed-container embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="embed-container">
<iframe src="https://www.youtube.com/embed/aAkMkVFwAoo?rel=0&enablejsapi=1" frameborder="0" allowfullscreen id="youtube-iframe"></iframe>
</div>
</div>
<script type="text/javascript">
var tag = document.createElement("script");
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player("youtube-iframe", {
events: {
"onStateChange": onPlayerStateChange
}
});
}
var started = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !started) {
if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.jsHandler) {
window.webkit.messageHandlers.jsHandler.postMessage("YouTubePlayerStarted");
}
started = true;
}
}
</script>
</body>
</html>
"""
webView?.loadHTMLString(youtubeHtml, baseURL: URL(string: "https://www.youtube.com"))
}
@objc func doneAction() {
self.dismiss(animated: true)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping ((WKNavigationActionPolicy) -> Void)) {
decisionHandler(.allow)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
decisionHandler(.allow)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
}
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
guard let serverTrust = challenge.protectionSpace.serverTrust else {
completionHandler(.performDefaultHandling, nil)
return
}
let cred = URLCredential(trust: serverTrust)
completionHandler(.useCredential, cred)
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "jsHandler" {
guard let messageBody = message.body as? String, messageBody == "YouTubePlayerStarted" else {
return
}
}
}
}
Upvotes: 0
Views: 47