自動レイアウトを使用して合計幅のパーセンテージを作成するにはどうすればよいですか?


114

3つの動的な列を作成する必要があります。それぞれの列は、全幅の一定のパーセンテージを持っています。3分の1ではなく、異なる値。たとえば、次の図は3つの列を示しています。最初の列は42%幅、2番目は25%幅、3番目は33%幅です。

ビューコントローラ全体で600ピクセルの場合、それぞれ252、150、198ピクセルになります。

ただし、それ以降のディスプレイサイズ(iPhone 4ランドスケープ(幅960)またはiPad 2ポートレート(幅768))では、相対的なパーセンテージを同じにします(上記のピクセル幅ではありません)。

ストーリーボードを使用して(つまり、コードなしで)これを行う方法はありますか?これはコードで簡単に実行できますが、私の目標は、この表示ロジックをできるだけストーリーボードに配置することです。

ここに画像の説明を入力してください

回答:


205

あなたが言うように、あなたがコードでそれを行う方法を知っているなら、あなたはすでにストーリーボードでそれを行う方法を知っています。これはまったく同じ制約ですが、コードではなく視覚的に作成します。

  1. ビューとそのスーパービューの両方を選択します。

  2. Editor-> Pin-> Widths Equallyを選択して、幅をスーパービューの幅に等しくなるように制限します(実際には、キャンバスの下部にある「ピン」ポップアップダイアログが最適です)。

  3. 制約を編集し、Multiplierを希望する分数、たとえば0.42に設定します。他のビューについても同様です。


9
制約しているビューが、スーパービューの幅ではなく、等幅制約の「最初の項目」に表示されていることを確認してください。そうでない場合は、サブビューの幅がスーパービューの幅の倍数になります。等幅制約を適用するためにサブビューからスーパービューにコントロールドラッグすると、これらは常に逆になります。これは私には直観に反するようです。
メモン14年

ああ-「コードでそれを行う」とは、「手動で、制約や自動レイアウトなしに」のようなものを意味しました。
Jeffrey Berthiaume、2014年

素敵な答え。IBが制約を編集せずにこれを行う方法を提供していないことに驚きます。
wcochran 2015年

これをUITableViewCellに適用しようとすると、すべてがグレー表示されていました。すべてのビューを新しいビューに埋め込み、ラベルからこの新しいビューまでの幅を等しく選択する必要がありました。それが役に立てば幸い。
nano

6
Xcode7の新機能:ビューを均等に整列させたい場合は、新しい「スタックビュー」を使用してください。
Bijan

15

AppleがUIStackViewを導入すると、作業が非常に簡単になりました。

方法1:Nib / StoryBoardを使用する:

あなたはインターフェースビルダーに3つのビューを追加し、それらをstackviewに埋め込む必要があります

Xcode►エディター►埋め込み►StackView

ここに画像の説明を入力してください

stackViewを選択し、safeAreaでリーディング、トレーリング、トップ&等しい高さで制約を与える

クリックして属性インスペクター領域に 設定し、StackViewの水平方向と分布を設定して比例的に塗りつぶします

[ ここに画像の説明を入力してください3

側面のそれぞれにリーディング、トレーリング、トップ、ボトムの3つのビューの制約を与えます。 ここに画像の説明を入力してください

方法2:プログラムで:

import UIKit
class StackViewProgramatically: UIViewController {
    var propotionalStackView: UIStackView!
    ///Initially defining three views
    let redView: UIView = {
        let view = UIView()//taking 42 % initially
        view.frame = CGRect(x: 0, y: 0, width: 42 * UIScreen.main.bounds.width/100, height: UIScreen.main.bounds.height)
        view.backgroundColor = .red
        return view
    }()

    let greenView: UIView = {
        let view = UIView()//taking 42* initially
        view.frame = CGRect(x: 42 * UIScreen.main.bounds.width/100, y: 0, width: 25 * UIScreen.main.bounds.width/100, height: UIScreen.main.bounds.height)
        view.backgroundColor = .green
        return view
    }()
    let blueView: UIView = {
        let view = UIView()//taking 33*initially
        view.frame = CGRect(x: 67 * UIScreen.main.bounds.width/100, y: 0, width: 33 * UIScreen.main.bounds.width/100, height: UIScreen.main.bounds.height)
        view.backgroundColor = .blue
        return view
    }()

    ///Changing UIView frame to supports landscape mode.
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        DispatchQueue.main.async {
            self.redView.frame = CGRect(x: 0, y: 0, width: 42 * self.widthPercent, height: self.screenHeight)
            self.greenView.frame = CGRect(x: 42 * self.widthPercent, y: 0, width: 25 * self.widthPercent, height: self.screenHeight)
            self.blueView.frame = CGRect(x: 67 * self.widthPercent, y: 0, width: 33 * self.widthPercent, height: self.screenHeight)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        //Adding subViews to the stackView
        propotionalStackView = UIStackView()
        propotionalStackView.addSubview(redView)
        propotionalStackView.addSubview(greenView)
        propotionalStackView.addSubview(blueView)
        propotionalStackView.spacing = 0
        ///setting up stackView
        propotionalStackView.axis = .horizontal
        propotionalStackView.distribution = .fillProportionally
        propotionalStackView.alignment = .fill
        view.addSubview(propotionalStackView)
    }
}
//MARK: UIscreen helper extension
extension NSObject {

    var widthPercent: CGFloat {
        return UIScreen.main.bounds.width/100
    }

    var screenHeight: CGFloat {
        return UIScreen.main.bounds.height
    }
}

出力:

横向きと縦向きで動作します

ここに画像の説明を入力してください ここに画像の説明を入力してください

デモプロジェクト-https://github.com/janeshsutharios/UIStackView-with-constraints

https://developer.apple.com/videos/play/wwdc2015/218/


4

これはより詳細に説明できるので、スーパービュー内で一定の割合のレイアウトが必要な任意の数のビューに簡単に適用できると思います。

左端のビュー

  • に固定 SuperView.Leading
  • 固定比率を乗数として定義します SuperView.Height

中間ビュー

  • 固定比率を乗数として定義します SuperView.Height
  • そのピンleftの隣の右に

右からのビュー

  • 固定パーセンテージを定義していません(利用可能な残りのビューです)
  • そのピンleftの隣の右に
  • ピンそのrightSuperView.Trailing

すべてのビュー

  • Top Layout Guide.Topおよびにアンカーして、固定されていない高さを定義しTop Layout Guide.bottomます。上記の回答では、これは隣接するビューに同じ高さを設定することによっても実行できることに注意してください。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.