2016-09-19 6 views
2

私はiMessageアプリケーションを使用しており、プログラムによってビューを追加しました。しかし、私はそれを常に正しいサイズにするための正しい制約を解決できないようです。たとえば、私が別のエクステンションのためにエクステンションを残して戻ってくると、ビューは数百px下がります。私はこれが.isActiveと関係があると思う。私の目標は、常に適切なサイズになるようにビューのサイズを自動的に変更するか、利用可能な高さと幅をすべて利用することです。プログラムでフルサイズビューを迅速に追加する

func createBrowser() { 
    let controller = MSStickerBrowserViewController(stickerSize: .small) 
    addChildViewController(controller) 
    view.addSubview(controller.view) 

    controller.view.translatesAutoresizingMaskIntoConstraints = false 
    controller.stickerBrowserView.backgroundColor = UIColor.blue 
    controller.stickerBrowserView.dataSource = self 

    view.topAnchor.constraint(equalTo: controller.view.topAnchor).isActive = true 
    view.bottomAnchor.constraint(equalTo: controller.view.bottomAnchor).isActive = true 
    view.leftAnchor.constraint(equalTo: controller.view.leftAnchor).isActive = true 
    view.rightAnchor.constraint(equalTo: controller.view.rightAnchor).isActive = true 
    view.centerXAnchor.constraint(equalTo: controller.view.centerXAnchor).isActive = true 
    view.centerYAnchor.constraint(equalTo: controller.view.centerYAnchor).isActive = true 
} 

スクリーンショット:https://d17oy1vhnax1f7.cloudfront.net/items/1F2B0s3v0s1k3E2L0Z07/Screen%20Shot%202016-09-19%20at%2011.42.51%20AM.png

+0

これは愚かな質問があることも/私が正しくあなたのコードを読むことがないかもしれませんが、あなたを持っていますあなたの制約は間違った方向に向いていますか?古いビューの制約に基づいて新しいビューの制約を設定しないでください。新しい子コントローラのビューに基づいて、親コントローラのビューの制約を設定しているかのように見えます。 – Sparky

+0

@ Sparkyこのような意味ですか? controller.view.topAnchor.constraint(equalTo:view.topAnchor).isActive = trueです。私はそれを行い、行動は同じです。 –

+0

@ Sparky?申し訳ありませんが、iOS開発者には比較的新しいです。リル '助け?ありがとう! –

答えて

0

が良く、私は一緒に以下を入れている事を説明します。これは、サブビューのレイアウトを修正する2つの方法を示しています。制約を使用する場合は、配列として制約を作成し、createredSquareWithConstraintsのコードに示すように、すべてを一度に有効にすることをお勧めします。制約は、1つのビューのフィーチャを別のフィーチャのフィーチャに関連付ける単純な線形方程式です。たとえば、「擬似コード」では、配列の最初の制約は次のように書くことができます。

「サブビューの先頭の余白をコンテナビューの先頭に1を加えたものに0を加えたものに設定します。

(あなたはサブビューの一つの特徴に基づい含むビューの制約を設定したかのように、それは私には見えたとして私は以前に混乱して理由です。)

それはレイアウトを使用するために完全に有効なままであるが私が思うのは、viewWillTransitionToSize()デリゲートメソッドをオーバーライドすることです。ビューメソッドのサブビューのフレームは、含まれているビューのサイズを指定するだけです。そのため、これも実装しました。最初のフレームのある黄色の四角形を作成し、viewWillTransitionToSizeが呼び出されるたびに変更されます。私は個人的には、レイアウトの制約を使用するよりも、あまり控え目に感じることがありません。

