0

次のコードを参照してください。

def viewDidLoad
    super
    self.view.translatesAutoresizingMaskIntoConstraints = false
    self.view.backgroundColor = UIColor.whiteColor

    @start = UIButton.buttonWithType(UIButtonTypeRoundedRect).tap do |el|
      el.translatesAutoresizingMaskIntoConstraints = false          
      el.setTitle('Start', forState:UIControlStateNormal)
      el.addTarget(self, action:'toStartController', forControlEvents:UIControlEventTouchUpInside)
      self.view.addSubview(el)
    end

    self.layout_subviews
  end

def layout_subviews
    metrics = { 'space' => 8 }

    views_dict = { 
      'superview' => self.view, 
      'start' => @start
    }

    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('H:|-[start(100)]-|', 
                                                                    options: NSLayoutFormatAlignAllCenterX, 
                                                                    metrics: metrics, 
                                                                      views: views_dict))

    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('V:[start]-|', 
                                                                    options: NSLayoutFormatAlignAllBottom, 
                                                                    metrics: metrics, 
                                                                      views: views_dict))
  end

私が抱えている問題はH:|-[start(100)]-|うまくいきません。私が欲しいのは、X軸を中心とし、デフォルトのマージンで画面の下部に取り付けられた幅100のボタンです。これを削除するとすぐに機能(100)しますが、ボタンは画面の幅からデフォルトの余白を引いた幅まで伸びます。カスタム幅を指定すると、自動レイアウトシステムでは左右の余白を計算できないと思います。Unable to simultaneously satisfy constraints.エラーが発生します。これは、のダッシュと関係があると思います。ダッシュは、デフォルトのマージンではなく、要素をH:|-[start(100)]-|にアタッチするために流動的な幅を持っている必要があります。startsuperview

私がこれをどのように解決するかについて何か考えはありますか?

更新(ghettopiaに感謝):

UINavigationControllerこれは機能します(アプリデリゲートでaを使用していて、 self.view.translatesAutoresizingMaskIntoConstraints = falseinviewDidLoadTestControllerコメントアウトされていることに注意してください):

class AppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)
    @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds).tap do |win|
      controller = TestController.alloc.initWithNibName(nil, bundle:nil)
      win.rootViewController = UINavigationController.alloc.initWithRootViewController(controller).tap do |root|
        root.navigationBarHidden = true
        root.wantsFullScreenLayout = true
      end
      win.makeKeyAndVisible
    end
    true
  end
end

class TestController < UIViewController

  def viewDidLoad
    super
    # self.view.translatesAutoresizingMaskIntoConstraints = false
    self.view.backgroundColor = UIColor.blueColor

    @button = UIButton.buttonWithType(UIButtonTypeRoundedRect)
    @button.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(@button)

    views = { 
      'view' => self.view, 
      'button' => @button
    }

    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('H:[button(100)]', options: 0, metrics: nil, views: views))
    self.view.addConstraint(NSLayoutConstraint.constraintWithItem(@button, attribute: NSLayoutAttributeCenterX, relatedBy: NSLayoutRelationEqual, toItem: self.view, attribute: NSLayoutAttributeCenterX, multiplier: 1, constant: 0))
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('V:[button]-|', options: 0, metrics: nil, views: views))
  end
end

正しい画面

素晴らしい。これで、意図したとおり、X軸の中央にボタンがあり、デフォルトのマージンが下にあるブルースクリーンが表示されます。self.view.translatesAutoresizingMaskIntoConstraints = falseただし、自動レイアウトを機能させるには、私が読んだものから必要です。UINavigationControllerこれを実現するために、これも機能します(今回は使用しておらず、self.view.translatesAutoresizingMaskIntoConstraints = falseISが使用されていることに注意してください)。viewDidLoadTestController

class AppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)
    @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds).tap do |win|
      win.rootViewController = TestController.alloc.initWithNibName(nil, bundle:nil)
      win.makeKeyAndVisible
    end
    true
  end
end

