为什么忽略UIImageView.content模式

时间:2016-11-03 04:01:19

标签: swift uistackview contentmode

我有一个包含三个子视图的垂直UIStackView,我想将内容集中在所有这三个子视图中。我是以编程方式执行此操作,而不是使用故事板。我开始尝试使用故事板,只添加最后arrangedSubview但更复杂的事情。

我已经尝试在堆栈视图本身,每个子视图上设置'.contentMode`,同时在所有子视图上设置它们(如下所示)。它们都没有任何影响 - 无论我做什么,这三个子视图中的所有内容都保持与容器视图齐平。我还确保基于我在另一个帖子中看到的内容未在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线程上发现了另外一件事,但它也没有用:

    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

但是它不是居中,而是看起来几乎是右对齐(蓝色框是堆栈视图):

enter image description here

在我看来,视图不知道它们所在的父视图的边界,但我认为我正在正确地创建堆栈视图及其子视图。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

  

但我认为我正确地创建了堆栈视图及其子视图

再想一想。你完全错了。让我们考虑一下这个安排好的观点:

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

你在这里犯了两个错误的东西(可能是三个,具体取决于你的数量)。

  • 您不能设置任何帧。这毫无意义。这是一个堆栈视图!它通过约束来完成它的工作。约束与框架相反;你使用其中一种。

  • 您必须设置约束!您尚未向图像视图提供任何约束。所以它只是想将自己设置为视图的大小。特别是,堆栈视图将执行的所有工作都基于其排列视图的intrinsicContentSize。您需要提供足够的信息,使其按照您的意图工作。

  • 您忘记将图片视图translatesAutoresizingMaskIntoConstraints设置为false。因此,堆栈视图所施加的约束将与图像视图的自动调整冲突。事实上,我很确定如果你只是在运行项目时查看控制台,你将看到运行时正在尖叫"冲突!"在你。

  

我是以编程方式完成所有操作,而不是使用故事板

这是一个崇高的目标,但我建议你在故事板(或xib文件)中做得更好,因为它会比你的代码做得更好。