我试图从nib文件中将子视图加载到我的应用的每个页面。现在,我正在使用一种不同寻常的方法加载这个子视图,因为我通过UIStoryboard的扩展来做这件事(可能与我的问题无关,但我不确定)。这就是加载nib文件时代码的外观:
extension UIStoryboard {
public func appendCustomView(to viewController: UIViewController) {
if let myCustomSubview = Bundle.main.loadNibNamed("MyCustomSubview", owner: nil, options: nil)![0] as? MyCustomSubview {
viewController.view.addSubview(myCustomSubview)
}
}
}
此代码执行它应该执行的操作并添加" MyCustomSubview"到视图控制器(我不会详细了解这个方法是如何被调用的,因为它起作用所以它看起来并不重要)。问题是我不能为我的生活找出如何添加影响myCustomSubview大小的约束。我已经尝试将代码放在我上面显示的函数以及MyCustomSubview swift文件中以添加约束,但无论我做什么,子视图都不会改变。
理想情况下,约束会固定" MyCustomSubview"在ViewController的底部,宽度设置为屏幕大小和硬编码高度约束。
以下是我尝试过的两种主要方法(每种方法大约有100种不同的方法),但不起作用:
方法1 - 直接从" appendCustomView"
添加约束public func appendCustomView(to viewController: UIViewController) {
if let myCustomSubview = Bundle.main.loadNibNamed("MyCustomSubview", owner: nil, options: nil)![0] as? MyCustomSubview {
let top = NSLayoutConstraint(item: myCustomSubview, attribute: .top, relatedBy: .equal
, toItem: viewController.view, attribute: .top, multiplier: 1, constant: 50.0)
viewController.view.addSubview(myCustomSubview)
viewController.view.addConstraint(top)
}
}
方法2 - 在MyCustomSubview中添加约束出口和setter方法
class MyCustomSubview: UIView {
@IBOutlet weak var widthConstraint: NSLayoutConstraint!
@IBOutlet weak var heightConstraint: NSLayoutConstraint!
func setConstraints(){
self.widthConstraint.constant = UIScreen.main.bounds.size.width
self.heightConstraint.constant = 20
}
}
在" appendCustomView"
中调用setter方法public func appendCustomView(to viewController: UIViewController) {
if let myCustomSubview = Bundle.main.loadNibNamed("MyCustomSubview", owner: nil, options: nil)![0] as? MyCustomSubview {
myCustomSubview.setConstraints()
viewController.view.addSubview(myCustomSubview)
}
}
(*注意:这些例子的实际限制是无关紧要的,我没有尝试满足上面提到的规范,我只是试图对视图进行任何改变,以了解约束是更新。他们不是。)
编辑:更改" MyCustomNib"到" MyCustomSubview"为清楚起见。
答案 0 :(得分:2)
当您从Nib向视图添加约束时,您必须调用yourView.translatesAutoresizingMaskIntoConstraints = false
,并且还需要确保您拥有全部4(除非它是标签或其他一些仅需要的视图类型2)制约因素:
以下是一些示例代码,使视图填充其父视图:
parentView.addSubview(yourView)
yourView.translatesAutoresizingMaskIntoConstraints = false
yourView.topAnchor.constraint(equalTo: parentView.topAnchor).isActive = true
yourView.leadingAnchor.constraint(equalTo: parentView.leadingAnchor).isActive = true
yourView.bottomAnchor.constraint(equalTo: parentView.bottomAnchor).isActive = true
yourView.trailingAnchor.constraint(equalTo: parentView.trailingAnchor).isActive = true
编辑:我实际上已经开始使用这种添加NSLayoutConstraints
的方法,即使结果相同
NSLayoutConstraint.activate([
yourView.topAnchor.constraint(equalTo: parentView.topAnchor),
yourView.leadingAnchor.constraint(equalTo: parentView.leadingAnchor),
yourView.bottomAnchor.constraint(equalTo: parentView.bottomAnchor),
yourView.trailingAnchor.constraint(equalTo: parentView.trailingAnchor),
])
答案 1 :(得分:0)
对于将来遇到此问题的任何人来说,这是我通过稍微调整this answer来提出的解决方案
在与nib文件对应的swift类中添加setConstraints(withRelationshipTo)方法:
class MyCustomSubview: UIView {
func setConstraints(withRelationshipTo view: UIView){
self.translatesAutoresizingMaskIntoConstraints = false
// Replace with your own custom constraints
self.heightAnchor.constraint(equalToConstant: 40.0).isActive = true
self.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
self.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
self.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
}
}
然后在将nib文件添加到视图后调用setConstraints方法(可能在视图控制器的viewWillAppear或viewDidLoad中)
class MyViewController: UIViewController {
override func viewWillAppear(_ animated: Bool){
super.viewWillAppear(animated)
if let myCustomSubview = Bundle.main.loadNibNamed("MyCustomSubview", owner: nil, options: nil)![0] as? MyCustomSubview {
let view = self.view // Added for clarity
view.addSubview(myCustomSubview)
myCustomSubview.setConstraints(withRelationshipTo: view)
}
}
}
答案 2 :(得分:0)
您可以将此扩展程序用于您将子视图添加到现有UIView的任何位置。
extension UIView {
func setConstraintsFor(contentView: UIView, left: Bool = true, top: Bool = true, right: Bool = true, bottom: Bool = true) {
contentView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(contentView)
var constraints : [NSLayoutConstraint] = []
if left {
let constraintLeft = NSLayoutConstraint(item: contentView, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1, constant: 0)
constraints.append(constraintLeft)
}
if top {
let constraintTop = NSLayoutConstraint(item: contentView, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1, constant: 0)
constraints.append(constraintTop)
}
if right {
let constraintRight = NSLayoutConstraint(item: contentView, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1, constant: 0)
constraints.append(constraintRight)
}
if bottom {
let constraintBottom = NSLayoutConstraint(item: contentView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 0)
constraints.append(constraintBottom)
}
self.addConstraints(constraints)
}
}
您可以这样调用此方法:
containerView.setConstraintsFor(contentView: subView!, top: false)
这会将subView添加到containerView并将约束添加到除了顶边之外的所有边。 如果需要,可以修改此方法以传递left,top,right,bottom常量值。