前提
メインコントローラー:UITabBarController
遷移元Controller:UIViewControllerA
遷移先Controller:UIViewControllerB
遷移先ViewControllerのカスタムビュー:CustomView
以上の構成より
下記の順序で画面遷移が行われております。
Swift
1///UITabBarController 2 let firstViewController = UIViewControllerA 3 let UINavigationController_0 = UINavigationController(rootViewController: firstViewController) 4 UINavigationController_0.modalPresentationStyle = .fullScreen 5 UINavigationController_0.tabBarItem = UITabBarItem(title: "tab1", image: .none, tag: 0)
Swift
1///UIViewControllerA 2 3 let UIVIEWCONTROLLERB = UIViewControllerB() 4 self.navigationController?.pushViewController(TARGETPROFILEVIEWCONTROLLER, animated: true) 5
実現したいこと
上記の画面遷移後
UIViewControllerB()ではカスタムビューとして自前で用意しているビューを設定しております。
Swift
1///UIViewControllerB 2 3 let CUSTOMVIEW = CustomView() 4 5 override func viewDidLayoutSubviews() { 6 7 self.view = CUSTOMVIEW 8 9 } 10
CUSTOMVIEW内ではコードレイアウトを行なっているのですが、一つ目のオブジェクトの基準となる
TopAnchorを設定する際、自身のTopAnchorと同じ値にした場合、NavigationControllerにViewが重なってしまいうまくレイアウトが行えませんでした(自身のViewのTopAncherは画面のTopAnchorなので上記のself.view = CUSTOMVIEWではNavigationControllerを考慮しない。当たり前ですが、、、)
Swift
1///CustomView() 2 ///これではカスタムビューに重なってしまう 3 object.topAnchor.constraint(equalTo: self.topAnchor).isActive = true 4
このようなことからなんとかカスタムビュー内でUInavigationControllerのナビゲーションバーのBottomの値を取得したいのですがどうしてもうまくいきません。
MVCモデルの採用を行なっているためにUINavigationController内でなるべくレイアウトの設定は行いたくないというのがありますのでUIVIEW内で完結できる方法がありましたらご教授いただけますと幸いです。
試したこと
■CustomViewのイニシャライズでnavigationBarのAnchorの値を渡す
⇨こちらカスタムビュー内のoverride init内でSuper.initにて継承基のframe初期化を行っていることの影響で
Designatedイニシャライザ及びConvenienceイニシャライザの実装ができませんでした
■CustomViewインスタンス後にプロパティオブザーバを実装し、navigationBarのAnchorの値をUIViewControllerBから渡したらレイアウトの処理が行われるようにする
⇨こちらは階層が異なるNavigationBarの値を使用することは禁止されているようで値が入ったプロパティをレイアウト時に使用する段階でエラーが発生してしまいました
■UIViewControllerBのビュー設定で、CustomViewのFrameを計算(UIViewControllerBにいるのでNavigationBarの値が取れる)してからAddSubViewを行い、設定する
⇨こちらはAddsubViewにした場合UITabBarControllerのタブが表示されてしまう
どうにかスマートに行う方法はありませんでしょうか。
そもそも、UINavigationControllerでPush遷移した先のViewがカスタムビューという状況はいくらでもあると思うのですがネットで調べてもStoryBoardで実装しているものばかりでコードレイアウトを行なっているものがなく、解決には至りませんでした。
試したことの三つ目にあるFrame計算の方法にて表示されているタブを非表示にする処理をUIViewControllerBにて行う手もあるのですがそもそもの画面領域が狭まってしまう(タブ領域を使用できない)というのがありますのでなるべく使いたくはありません。
どなたかご回答いただけますでしょうか。お願いいたします。
追記①
TakeOne様にて説明不足の旨ご指摘いただきましたので追記させていただきます。
コメント及びご指摘誠にありがとうございます。
Swift
1///MainTabBarController() 2import Foundation 3import UIKit 4 5final class MainTabBarController: UITabBarController { 6 7 override func viewDidLoad() { 8 super.viewDidLoad() 9 setupTab() 10 } 11 12 func setupTab() { 13/// タブにViewControllerを設定 14 let firstViewController = UIViewControllerA() 15 let UINavigationController_0 = UINavigationController(rootViewController: firstViewController) 16 UINavigationController_0.modalPresentationStyle = .fullScreen 17 UINavigationController_0.tabBarItem = UITabBarItem(title: "tab1", image: .none, tag: 0) 18 19 viewControllers = [UINavigationController_0] 20 } 21}
Swift
1///UIViewControllerA() 2import Foundation 3import UIKit 4 5class UIViewControllerA:UIViewController, UIVIEWADelegateProtcol { 6 7 override func viewDidLoad() { 8 let UIVIEWA = UIVIEWA() 9 self.view = UIVIEWA 10 self.view.backgroundColor = .black 11 UIVIEWA.delegate = self 12 13 } 14 15 func transitionbuttonTappedAction() { 16 let UIVIEWCONTROLLERB = UIViewControllerB() 17 self.navigationController?.pushViewController(UIVIEWCONTROLLERB, animated: true) 18 } 19} 20
Swift
1///UIVIEWA() 2 3import Foundation 4import UIKit 5 6protocol UIVIEWADelegateProtcol:AnyObject { 7 func transitionbuttonTappedAction() 8} 9 10 11class UIVIEWA:UIView { 12 13 ///変数宣言 14 weak var delegate:UIVIEWADelegateProtcol? 15 16 override init(frame: CGRect) { 17 super.init(frame: frame) 18 self.backgroundColor = .black 19 autoLayoutSetUp() 20 autoLayout() 21 } 22//※初期化処理※ 23 required init?(coder: NSCoder) { 24 fatalError("init(coder:) has not been implemented") 25 } 26 27 ///遷移ボタン 28 let transitionbutton:UIButton = { 29 let returnButton = UIButton() 30 returnButton.tag = 1 31 returnButton.backgroundColor = .white 32 returnButton.addTarget(self, action: #selector(butttonClicked(_:)), for: UIControl.Event.touchUpInside) 33 return returnButton 34 }() 35 36 ///遷移押下された際の挙動 37 @objc func butttonClicked(_ sender: UIButton) { 38 if let delegate = delegate { 39 self.delegate?.transitionbuttonTappedAction() 40 } 41 } 42 43 func autoLayoutSetUp() { 44 ///各オブジェクトをViewに追加 45 addSubview(transitionbutton) 46 47 ///UIオートレイアウトと競合させない処理 48 transitionbutton.translatesAutoresizingMaskIntoConstraints = false 49 } 50 51 func autoLayout() { 52///適当なレイアウト。押せればOK 53 transitionbutton.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true 54 transitionbutton.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.05).isActive = true 55 transitionbutton.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor, constant: 100).isActive = true 56 transitionbutton.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 57 } 58}
Swift
1import Foundation 2import UIKit 3 4class UIViewControllerB:UIViewController{ 5 6 override func viewDidLoad() { 7 let UIVIEWB = UIVIEWB() 8 self.view = UIVIEWB 9 self.view.backgroundColor = .black 10 } 11}
Swift
1import Foundation 2import UIKit 3 4class UIVIEWB:UIView { 5 6 override init(frame: CGRect) { 7 super.init(frame: frame) 8 self.backgroundColor = .black 9 autoLayoutSetUp() 10 autoLayout() 11 } 12//※初期化処理※ 13 required init?(coder: NSCoder) { 14 fatalError("init(coder:) has not been implemented") 15 } 16 17 ///適当なオブジェクト 18 let tempButton:UIButton = { 19 let returnButton = UIButton() 20 returnButton.backgroundColor = .white 21 return returnButton 22 }() 23 24 func autoLayoutSetUp() { 25 ///各オブジェクトをViewに追加 26 addSubview(tempButton) 27 28 ///UIオートレイアウトと競合させない処理 29 tempButton.translatesAutoresizingMaskIntoConstraints = false 30 } 31 32 func autoLayout() { 33_**ここが問題の箇所**_ 34///ここでのtempButtonをUINavigationControllerのバーの下に配置したいのだが、 35///UINavigationContoller.navigationController?.navigationBar.bottomAnchorの値を持ってくることができない。試したこと一覧は全てダメでした。 36 tempButton.topAnchor.constraint(equalTo: self.topAnchor).isActive = true 37 tempButton.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.05).isActive = true 38 tempButton.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor, constant: 100).isActive = true 39 tempButton.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 40 } 41}
以上になります。問題の箇所はUIViewBのtempButtonのレイアウト部分になります。
よろしくお願い申し上げます。

回答2件
あなたの回答
tips
プレビュー