ios - 模仿马车线最好的方法是什么?

标签 ios swift cocoa-touch

我正在创建一个应用程序,用户可以在其中使用自定义键盘输入 4 个标签。我需要在最后一行 like here 之后模仿文本字段中的常用行.因为我的 textLabels 有圆角半径,所以我无法使用边框或阴影来解决问题。

@IBOutlet weak var xField: InsetLabel!
@IBOutlet weak var yField: InsetLabel!
@IBOutlet weak var wField: InsetLabel!
@IBOutlet weak var hField: InsetLabel!
var textfields: [InsetLabel] = []

@IBOutlet weak var xSuppView: UIView!
@IBOutlet weak var ySuppView: UIView!
@IBOutlet weak var hSuppView: UIView!
@IBOutlet weak var wSuppView: UIView!
var suppViews: [UIView] = []

override func viewDidLoad(){
     super.viewDidLoad()
     textfields = [xField, yField, wField, hField]
     suppViews = [xSuppView, ySuppView, wSuppView, hSuppView]

for (index, view) in textfields.enumerated() {

        let carriageView = UIView()
        let width: CGFloat = 2.0
        let x = view.frame.maxX + width
        let y = view.frame.minY
        let height = view.frame.height
        carriageView.frame = CGRect(x: x, y: y, width: 2, height: height)
        carriageView.layer.masksToBounds = true
        carriageView.layer.cornerRadius = 2
        carriageView.backgroundColor = ColorConstants.carriageColor
        carriages.append(carriageView)
        suppViews[index].addSubview(carriageView)
        suppViews[index].translatesAutoresizingMaskIntoConstraints = false

        let trailingConstraint = NSLayoutConstraint(item: carriageView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0)
        let heightConstraint = NSLayoutConstraint(item: carriageView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: height)
        let topSpaceConstraint = NSLayoutConstraint(item: carriageView, attribute: .centerY, relatedBy: .equal, toItem: suppViews[index], attribute: .centerY, multiplier: 1, constant: 0)
carriageView.addConstraints([trailingConstraint, heightConstraint, topSpaceConstraint])


        view.sizeToFit()

        view.layer.masksToBounds = true
        view.layer.cornerRadius = 4
    }
}

这就是为什么我创建了相同的 View 但角半径为 0,并且我已经设法将线放在我需要的位置,但它们的位置是固定的。

 let carriageView = UIView()
        let width: CGFloat = 2.0
        let x = view.frame.maxX + width
        let y = view.frame.minY
        let height = view.frame.height
        carriageView.frame = CGRect(x: x, y: y, width: 2, height: height)
        carriageView.layer.masksToBounds = true
        carriageView.layer.cornerRadius = 2
        carriageView.backgroundColor = ColorConstants.carriageColor
        carriages.append(carriageView)
        suppViews[index].addSubview(carriageView)
}

因此,我以编程方式向该行添加了约束,以使其随我的 textLabel 的宽度移动,但编译器不喜欢它。似乎此约束与 Storyboard约束冲突。基本上,我需要通过它们的共同点来约束一个父 View 的 2 个 subview 。我究竟做错了什么?这是错误的部分

    When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView(UIConstraintBasedLayout) _viewHierarchyUnpreparedForConstraint:] to debug.

顺便说一句,实例化 Storyboard 中几乎所有的 View 是否是一种糟糕的编程风格?我应该学习如何以编程方式创建所有内容吗?

编辑

错误出现在我向 View 添加约束的行中。

carriageView.addConstraints([trailingConstraint, heightConstraint, topSpaceConstraint])

可以吗,我有一个在 Storyboard中创建的 subview 和一个在 viewDidLoad 中创建的 subview ,我试图在代码中约束它们? This is how the tree of the superview looks

编辑

我发现,以编程方式创建此 View 是个坏主意,所以我只是使用界面构建器向每个标签添加了一个 View ,而不是仅在前导空间上添加了 1 个约束。对我来说更容易,而不是程序化方法

最佳答案

有问题的部分是了解何时使用自动布局以及何时使用自动调整大小(手动框架和自动调整大小掩码)。

当您在代码中创建 View 时,其translatesAutoresizingMaskIntoConstraints 默认为true,而在使用自动布局在 storyboard/xib 中创建时,则为false.

因此:

不需要设置

suppViews[index].translatesAutoresizingMaskIntoConstraints = false

您必须选择是否使用手动框架:

carriageView.frame = CGRect(x: x, y: y, width: 2, height: height)

或约束

let trailingConstraint = NSLayoutConstraint(item: carriageView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0)
let heightConstraint = NSLayoutConstraint(item: carriageView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: height)
let topSpaceConstraint = NSLayoutConstraint(item: carriageView, attribute: .centerY, relatedBy: .equal, toItem: suppViews[index], attribute: .centerY, multiplier: 1, constant: 0)
carriageView.addConstraints([trailingConstraint, heightConstraint, topSpaceConstraint])

如果你想设置一个手动框架,那么不要为 carriageView 设置任何约束,你可能应该设置自动调整掩码:

carriageView.autoresizingMask = [.flexibleHeight, .flexibleLeftMargin]

如果您选择使用自动布局,则必须

carriageView.translatesAutoresizingMaskIntoConstraints = false

并且您必须向父 View 添加一些约束:

carriageView.addConstraints([heightConstraint])
suppViews[index].addConstraints([trailingConstraint, topSpaceConstraint])

或使用效用函数:

NSLayoutConstraint.activate([trailingConstraint, heightConstraint, topSpaceConstraint])

请注意,在 IB 中创建约束要容易得多,但您仍然应该了解代码中发生的事情。

关于ios - 模仿马车线最好的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41914387/

相关文章:

ios - 如果我为表格 View 单元格设置动画,表格 View 滚动不会停止

ios - iPhone X Swift 底部有空白

ios - 是否可以合并/交叉两个 UIView 而不是让它们重叠?

iphone - 当方向改变时如何将ScrollView定位在键盘后面

ios - 将字符串转换为 CLLocation 坐标

ios - Xcode,模拟器 : App crashes on launch on older version of Simulator

ios - 如何从另一个变量构建一个变量

ios - NSCoding 意外发现 nil

ios - 如何在 ios swift5 中编码 firebase 时间戳?

iphone - UITextField 内阴影