什么是模仿运输线的最佳方式?

时间:2017-01-28 20:16:05

标签: 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
    }
}

这就是为什么我创建了相同的视图,但是角半径为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的宽度移动,但编译器并不喜欢它。似乎这种约束与故事板约束冲突。基本上,我需要通过共同的方面约束一个超级视图的2个子视图。我究竟做错了什么?这是错误的一部分

    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.

顺便说一下,在我的故事板中实例化几乎所有视图都是一种糟糕的编程风格?我应该学习如何以编程方式创建所有内容吗?

修改

错误出现在该行中,我在其中向视图添加约束。

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

没关系,我有一个子视图,在storyboard中创建,以及在viewDidLoad中创建的子视图,我试图在代码中约束它们? This is how the tree of the superview looks

修改

我想通过编程方式创建这个视图是一个坏主意,所以我只是在界面构建器中为每个标签添加了一个视图,而不是在前导空间上添加了一个约束。对我来说更容易,而不是程序化方法

1 个答案:

答案 0 :(得分:0)

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

当您在代码中创建视图时,默认情况下其translatesAutoresizingMaskIntoConstraintstrue,并且当在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

你必须在superview中添加一些约束:

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

或使用效用函数:

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

请注意,在IB中创建约束要容易得多,但您仍应了解代码中的内容。