0

3 つのサブビューを持つ縦型UIStackViewがあり、これら 3 つのサブビューすべてのコンテンツを中央に配置したいと考えています。ストーリーボードではなく、すべてプログラムでこれを行っています。ストーリーボードを使用することから始めて、最後に追加するだけで、arrangedSubviewさらに複雑なことを追加しました。

スタック ビュー自体、各サブビュー、およびそれらすべてを同時に設定してみました (以下を参照)。それらのどれも何の影響もありません - これらの 3 つのサブビューのすべては、私が何をしても、コンテナー ビューに対してフラッシュ レフトのままです。また、別のスレッドで見たものに基づいて、自動サイズ変更サブビューが IB でチェックされていないことを確認しましたが、どちらも違いはありませんでした。

ここで私が間違っていることを誰かに教えてもらえますか? ありがとう。

override func viewDidLoad() {
    super.viewDidLoad()
    let horizontalCenter = self.view.frame.width/2
    let verticalCenter = self.view.frame.height/2

    // the stackview that lives in 'emptyLogView'
    let liftLogStackView = UIStackView(frame: CGRect(x: horizontalCenter, y: verticalCenter, width: 320, height: 480))
    liftLogStackView.axis = .Vertical
    liftLogStackView.distribution = UIStackViewDistribution.FillEqually
    liftLogStackView.contentMode = .Center

    // 1st subview
    let weightsImage = UIImage(named: "weights_image")
    let weightsContainerView = UIImageView(image: weightsImage)
    weightsContainerView.frame = CGRect(x: 0, y: 0, width: 320, height: 77)
    weightsContainerView.contentMode = .Center

    // 2nd subview
    let noLiftsMessageContainerView = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 40))
    let noLiftsMessage = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 20))
    noLiftsMessage.text = "You don't have any lifts saved."
    noLiftsMessage.textColor = UIColor(hexString: "b7b7b7")
    noLiftsMessageContainerView.contentMode = .Center

    // 3rd subview
    let letsDoThisContainerView = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 40))
    let doThisButton = UIButton(frame: CGRect(x: 0, y: 0, width: 120, height: 36))
    doThisButton.setTitle("Let's do this.", forState: .Normal)
    doThisButton.setTitleShadowColor(UIColor.blackColor(), forState: .Highlighted)
    doThisButton.layer.cornerRadius = 6
    doThisButton.layer.backgroundColor = UIColor(hexString: "b7b7b7").CGColor
    doThisButton.layer.borderWidth = 0
    letsDoThisContainerView.contentMode = .Center

    noLiftsMessageContainerView.addSubview(noLiftsMessage)
    letsDoThisContainerView.addSubview(doThisButton)

    liftLogStackView.addArrangedSubview(weightsContainerView)

    liftLogStackView.addArrangedSubview(noLiftsMessageContainerView)

    liftLogStackView.addArrangedSubview(letsDoThisContainerView)

    liftLogStackView.translatesAutoresizingMaskIntoConstraints = false

    emptyLogView.addSubview(liftLogStackView)

    let horizontalCenterConstraint = NSLayoutConstraint(item: liftLogStackView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: emptyLogView, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0)

    let verticalCenterConstraint = NSLayoutConstraint(item: liftLogStackView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: emptyLogView, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0)

    emptyLogView.addConstraint(horizontalCenterConstraint)
    emptyLogView.addConstraint(verticalCenterConstraint)
}

アップデート

6年前のSOスレッドでもう1つ試してみましたが、どちらも機能しませんでした:

    let letsDoThisContainerView = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 40))
    let doThisButton = UIButton(frame: CGRect(x: 0, y: 0, width: 120, height: 36))
    doThisButton.setTitle("Let's do this.", forState: .Normal)
    doThisButton.setTitleShadowColor(UIColor.blackColor(), forState: .Highlighted)
    doThisButton.layer.cornerRadius = 6
    doThisButton.layer.backgroundColor = UIColor(hexString: "b7b7b7").CGColor
    doThisButton.layer.borderWidth = 0

    // this is the new thing
    let contentAlignmentMode = UIViewContentMode.Center
    liftLogStackView.contentMode = contentAlignmentMode

また、別の設定を試みましたcontentMode.Right、何も起こりません。私が何をしても、要素はすべて左に詰まっています。

更新 2

答えの一部を見つけました(と思います)。それはUIStackViewAlignment私が必要なもののようです。だから私は今これを持っています:

    let liftLogStackView = UIStackView(frame: CGRect(x: horizontalCenter, y: verticalCenter, width: 320, height: 480))
    liftLogStackView.axis = .Vertical
    liftLogStackView.distribution = UIStackViewDistribution.FillEqually

    // Finally, this has an affect on the alignment
    liftLogStackView.alignment = UIStackViewAlignment.Center

しかし、中央揃えではなく、ほぼ右揃えのように見えます (青いボックスはスタック ビューです)。

ここに画像の説明を入力

ビューが親ビューの境界を認識していないように見えますが、スタックビューとそのサブビューを正しく作成していると思います。

何か案は?

4

1 に答える 1

1

しかし、スタックビューとそのサブビューを正しく作成していると思います

もう一度考えてみて。あなたはそれらを完全に間違って作成しています。この 1 つの整理されたビューだけを考えてみましょう。

let weightsImage = UIImage(named: "weights_image")
let weightsContainerView = UIImageView(image: weightsImage)
weightsContainerView.frame = CGRect(x: 0, y: 0, width: 320, height: 77)

ここで2 つの間違ったことをしています (数え方によっては 3 つかもしれません)。

  • フレームを設定しないでください。それは無意味です。これはスタック ビューです。制約を通じて機能します。制約はフレームの反対です。どちらかを使用します。

  • 制約を設定する必要があります! イメージ ビューに制約を与えていません。したがって、単にビューのサイズに設定する必要があります。特に、スタック ビューが実行するすべての作業は、配置されたビューに基づいていintrinsicContentSizeます。意図したとおりに機能させるには、十分な情報を提供する必要があります。

  • translatesAutoresizingMaskIntoConstraints画像ビューを に設定するのを忘れましたfalse。したがって、スタック ビューによって課される制約は、イメージ ビューの自動サイズ変更と競合します。実際、プロジェクトを実行するときにコンソールを見るだけで、ランタイムが「競合!」と叫んでいることがわかると確信しています。あなたに。

ストーリーボードではなく、すべてプログラムでこれを行っています

これは崇高な目標ですが、ストーリーボード (または xib ファイル) で実行することをお勧めします。これは、コードが実行しているよりも、これらすべてをうまく処理できるからです。

于 2016-11-04T16:38:08.740 に答える