子视图添加到 UITableView 导航栏下方 Y 值不正确

问题描述 投票:0回答:2

我有一个 UITableViewController,它嵌入在 UINavigationController 中,而 UINavigationController 又嵌入 UITabBarController。

我试图添加一个子视图,以在不满足条件时遮挡导航栏和选项卡栏之间的区域,但我添加的子视图并不完全位于正确的位置。它似乎向上移动了状态栏和导航栏组合的高度(注意阴影区域下方的间隙......也应该是阴影的)。

这是我试图实现它的方法:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    setupLinks()
    addBlockViewIfRequired()
  }
  
  override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    blockView.removeFromSuperview()
  }
  override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    setSizeOfBlockView()
  }
  
  func addBlockViewIfRequired() {
    if dataModel.getAccounts().isEmpty {
      if let navController = self.navigationController {
        blockView.backgroundColor = UIColor.blackColor()
        blockView.alpha = 0.5
        setSizeOfBlockView()
        navController.view.insertSubview(blockView, belowSubview: navController.navigationBar)
      }
    }
  }
  
  func setSizeOfBlockView() {
    let blockViewRect = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)
    blockView.frame = blockViewRect
  }

关于我需要调整什么才能正确放置此子视图,有什么想法吗?谢谢!

ios swift uitableview uinavigationbar subview
2个回答
1
投票

你为什么要尝试将这个阻塞View放入导航控制器的rootView

导航控制器应该完全忽略特定的业务上下文细节。修复很简单,但问题背后有一些基本的编程原理,所以请考虑一下。 要求是“如果帐户为空,则显示块视图”。但每一个需求都会带来一个问题 -> 谁应该负责处理这个需求?哪个实体/对象?

软件架构基本上就是这些职责的划分。
在您的情况下,显示阻塞视图的正确负责实体是位于导航控制器堆栈中的viewController。如果我可以从屏幕截图中假设的话,它就是显示表格视图的那个。 所以代替这个

navController.view.insertSubview(blockView, belowSubview:navController.navigationBar)

我希望在各自的视图控制器中有一个私有的便捷方法

setupBlockView() { //here you set up your view..everything (color, content, position in view hierachy..whatever) **except** layout (size and position) self.view.addSubView(blockView) }

您可以从 
viewDidLoad

而不是

viewDidAppear
调用此方法。据我所知,您有一个 blockView 属性,可以使视图保持活动状态。顺便说一句,应该是私人的。

接下来,在

viewWillAppear

中,您将使用一个非常简单的


blockView.hidden = model.account.isEmpty

很高兴看到有人使用“layoutSubviews”来布局子视图:)但是一旦应用上面的更改..布局变得非常简单..摆脱方便的方法,直接在布局子视图中说

blockView.frame = self.view.bounds

边界方法是正确的。您只想复制大小,而不具有非零位置。
您是否注意到我们删除了多少
许多

行代码? :)


0
投票

您需要将 blockViewRect.origin.y 设置为导航栏的底部,例如

let blockViewRect = CGRectMake(0, navigationController?.navigationBar.frame.maxY, self.view.bounds.size.width, self.view.bounds.size.height)

只是为了让事情变得漂亮一点......

var blockViewRect = self.view.bounds blockViewRect.origin.y = navigationController?.navigationBar.frame.maxY

仅供参考,正确的 navigationController 可能位于您的 VC 的父视图控制器之一中。

© www.soinside.com 2019 - 2024. All rights reserved.