前提・実現したいこと
storyboardなしで開発をしています。
UIViewの上にMKMapViewをaddSubViewしています。
UIViewのsafeArea部分の背景色を自由に変えたいのですが、上手くいきません。
背景色を白やオレンジなどにするとsafeArea部分の時刻などが表示されますが、黒や透明にすると真っ黒になってしまい時刻が表示されなくなってしまうので、この問題を解決したいです。
storyboardなしでの開発が初めてなので理解していないことが多いと思いますが、ご回答よろしくお願いします。
シュミレータ画面
背景色が透明の時
該当のソースコード
ViewController.swift
import UIKit import MapKit import CoreLocation class ViewController: UIViewController, MKMapViewDelegate { /* safaAreaの値を取得 */ var safaAreaHeight:CGFloat = 0 var safeAreaWidth:CGFloat = 0 var topPadding:CGFloat = 0 var buttomPadding:CGFloat = 0 var leftPadding:CGFloat = 0 var rightPadding:CGFloat = 0 /* viewの幅と高さを取得するための変数 */ var screenWidth:CGFloat = 0 var screenHeight:CGFloat = 0 /* 位置情報を管理するための変数 */ var locationManeger:CLLocationManager! var mapView: MKMapView = MKMapView() override func loadView() { // print(self.view as Any) super.loadView() print("loadView!!") // print(self.view as Any) print(self.view.backgroundColor as Any) view.backgroundColor = .clear settingLocationManeger() print("背景色:(self.view.backgroundColor as Any)") } override func viewDidLoad() { // print(self.view as Any) super.viewDidLoad() print("viewDidLoad!!") // print(self.view as Any) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) } override func viewWillLayoutSubviews() { // super.viewWillLayoutSubviews() screenWidth = view.frame.size.width screenHeight = view.frame.size.height let safeArea = self.view.safeAreaInsets topPadding = safeArea.top buttomPadding = safeArea.bottom leftPadding = safeArea.left rightPadding = safeArea.right if screenWidth > screenHeight { safaAreaHeight = screenHeight safeAreaWidth = screenWidth - leftPadding - rightPadding ↓このコメントアウトを外してもレイアウトがズレます。(上に寄る) // self.view.frame = CGRect(x: leftPadding, y: topPadding, width: safeAreaWidth, height: safaAreaHeight) mapView.frame = CGRect(x: leftPadding, y: topPadding, width: safeAreaWidth, height: safaAreaHeight) } else { safaAreaHeight = screenHeight - topPadding - buttomPadding safeAreaWidth = screenWidth - leftPadding - rightPadding print("topPaddingだよ:(topPadding as Any)") print("view.frameだよ:(self.view.frame)") ↓このコメントアウトを外してもレイアウトがズレます。(上に寄る) // self.view.frame = CGRect(x: leftPadding, y: topPadding, width: safeAreaWidth, height: safaAreaHeight) mapView.frame = CGRect(x: leftPadding, y: topPadding, width: safeAreaWidth, height: safaAreaHeight) print("mapView.frameだよ:(mapView.frame)") } // view.backgroundColor = .clear view.addSubview(mapView) // print(self.view.frame) // print(self.mapView.frame) // print(self.view.backgroundColor as Any) } } extension ViewController: CLLocationManagerDelegate { /* 位置情報を取得・更新するたびに呼ばれる */ func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let location = locations.first let latitude = location?.coordinate.latitude ?? 0 let longitude = location?.coordinate.longitude ?? 0 let locationOfCoordinate = CLLocationCoordinate2DMake(latitude, longitude) /* mapViewの中心をユーザーがいる場所に設定 */ mapView.setCenter(locationOfCoordinate, animated: true) var region: MKCoordinateRegion = mapView.region region.center = locationOfCoordinate region.span.latitudeDelta = 0.001 region.span.longitudeDelta = 0.001 /* ピンを生成 */ let pointAnnotation:MKPointAnnotation = MKPointAnnotation() pointAnnotation.coordinate = locationOfCoordinate pointAnnotation.title = "現在地" mapView.addAnnotation(pointAnnotation) mapView.setRegion(region, animated: true) mapView.mapType = MKMapType.standard /* 位置情報の取得を止める */ locationManeger.stopUpdatingLocation() } /* 位置情報の取得に失敗した時に呼ばれる */ func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { print(error.localizedDescription) } } extension ViewController { func settingLocationManeger() { locationManeger = CLLocationManager() guard locationManeger != nil else { return } locationManeger.requestAlwaysAuthorization() let status = CLLocationManager.authorizationStatus() switch status { case .restricted, .denied: break case .authorizedWhenInUse, .authorizedAlways: locationManeger.delegate = self locationManeger.distanceFilter = 1 locationManeger.startUpdatingLocation() case .notDetermined: locationManeger.requestAlwaysAuthorization() locationManeger.delegate = self locationManeger.startUpdatingLocation() default: break } } }
ログ画面
仮説
ログ画面を見る限り、背景色は透明の時もしっかり反映されているように見えます。
もしかしたら背景色の問題ではなく、view.frameのy値を本来44.0とheigthを734.0にしたいのに、0.0と812.0になっていてレイアウトがずれていることが原因な気がするのですが、頭が混乱してます。
試したこと
画面が作られる順番を理解していないのが原因かと思い、画面がどのタイミングで作られるのかライフサイクルの記事を見ながら、func loadView()やfunc viewDidAppee()などを試しましたがわかりませんでした。
safeAreaの取得方法も調べました。
参考にした記事
補足情報
xcodeバージョン 11.3.1
回答1件
あなたの回答
tips
プレビュー