ボタンで囲み、画面を回転させると、いずれの方法も同じことが実現するはずです。 [NB私は1つの広場を拘束されたものとして、そして1つは拘束されていないものとしてラベル付けしましたが、実際には両方とも異なる方法で拘束されています。これは明らかに実際に何をするかではないことを付け加えておきます。一つの方法論を選択し、そうでなければあなたのコードを全部置くべきです!

希望に役立ちます!

import UIKit 

class ViewController: UIViewController { 

    var constrainedredSquare : UIView! 
    var unconstrainedRedSquare : UIView! 
    var methodOneButton : UIButton! 
    var methodTwoButton : UIButton! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
     self.view.backgroundColor = UIColor.blue 

     func getButton(name: String) -> UIButton { 
      let button : UIButton = UIButton() 
      button.backgroundColor = UIColor.white 
      button.layer.cornerRadius = 3 
      button.clipsToBounds = true 
      button.setTitle(name, for: UIControlState.normal) 
      button.setTitleColor(UIColor.black, for: UIControlState.normal) 
      return button 
     } 

     self.methodOneButton = getButton(name: "Red - Constraints") 
     self.methodTwoButton = getButton(name: "Yellow - viewWillTransitionToSize") 

     self.methodOneButton.addTarget(self, action: #selector(self.createRedSquareWithConstraints), for: .touchUpInside) 
     self.methodTwoButton.addTarget(self, action: #selector(self.createYellowSquareWithoutConstraints), for: .touchUpInside) 
     self.methodOneButton.frame = CGRect(origin: CGPoint(x: 200, y: 100), size: CGSize(width: 300, height: 300)) 
     self.methodTwoButton.frame = CGRect(origin: CGPoint(x: self.view.frame.width - 500, y: 100), size: CGSize(width: 300, height: 300)) 
     self.view.addSubview(self.methodOneButton) 
     self.view.addSubview(self.methodTwoButton) 

    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 
     if let _ = self.unconstrainedRedSquare { 
      self.unconstrainedRedSquare.frame = CGRect(origin: CGPoint.zero, size: size) 
     } 
     self.methodOneButton.frame = CGRect(origin: CGPoint(x: 200, y: 100), size: CGSize(width: 300, height: 300)) 
     self.methodTwoButton.frame = CGRect(origin: CGPoint(x: size.width - 500, y: 100), size: CGSize(width: 300, height: 300)) 
    } 


    func createYellowSquareWithoutConstraints() { 
     if let _ = self.unconstrainedRedSquare { 
      self.unconstrainedRedSquare.removeFromSuperview() 
     } 
     else 
     { 
      if let _ = constrainedredSquare { 
       self.constrainedredSquare.removeFromSuperview() 
      } 
      self.unconstrainedRedSquare = UIView() 
      self.unconstrainedRedSquare.backgroundColor = UIColor.yellow 
      self.unconstrainedRedSquare.frame = CGRect(origin: CGPoint.zero, size: self.view.frame.size) 
      self.view.addSubview(self.unconstrainedRedSquare) 

      self.view.bringSubview(toFront: self.methodOneButton) 
      self.view.bringSubview(toFront: self.methodTwoButton) 
     } 

    } 

    func createRedSquareWithConstraints() { 
     if let _ = self.constrainedredSquare { 
      self.constrainedredSquare.removeFromSuperview() 
     } 
     else 
     { 
      if let _ = self.unconstrainedRedSquare { 
       self.unconstrainedRedSquare.removeFromSuperview() 
      } 
      let redSquare : UIView = UIView() 
      redSquare.backgroundColor = UIColor.red 

      self.view.addSubview(redSquare) 

      self.view.bringSubview(toFront: self.methodOneButton) 
      self.view.bringSubview(toFront: self.methodTwoButton) 

      let rsConstraints : [NSLayoutConstraint] = [NSLayoutConstraint(item: redSquare, attribute: NSLayoutAttribute.leading, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.leading, multiplier: 1.0, constant: 0), 
               NSLayoutConstraint(item: redSquare, attribute: NSLayoutAttribute.trailing, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.trailing, multiplier: 1.0, constant: 0), 
               NSLayoutConstraint(item: redSquare, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.top, multiplier: 1.0, constant: 0), 
               NSLayoutConstraint(item: redSquare, attribute: NSLayoutAttribute.bottom, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.bottom, multiplier: 1.0, constant: 0), 
               NSLayoutConstraint(item: redSquare, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.width, multiplier: 1.0, constant: 0), 
               NSLayoutConstraint(item: redSquare, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.height, multiplier: 1.0, constant: 0)] 
      redSquare.translatesAutoresizingMaskIntoConstraints = false 
      NSLayoutConstraint.activate(rsConstraints) 
     } 
    } 
} 
0

UIViewに私の内線番号を使用することができます。それは(あなたがしたい場合のみ)いずれかの側に余分なパディングを追加することができます:

public extension UIView { 
    typealias ConstraintsTupleStretched = (top:NSLayoutConstraint, bottom:NSLayoutConstraint, leading:NSLayoutConstraint, trailing:NSLayoutConstraint) 
    func addSubviewStretched(subview:UIView?, insets: UIEdgeInsets = UIEdgeInsets()) -> ConstraintsTupleStretched? { 
     guard let subview = subview else { 
      return nil 
     } 

     subview.translatesAutoresizingMaskIntoConstraints = false 
     addSubview(subview) 

     let constraintLeading = NSLayoutConstraint(item: subview, 
                attribute: .Left, 
                relatedBy: .Equal, 
                toItem: self, 
                attribute: .Left, 
                multiplier: 1, 
                constant: insets.left) 
     addConstraint(constraintLeading) 

     let constraintTrailing = NSLayoutConstraint(item: self, 
                attribute: .Right, 
                relatedBy: .Equal, 
                toItem: subview, 
                attribute: .Right, 
                multiplier: 1, 
                constant: insets.right) 
     addConstraint(constraintTrailing) 

     let constraintTop = NSLayoutConstraint(item: subview, 
               attribute: .Top, 
               relatedBy: .Equal, 
               toItem: self, 
               attribute: .Top, 
               multiplier: 1, 
               constant: insets.top) 
     addConstraint(constraintTop) 

     let constraintBottom = NSLayoutConstraint(item: self, 
                attribute: .Bottom, 
                relatedBy: .Equal, 
                toItem: subview, 
                attribute: .Bottom, 
                multiplier: 1, 
                constant: insets.bottom) 
     addConstraint(constraintBottom) 
     return (constraintTop, constraintBottom, constraintLeading, constraintTrailing) 
    } 

} 

使用法:

view.addSubviewStretched(tableView) 

let BorderedBackgroundInset = UIEdgeInsets(top: 1, left: 1, bottom: 1, right: 1) 
view?.addSubviewStretched(calendar.view, insets: BorderedBackgroundInset) 
+0

最新版の迅速に対応するために制約内のコードを調整しなければならなかったが、これは完全に機能した。ありがとう! –

+0

このメッセージが表示されます。「addSubvieStretched(subview:insets :)」の呼び出し結果は使用されていません。どう言う意味ですか? –

+0

上記を使用して生成されるエラーのスクリーンショットを以下に示します。https://www.dropbox.com/s/8gi67ulcjuldm4k/Screenshot%202016-10-05%2012.24.48.png?dl=0およびhttps:/ /www.dropbox.com/s/t9ks7d02coycicb/Screenshot%202016-10-05%2012.26.34.png?dl=0 –

関連する問題