gpt4 book ai didi

ios - 自动布局 - 可折叠 View (垂直)

转载 作者:行者123 更新时间:2023-11-28 21:55:13 24 4
gpt4 key购买 nike

我想创建一个“添加新的信用卡 viewController”。我们不想因为一次显示所有必填字段而激怒用户。此操作包含几个步骤。在每一步中, View Controller 都会显示一个新的 subview (其中包含一个或多个文本字段)并折叠一个旧的 subview (验证文本后的当前文本字段)。

  1. 我已经在 Storyboard上创建了 ViewController。并将其所有 subview 一个放在另一个之上。

  2. 我已经在 storyBoard 上创建了所有约束,每个 subview 对上面 subview 的剪辑等等。

即:

NSMutableArray *constraints = [[NSLayoutConstraint
constraintsWithVisualFormat:
@"V:|[titleView]-[subtitleView]-[amountView]-[cardNumView]-[cardsImagesView]-[mmYYCvvView]-[billingInfoView]-[buttomView]|"
options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom
metrics:nil
views:variableBindings] mutableCopy];
  1. 这些 subview 中的每一个都包含一个高度限制。

  2. 在每一步中,一个高度约束设置为零,另一个从零变为所需高度。

即:

self.hgtCrtMMYYCvv.constant = showFields? 50 : 0;
self.hgtCrtBillingInfo.constant = showFields? 140 : 0;
self.mmYYCvvView.hidden = !showFields;
self.billingInfoView.hidden = !showFields;

我有两个问题:

  • 在不调用 layoutIfNeeded 的情况下,初始布局是有效的,但在更改高度限制后没有更改。

  • 调用 layoutIfNeeded 没有将底部 View 裁剪到最后一个可见的 View - 将它放置在 View 的底部,就好像所有 subview 同时出现一样,但由于有些 subview 被隐藏了差距被创造了。更改 subview 的高度约束已应用到屏幕上,但间隙仍然存在。

请指教。

最佳答案

Calling "layoutIfNeeded" did not clip the bottom view to the last visible one - placed it at the bottom of the view as if all the subviews appear at once

查看您的限制条件。您已将底部 View 的底部固定到其父 View 的底部!所以它的底部必须出现在父 View 的底部,因为那是你指示它做的。

确实,令我惊讶的是您的约束竟然有效。您基本上已经过度确定了它们。如果您为每个字段指定一个高度固定其顶部和底部,对于每个字段,除非您非常幸运,否则将不可能满足您的约束条件。父 View 的高度是固定的,因此您的约束必须完美地加到那个高度。

我将建议一个完整的替代方法,我认为您会发现它更容易。不要弄乱单个常量,而是为每种可能的情况计划正确的(不是过度确定的)约束,并将这些约束存储在属性中。现在,当您想要隐藏/显示一个字段时,只需删除所有约束并换成另一组即可。

这也将解决 layoutIfNeeded 问题。

碰巧我有一个实际的例子来展示如何做到这一点。 (它是用 Swift 编写的,但我相信您可以在心理上进行补偿。)在我的示例代码中,我们有三个矩形;然后我移除一个矩形并缩小其余两个之间的间隙。两组约束的准备很繁琐但很初级:

    let c1 = NSLayoutConstraint.constraintsWithVisualFormat("H:|-(20)-[v(100)]", options: nil, metrics: nil, views: ["v":v1]) as [NSLayoutConstraint]
let c2 = NSLayoutConstraint.constraintsWithVisualFormat("H:|-(20)-[v(100)]", options: nil, metrics: nil, views: ["v":v2]) as [NSLayoutConstraint]
let c3 = NSLayoutConstraint.constraintsWithVisualFormat("H:|-(20)-[v(100)]", options: nil, metrics: nil, views: ["v":v3]) as [NSLayoutConstraint]
let c4 = NSLayoutConstraint.constraintsWithVisualFormat("V:|-(100)-[v(20)]", options: nil, metrics: nil, views: ["v":v1]) as [NSLayoutConstraint]
let c5with = NSLayoutConstraint.constraintsWithVisualFormat("V:[v1]-(20)-[v2(20)]-(20)-[v3(20)]", options: nil, metrics: nil, views: ["v1":v1, "v2":v2, "v3":v3]) as [NSLayoutConstraint]
let c5without = NSLayoutConstraint.constraintsWithVisualFormat("V:[v1]-(20)-[v3(20)]", options: nil, metrics: nil, views: ["v1":v1, "v3":v3]) as [NSLayoutConstraint]

self.constraintsWith.extend(c1)
self.constraintsWith.extend(c2)
self.constraintsWith.extend(c3)
self.constraintsWith.extend(c4)
self.constraintsWith.extend(c5with)

self.constraintsWithout.extend(c1)
self.constraintsWithout.extend(c3)
self.constraintsWithout.extend(c4)
self.constraintsWithout.extend(c5without)

NSLayoutConstraint.activateConstraints(self.constraintsWith)

但是当需要将中间 View 调入或调出界面时,返回就来了:这是微不足道的。只需删除或插入它,然后删除所有约束,现在插入适合情况的完整新约束集,我们已经准备好了:

@IBAction func doSwap(sender: AnyObject) {
if self.v2.superview != nil {
self.v2.removeFromSuperview()
NSLayoutConstraint.deactivateConstraints(self.constraintsWith)
NSLayoutConstraint.activateConstraints(self.constraintsWithout)
} else {
self.view.addSubview(v2)
NSLayoutConstraint.deactivateConstraints(self.constraintsWithout)
NSLayoutConstraint.activateConstraints(self.constraintsWith)
}
}

多组约束的准备是繁琐的,但可以通过规则来完成,即约束可以在循环中“机器生成”(写这个留给你做练习).换入和换出约束也是根据一个简单的规则,因为只有一组适合您希望显示/隐藏的特定字段集。因此,一旦设置完成,它将比您现在所做的更简单、更易于维护。

关于ios - 自动布局 - 可折叠 View (垂直),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26829799/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com