前回まででプログレスバーを含めたWebViewのガワアプリの基本的な部分を完成したつもりだったのですが、よく確認したところ、iPhoneXで画面下にわずかにWebページが表示されない隙間が出来ていました。
原因を調べまくったところ、どうやらcontentInsetという、領域内にスペースを自動で差し込む処理が存在したようです。そこで、その領域を取ることで本当の本当に、iPhoneXの隅から隅まで完全な全面表示になりました。
import UIKit
import WebKit
class ViewController: UIViewController {
private var _webView : WKWebView!
private var _hideStatusBar : Bool = false
private var _iPhoneX_Header : CGFloat = 0
private var _progressView: UIProgressView!
func iPhoneX() -> Bool {
guard #available(iOS 11.0, *) else {
return false
}
return UIApplication.shared.windows[0].safeAreaInsets != UIEdgeInsets.zero
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// ステータスバーの高さを取得
_iPhoneX_Header = iPhoneX() ? UIApplication.shared.statusBarFrame.size.height : 0
// WKWebViewを位置指定して表示
let webC = WKWebViewConfiguration()
_webView = WKWebView(frame:CGRect(x:0, y: -_iPhoneX_Header, width:self.view.bounds.size.width, height:self.view.bounds.size.height + _iPhoneX_Header), configuration: webC)
//_webView.scrollView.contentInsetAdjustmentBehavior = .always
// ジェスチャー(フリック)による 進む や 戻る を許可
_webView.allowsBackForwardNavigationGestures = true
// WebViewの読込監視
_webView.addObserver(self, forKeyPath:"estimatedProgress", options:.new, context:nil)
// ステータスバーの非表示 ※ステータスバーの高さを取得する前に非表示にすると、ステータスバーの高さが取得できない
_hideStatusBar = true
self.setNeedsStatusBarAppearanceUpdate()
// テキスト漫画読み込み
let url : URL = URL(string: "https://minnano.app/textmanga/")!
let request : URLRequest = URLRequest(url: url)
_webView.load(request)
self.view.addSubview(_webView)
// ProgressView
_progressView = UIProgressView(frame: CGRect(x:0, y:0, width:self.view.bounds.size.width * 2, height:4))
_progressView.layer.position = CGPoint(x:0, y:self.view.bounds.size.height - 1)
_progressView.transform = CGAffineTransform(scaleX: 1.0, y: 2.0)
_progressView.progressTintColor = UIColor.green
_progressView.trackTintColor = UIColor.orange
self.view.addSubview(_progressView)
// 回転時の通知
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.orientationChange(notification:)), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}
deinit {
_webView?.removeObserver(self, forKeyPath: "estimatedProgress")
}
@objc
private func orientationChange(notification: NSNotification) {
let portrait : Bool = UIInterfaceOrientationIsPortrait(UIApplication.shared.statusBarOrientation)
// WebViewの表示調整
_webView.frame.origin = CGPoint(x:portrait ? 0 : -_iPhoneX_Header, y:portrait ? -_iPhoneX_Header : 0)
_webView.frame.size = CGSize(width:self.view.bounds.size.width + (portrait ? 0 : _iPhoneX_Header * 2), height:self.view.bounds.size.height + (portrait ? _iPhoneX_Header : 0))
_webView.scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: portrait ? -_iPhoneX_Header * 4 / 5 : -_iPhoneX_Header / 2, right: 0)
//_webView.scrollView.contentInset = UIEdgeInsets(top: portrait ? _iPhoneX_Header : 0,
// left: portrait ? 0 : _iPhoneX_Header,
// bottom: 0,
// right: portrait ? 0 : _iPhoneX_Header)
// プログレスバーの表示調整
_progressView.frame.origin = CGPoint(x: 0, y: 0)
_progressView.frame.size = CGSize(width:self.view.bounds.size.width * 2, height:4)
_progressView.layer.position = CGPoint(x:0, y:self.view.bounds.size.height - 1)
}
// ステータスバーの非表示
override var prefersStatusBarHidden: Bool {
return _hideStatusBar
}
// WebViewの監視
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
if("estimatedProgress" == keyPath){
if(_progressView != nil){
// 更新
let progress : Float = Float(_webView.estimatedProgress)
_progressView.setProgress(progress < 1.0 ? progress : 0.0, animated: progress < 1.0)
_progressView.alpha = progress < 1.0 ? 1.0 : 0.0 // 読み込みが完了したら非表示に
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
下記は上のコードのcontentInset処理部分の抜粋です。 UIEdgeInsetsで余白を調整しています。4 / 5 とか 1 / 2 は、どうしてそうなるのかはわからないのですが、ピッタリ画面端までWebが表示される値です。
誰かどうしてこうなるのか教えてください。
_webView.frame.origin = CGPoint(x:portrait ? 0 : -_iPhoneX_Header, y:portrait ? -_iPhoneX_Header : 0)
_webView.frame.size = CGSize(width:self.view.bounds.size.width + (portrait ? 0 : _iPhoneX_Header * 2), height:self.view.bounds.size.height + (portrait ? _iPhoneX_Header : 0))
_webView.scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: portrait ? -_iPhoneX_Header * 4 / 5 : -_iPhoneX_Header / 2, right: 0)
ちょーすっきりした。