class TestController < UIViewController

  def viewDidLoad
    super
    self.view.translatesAutoresizingMaskIntoConstraints = false
    self.view.backgroundColor = UIColor.blueColor

    @button = UIButton.buttonWithType(UIButtonTypeRoundedRect)
    @button.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(@button)

    views = { 
      'view' => self.view, 
      'button' => @button
    }

    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('H:[button(100)]', options: 0, metrics: nil, views: views))
    self.view.addConstraint(NSLayoutConstraint.constraintWithItem(@button, attribute: NSLayoutAttributeCenterX, relatedBy: NSLayoutRelationEqual, toItem: self.view, attribute: NSLayoutAttributeCenterX, multiplier: 1, constant: 0))
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('V:[button]-|', options: 0, metrics: nil, views: views))
  end
end

しかし、それは適切な解決策のようには思えません。UINavigationControllerアプリの構造を作成する必要があります。上記の解決策を使用しないと、真ん中(両方の軸)にボタンがない黒い画面が表示されます。ビューが壊れているようです: 黒い画面

考え?私はそれを削除self.view.translatesAutoresizingMaskIntoConstraints = falseして忘れるべきですか、それとも本当に必要ですか?もしそうなら、私のコードに何か問題があるに違いありません。

アップデート2:

興味深いチュートリアル:iOS 6の自動レイアウト:コードを介した制約の追加。作者はで使用せず、サブビューでのみ使用self.view.translatesAutoresizingMaskIntoConstraints = falseします。viewDidLoad

アップデート3:

の代わりにメソッドに移動self.view.translatesAutoresizingMaskIntoConstraints = falseすることで、ブラックスクリーンの問題を解決できたと思います。なぜこれが機能するのかはわかりませんが、最初に意図したように、画面はスクリーンショットと同じように見えます。更新されたコードは次のとおりです。initviewDidLoad

class AppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)
    @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds).tap do |win|
      controller = TestController.alloc.initWithNibName(nil, bundle:nil)
      win.rootViewController = UINavigationController.alloc.initWithRootViewController(controller).tap do |root|
        root.navigationBarHidden = true
        root.wantsFullScreenLayout = true
      end
      win.makeKeyAndVisible
    end
    true
  end
end    

class TestController < UIViewController

  def init
    self.view.translatesAutoresizingMaskIntoConstraints = false
  end

  def viewDidLoad
    super
    self.view.backgroundColor = UIColor.blueColor

    @button = UIButton.buttonWithType(UIButtonTypeRoundedRect)
    @button.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(@button)

    views = { 
      'view' => self.view, 
      'button' => @button
    }

    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('H:[button(100)]', options: 0, metrics: nil, views: views))
    self.view.addConstraint(NSLayoutConstraint.constraintWithItem(@button, attribute: NSLayoutAttributeCenterX, relatedBy: NSLayoutRelationEqual, toItem: self.view, attribute: NSLayoutAttributeCenterX, multiplier: 1, constant: 0))
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('V:[button]-|', options: 0, metrics: nil, views: views))
  end
end
4

1 に答える 1

6
UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect] ;
button.translatesAutoresizingMaskIntoConstraints = NO ;
[self.view addSubview:button] ;

NSDictionary* views = @{ @"view" : self.view  ,  @"button" : button } ;
// Make button's width 100.
[self.view addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:[button(100)]"  options:0   metrics:nil  views:views ] ] ;
// Make button's CenterX the same as self.view's CenterX.
[self.view addConstraint: [NSLayoutConstraint constraintWithItem:button  attribute:NSLayoutAttributeCenterX  relatedBy:NSLayoutRelationEqual  toItem:self.view  attribute:NSLayoutAttributeCenterX  multiplier:1  constant:0 ] ] ;
// Make button's NSLayoutAttributeBottom the default space away from self.view's NSLayoutAttributeBottom.
[self.view addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"V:[button]-|"  options:0   metrics:nil  views:views ] ] ;
于 2012-12-15T18:56:06.680 に答える