【问题标题】:Initializing a Custom UIView using only Constraints (IOS)仅使用约束 (IOS) 初始化自定义 UIView
【发布时间】:2017-04-26 02:45:33
【问题描述】:

我被指示创建一个井字游戏。

要求是:

  1. 仅使用 MVC
  2. 以编程方式显示视图
  3. 仅使用约束设置正方形的大小

因此,我创建了一个 Board 类和一个 Square 类。板类几乎只是一个带有背景颜色的 UIView。我在初始化的主要问题。每次我使用自定义 UIView 时,我都必须使用 CGRect 框架进行初始化。讲师告诉我们不要直接使用 CGRect 函数设置视图的框架,而只能使用约束。

这就是问题所在。我正在尝试在另一个视图中初始化一个板。因为板子是 UIView 的子类,所以我必须设置一个框架。

如何在没有框架的情况下将 UIView 初始化为只能使用传入参数中的 UIView 的约束来设置它的 Size?

下面是我现在正在做的事情。我想在没有 frame 参数的情况下初始化它,但它是必需的。我想初始化这个类并在另一个视图控制器类的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")
}

当我创建板类时,我想将约束设置为我在初始化类时作为参数传入的view。令人沮丧的是,它不会生效,因为我必须使用所需的帧初始化程序。

有没有办法解决这个问题?

【问题讨论】:

    标签: ios swift cocoa-touch uiview nslayoutconstraint


    【解决方案1】:

    你的约束是错误的;你正试图将你的观点限制在自己身上。您是否试图约束您的视图以填充其超级视图?

        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
            }
        }
    

    【讨论】:

      【解决方案2】:

      您可以简单地做到这一点。这是代码

          //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)
      

      顺便说一句,你不需要框架,因为这个值是计算出来的。您可以创建视图、添加视图并设置适当的约束。希望这对您有所帮助。

      【讨论】:

        【解决方案3】:

        您可以使用默认框架进行初始化。当您应用约束时,约束将覆盖您设置的原始框架。

        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()
            }
        }
        

        【讨论】:

        • 谢谢!这是根据传入的UIView参数设置约束的方式吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-08-06
        • 2018-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多