这是在没有使用故事板的情况下以编程方式创建具有未知高度的中心(垂直和水平)容器(应该适应其内部的任何内容)的最佳方法吗?
在下面的示例中,有一个完整大小的背景图像/颜色/等等,并且有一个居中的容器。容器没有固定的高度,如果我想添加或删除控件,它应该适应。控件使用约束在它们之间隔开。
答案 0 :(得分:1)
如果你的控件如图所示,这是使用UIStackView
的完美情况。除了添加视图之外,它还可以扩展,收缩而无需执行任何操作。
然后使用UIStackView
上的约束来扩展/收缩包含白色圆角视图。
答案 1 :(得分:0)
在swift 4中你可以这样做:
第一种方式:
let view = UIView(frame: CGRect(0, 0, 100, 60))
view.center = self.view.center
self.view.addSubview(view)
或使用 autoLayout :
第二种方式
let view = UIView()
view.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
view.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
view.widthAnchor.constraint(equalToConstant: 100).isActive = true
view.heightAnchor.constraint(equalToConstant: 60).isActive = true
答案 2 :(得分:0)
创建您的containerView
。它需要的唯一限制是固定到centerX和centerY:
containerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
containerView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
然后,您需要做的只是使用子视图填充它,并确保这些子视图固定到容器视图的所有边缘。然后容器视图可以自我调整大小。
如果您的图片正是您要复制的内容,则甚至不需要第二步:只需使用垂直轴containerView
UIStackView
,然后添加所有{{1} }}
答案 3 :(得分:0)
第一种方法是使用UIStackView。
第二种方法是以编程方式生成约束。我将对此进行阐述,因为我主要是出于各种原因使用它。
我写了以下扩展名 - 随意使用它:
通过使用它,我可以更轻松地在代码中约束子视图。
我已在项目底部制作了用例样本。
// MARK: Layout priorities which are mostly used
class LayoutPriority {
static let required: Float = 1000
static let must: Float = 999
static let defaultHigh: Float = 750
static let defaultLow: Float = 250
static let zero: CGFloat = 0
}
extension UIView {
// Make sure the view applies to autolayout rules
private func validateViewForAutolayoutRules() throws -> Bool {
// Implies it is the caller responsibility to make sure the view has superview
guard let _ = superview else {
throw ConstraintErrorType.nullifiedSuperview("Superview is nil");
}
// Enable autolayout mechanism
if translatesAutoresizingMaskIntoConstraints {
translatesAutoresizingMaskIntoConstraints = false
}
return true
}
// This method assumes the two views share the same parent
@discardableResult
public func layout(_ firstAttribute: NSLayoutAttribute, to secondAttribute: NSLayoutAttribute, of view: UIView, relation: NSLayoutRelation = .equal, multiplier: CGFloat = 1.0, constant: CGFloat = 0, priority: UILayoutPriority = UILayoutPriority.required) -> NSLayoutConstraint? {
guard let selfValidationSuccess = try? validateViewForAutolayoutRules(), selfValidationSuccess == true else {
print("\(String(describing: self)) Error in func: \(#function)")
return nil
}
let constraint = NSLayoutConstraint(item: self, attribute: firstAttribute, relatedBy: .equal, toItem: view, attribute: secondAttribute, multiplier: multiplier, constant: constant)
constraint.priority = priority
superview!.addConstraint(constraint)
return constraint
}
// Set constant edge
@discardableResult
func setConstant(edge: NSLayoutAttribute, value: CGFloat, priority: UILayoutPriority = UILayoutPriority.required) -> NSLayoutConstraint?
{
// Enable autolayout mechanism
translatesAutoresizingMaskIntoConstraints = false
let constraint = NSLayoutConstraint(item: self, attribute: edge, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1.0, constant: value)
constraint.priority = priority
addConstraint(constraint)
return constraint
}
}
现在你以这种方式使用它:
containerView
,添加它,并将其置于其超级视图中(不设置高度)。containerView
的两侧和顶部。containerView
底部的底部。那样' containerView'垂直拉伸。
class ViewController: UIViewController {
func configure() {
// Generate container
let containerView = UIView()
view.addSubview(containerView)
// Cling center of 'containerView' to it's superview
containerView.layout(.centerX, to: .centerX, of: view)
containerView.layout(.centerY, to: .centerY, of: view)
containerView.layout(.right, to: .right, of: view, constant: -50)
containerView.layout(.left, to: .left, of: view, constant: 50)
// Setup first view
let firstView = UIView()
containerView.addSubview(firstView)
// Set constraints on firstView
firstView.setConstant(edge: .height, value: 50)
firstView.layout(.left, to: .left, of: containerView, constant: 20)
firstView.layout(.right, to: .right, of: containerView, constant: -20)
firstView.layout(.top, to: .top, of: containerView)
// Setup second view
let secondView = UIView()
containerView.addSubview(secondView)
// Set constraints on second view
secondView.setConstant(edge: .height, value: 50)
secondView.layout(.left, to: .left, of: containerView, constant: 20)
secondView.layout(.right, to: .right, of: containerView, constant: -20)
secondView.layout(.bottom, to: .bottom, of: containerView, constant: -50)
// Cling to to the first view
secondView.layout(.top, to: .bottom, of: firstView, constant: 20)
}
}