我被指示制作一个井字游戏。
要求是:
因此,我创建了一个Board类和一个Square类。董事会类它几乎只是一个背景颜色的UIView。我在初始化中的主要问题。每次我使用Custom UIView时,我都必须使用CGRect框架初始化。教师告诉我们不要直接使用CGRect函数设置视图的帧,而只是使用约束。
这就是问题所在。我试图在另一个视图内初始化一个板。因为该板是UIView的子类,所以我 HAVE 来设置一个帧。
如何在没有框架的情况下初始化UIView,这样你只能使用传入的参数来设置UIView的约束来设置它的大小?
以下是我现在正在做的事情。我想在没有frame参数的情况下初始化它,但它是必需的。我想初始化这个类,并在另一个viewcontroller类的viewDidLoad
函数中使用它。我想传递UIView作为参数,并根据特定视图调整约束。
class Board: UIView {
init(frame: CGRect, view: UIView) {
super.init(frame: frame)
self.backgroundColor = .green
self.translatesAutoresizingMaskIntoConstraints = false
addConstraints(view: view)
}
func addConstraints(view:UIView){
NSLayoutConstraint(item: view,
attribute: .leading,
relatedBy: .equal,
toItem: view,
attribute: .leading,
multiplier: 1,
constant: 0).isActive = true
NSLayoutConstraint(item: view,
attribute: .trailing,
relatedBy: .equal,
toItem: view,
attribute: .trailing,
multiplier: 1,
constant: 0).isActive = true
NSLayoutConstraint(item: view,
attribute: .height,
relatedBy: .equal,
toItem: view,
attribute: .height,
multiplier: 1,
constant: 0).isActive = true
NSLayoutConstraint(item: view,
attribute: .width,
relatedBy: .equal,
toItem: view,
attribute: .width,
multiplier: 1,
constant: 0).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
当我创建board类时,我想在初始化类时将约束设置为我作为参数传入的view
。令人沮丧的是,它不会生效,因为我必须使用所需的帧初始化器。
有什么方法吗?
答案 0 :(得分:1)
您可以使用默认框架进行初始化。应用约束时,约束将覆盖您设置的原始帧。
class CustomView: UIView {
init(frame: CGRect, otherParam: Int) {
super.init(frame: frame) // Init with in case there are no constraints
setup()
}
}
或
class CustomView: UIView {
init(otherParam: Int) {
let frame = CGRect(x: 0, y:0, width: 100, height: 100)
super.init(frame: frame) // Init with a default frame
setup()
}
}
答案 1 :(得分:0)
//create
let childredView = UIView()
childredView.translatesAutoresizingMaskIntoConstraints = false
childredView.backgroundColor = UIColor.purple
//add it
self.view.addSubview(childredView)
self.view.bringSubview(toFront: childredView)
//set constraints
let views = ["childrenView": childredView]
let vertical = NSLayoutConstraint.constraints(withVisualFormat: "V:|[childrenView]|", options: [], metrics: nil, views: views)
let horizontal = NSLayoutConstraint.constraints(withVisualFormat: "H:|[childrenView]|", options: [], metrics: nil, views: views)
let all = vertical + horizontal
//activate them
NSLayoutConstraint.activate(all)
顺便说一句,你不需要框架,因为这个值是计算出来的。您可以创建视图,添加视图并设置适当的约束。希望这可以帮到你。
答案 2 :(得分:0)
你的约束是错误的;你试图限制自己的观点。您是否试图限制视图以填充其超级视图?
extension UIView {
func constrainToSuperView() {
translatesAutoresizingMaskIntoConstraints = false
let attributes: [NSLayoutAttribute] = [.top, .bottom, .leading, .trailing]
attributes.forEach { NSLayoutConstraint(item: self, attribute: $0, relatedBy: .equal, toItem: self.superview, attribute: $0, multiplier: 1, constant: 0).isActive = true}
}
}
同样,NSLayoutAnchor比NSLayoutConstraint更加初学者友好,因为它的强类型:
extension UIView {
func constrainToSuperView() {
guard let superview = superview else {
return
}
translatesAutoresizingMaskIntoConstraints = false
topAnchor.constraint(equalTo: superview.topAnchor).isActive = true
bottomAnchor.constraint(equalTo: superview.bottomAnchor).isActive = true
leadingAnchor.constraint(equalTo: superview.leadingAnchor).isActive = true
trailingAnchor.constraint(equalTo: superview.trailingAnchor).isActive = true
}
}