独創アプリ開発日記 57日目 iPhoneX完全全面ガワアプリ

前回まででプログレスバーを含めた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)

ちょーすっきりした。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です