子视图永远不可见
Posted
技术标签:
【中文标题】子视图永远不可见【英文标题】:Child view is never visible 【发布时间】:2017-07-31 06:46:46 【问题描述】:我正在以编程方式构建我们的 UI,但在为子视图渲染元素时遇到了一些麻烦。
我正在通过实例化我的初始视图控制器及其所需的视图来设置应用程序 Window
。
class AppDelegate: UIResponder, UIApplicationDelegate
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
let initialView = StartupView(frame: CGRect.zero)
let startupViewController = StartupViewController(startupView: initialView);
window = UIWindow(frame: UIScreen.main.bounds);
window!.rootViewController = startupViewController;
window?.backgroundColor = UIColor.white
window!.makeKeyAndVisible();
return true
StartupView
类实例化单个 UIButton
,它添加到自身并设置约束以指定高度/宽度并水平和垂直居中对齐。
class StartupView : UIView
// views
var newAccountButton: UIButton!
override init(frame: CGRect)
super.init(frame: frame)
self.configureView()
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
self.configureView()
override func updateConstraints()
self.newAccountButton.translatesAutoresizingMaskIntoConstraints = false
self.newAccountButton.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
self.newAccountButton.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
self.newAccountButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
self.newAccountButton.widthAnchor.constraint(equalToConstant: 50).isActive = true
print("\(self.newAccountButton.titleLabel?.text ?? "Unknown") is \(self.newAccountButton.frame)")
super.updateConstraints()
func configureView()
// New account button setup
newAccountButton = UIButton(frame: CGRect.zero)
newAccountButton.titleLabel?.text = "Create Account"
self.addSubview(newAccountButton)
StartupView
被赋予其ViewController
。似乎分配给StartupView
的ViewController
约束正在工作,因为我已经验证我的StartupView
的大小确实与ViewController
视图的大小相等。但是,当我运行模拟器时,我看不到 UIButton
。
class StartupViewController: UIViewController
var startupView: StartupView!
init(startupView: StartupView)
self.startupView = startupView
super.init(nibName: nil, bundle: nil)
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
self.startupView = StartupView(frame: CGRect.zero)
override func viewDidLoad()
super.viewDidLoad()
self.view.addSubview(self.startupView)
self.startupView.translatesAutoresizingMaskIntoConstraints = false
self.startupView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
self.startupView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
self.startupView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
self.startupView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
self.startupView.updateConstraints()
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
我做错了约束吗?或者我添加嵌套视图的顺序重要吗?
编辑
这是视图调试器的截图。
我可以看到布局中的按钮(突出显示),但看不到正在呈现的实际按钮。写print("\(self.newAccountButton.titleLabel?.text): \(self.newAccountButton.frame)")
会写出按钮的标题和它的框架,但没有呈现任何内容。
【问题讨论】:
你不应该自己打电话给updateConstraints()
。相反,您应该调用setNeedsUpdateConstraints()
并让布局引擎处理其余的事情。此外,请确保不要在 updateConstraints()
中再次添加相同的约束,因为此方法可以多次调用。
谢谢 - 我更新了我的代码以使用 setNeedsUpdateConstraints()
。它没有解决我最初的问题,但至少我知道请求约束更新的正确方法:)
【参考方案1】:
我认为您可以简单地这样做,而不是覆盖 updateConstraints:
编辑
与OP聊天讨论后的最终解决方案(不直接访问标签):
func configureView()
// New account button setup
newAccountButton = UIButton(frame: CGRect.zero)
newAccountButton.setTitleColor(self.tintColor, for: UIControlState.normal)
newAccountButton.setTitle("Create Account", for: UIControlState.normal)
self.addSubview(newAccountButton)
self.newAccountButton.translatesAutoresizingMaskIntoConstraints = false
self.newAccountButton.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
self.newAccountButton.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
self.newAccountButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
self.newAccountButton.widthAnchor.constraint(equalToConstant: 50).isActive = true
【讨论】:
当应用程序运行时,StartupView
中仍然缺少该按钮:/ 我还在configureView()
函数的末尾添加了setNeedsUpdateConstraints()
,但它没有任何区别
你是否从 StartupViewController viewDidLoad 中删除了 self.startupView.updateConstraints()
我做到了 - 没有任何影响
您是否删除了您覆盖的 updateConstraints 方法
我做到了,我更新了我的 OP 以显示调试器的屏幕截图。看起来约束正在起作用;但是什么都没有渲染。【参考方案2】:
我认为在您的应用委托中,您必须定义 StartupView
的大小。目前设置为zero
let initialView = StartupView(frame: CGRect.zero).
【讨论】:
启动视图在构建StartupView
约束时获取由StartupViewController
设置的大小。这没有问题以上是关于子视图永远不可见的主要内容,如果未能解决你的问题,请参考以下文章