2016-12-10 10 views
0

tic-tac-toeゲームを作成するように指示されました。Constraints(IOS)のみを使用してカスタムUIViewを初期化する

要件は次のとおりです。

  1. のみを使用してMVC
  2. 表示プログラムで
  3. だけこのため

は、私が作成した制約に正方形のサイズを設定するビューボードクラスとスクエアクラスです。ボードクラスは、ほとんど背景色を持つUIViewだけです。初期化における私の主な問題。カスタムUIViewを使用するたびに、CGRectフレームで初期化する必要があります。インストラクターは、CGRect関数を使用してビューのフレームを直接設定するのではなく、制約があることを教えてくれました。

これは問題です。私は別のビューの中でボードを初期化しようとしています。ボードはUIViewのサブクラスなので、フレームを設定するにはHAVEが必要です。

フレームなしでUIViewを初期化して、渡されたパラメータからUIViewの制約のみを使用してサイズを設定できるようにするにはどうすればよいですか?

以下は私が今やっていることです。私は、フレームパラメータなしでそれを初期化したいと思いますが、それは必須です。このクラスを初期化し、別の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") 
} 

は、私はクラスを初期化するとき、私は、パラメータとして渡されたviewに制約を設定したいと思います。私が使用しなければならない必要なフレームイニシャライザのために、挫折して、それは有効になりません。

これを回避する手段はありますか?

答えて

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

ありがとうございました!これは渡されるUIViewパラメータに従って制約を設定する方法ですか? –

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) 

私はこの値が計算されるので、フレームは必要ありません。ビューを作成して追加し、適切な制約を設定することができます。これがあなたを助けることを願っています。

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 
     } 
    } 
関連する問題