索引处的 Swift 方法 insertSubview 效果很好。但是如何重新定位所有子视图为插入的子视图腾出空间
Posted
技术标签:
【中文标题】索引处的 Swift 方法 insertSubview 效果很好。但是如何重新定位所有子视图为插入的子视图腾出空间【英文标题】:Swift method insertSubview at index works well. But how to reposition all subviews to make room for inserted one 【发布时间】:2017-06-22 05:05:24 【问题描述】:我以编程方式向特定视图添加了 4 个子视图(label1、label2、label3、label4)和约束(label2 顶部取决于 label1 底部等)。现在我使用 insertSubiewAtIndex 方法在索引 1(label5) 处插入另一个子视图。现在如何在约束是动态的情况下刷新 UI 意味着 label5 应该占据 label1 位置,而 label1 应该占据 label2 位置等等。
这是我的代码
override func viewDidLoad()
super.viewDidLoad()
let label1 = UILabel()
label1.translatesAutoresizingMaskIntoConstraints = false
label1.text = "label1"
label1.numberOfLines = 0
label1.tag = 1
self.containerView.addSubview(label1)
NSLayoutConstraint(item: label1, attribute: .top, relatedBy: .equal, toItem: self.containerView, attribute: .top, multiplier: 1.0, constant: 16.0).isActive = true
NSLayoutConstraint(item: label1, attribute: .leading, relatedBy: .equal, toItem: self.containerView, attribute: .leadingMargin, multiplier: 1.0, constant: 0.0).isActive = true
NSLayoutConstraint(item: label1, attribute: .trailing, relatedBy: .equal, toItem: self.containerView, attribute: .trailingMargin, multiplier: 1.0, constant: 0.0).isActive = true
let label2 = UILabel()
label2.translatesAutoresizingMaskIntoConstraints = false
label2.text = "label2"
label2.numberOfLines = 0
label2.tag = 1
self.containerView.addSubview(label2)
NSLayoutConstraint(item: label2, attribute: .top, relatedBy: .equal, toItem: self.containerView.subviews[self.containerView.subviews.count - 2], attribute: .top, multiplier: 1.0, constant: 16.0).isActive = true
NSLayoutConstraint(item: label2, attribute: .leading, relatedBy: .equal, toItem: self.containerView, attribute: .leadingMargin, multiplier: 1.0, constant: 0.0).isActive = true
NSLayoutConstraint(item: label2, attribute: .trailing, relatedBy: .equal, toItem: self.containerView, attribute: .trailingMargin, multiplier: 1.0, constant: 0.0).isActive = true
let label3 = UILabel()
label3.translatesAutoresizingMaskIntoConstraints = false
label3.text = "label3"
label3.numberOfLines = 0
label3.tag = 1
self.containerView.addSubview(label3)
NSLayoutConstraint(item: label3, attribute: .top, relatedBy: .equal, toItem: self.containerView.subviews[self.containerView.subviews.count - 2], attribute: .top, multiplier: 1.0, constant: 16.0).isActive = true
NSLayoutConstraint(item: label3, attribute: .leading, relatedBy: .equal, toItem: self.containerView, attribute: .leadingMargin, multiplier: 1.0, constant: 0.0).isActive = true
NSLayoutConstraint(item: label3, attribute: .trailing, relatedBy: .equal, toItem: self.containerView, attribute: .trailingMargin, multiplier: 1.0, constant: 0.0).isActive = true
let label4 = UILabel()
label4.translatesAutoresizingMaskIntoConstraints = false
label4.text = "label4"
label4.numberOfLines = 0
label4.tag = 1
self.containerView.addSubview(label4)
NSLayoutConstraint(item: label4, attribute: .top, relatedBy: .equal, toItem: self.containerView.subviews[self.containerView.subviews.count - 2], attribute: .top, multiplier: 1.0, constant: 16.0).isActive = true
NSLayoutConstraint(item: label4, attribute: .leading, relatedBy: .equal, toItem: self.containerView, attribute: .leadingMargin, multiplier: 1.0, constant: 0.0).isActive = true
NSLayoutConstraint(item: label4, attribute: .trailing, relatedBy: .equal, toItem: self.containerView, attribute: .trailingMargin, multiplier: 1.0, constant: 0.0).isActive = true
let label5 = UILabel()
label5.translatesAutoresizingMaskIntoConstraints = false
label5.text = "label5"
label5.numberOfLines = 0
label5.tag = 1
self.containerView.addSubview(label5)
NSLayoutConstraint(item: label5, attribute: .top, relatedBy: .equal, toItem: self.containerView.subviews[0], attribute: .top, multiplier: 1.0, constant: 16.0).isActive = true
NSLayoutConstraint(item: label5, attribute: .leading, relatedBy: .equal, toItem: self.containerView, attribute: .leadingMargin, multiplier: 1.0, constant: 0.0).isActive = true
NSLayoutConstraint(item: label5, attribute: .trailing, relatedBy: .equal, toItem: self.containerView, attribute: .trailingMargin, multiplier: 1.0, constant: 0.0).isActive = true
【问题讨论】:
【参考方案1】:override func viewDidLoad()
super.viewDidLoad()
containerView.backgroundColor = .white
let label1 = UILabel()
label1.translatesAutoresizingMaskIntoConstraints = false
label1.text = "label1"
label1.numberOfLines = 0
label1.tag = 1
self.containerView.addSubview(label1)
let label2 = UILabel()
label2.translatesAutoresizingMaskIntoConstraints = false
label2.text = "label2"
label2.numberOfLines = 0
label2.tag = 1
self.containerView.addSubview(label2)
let label3 = UILabel()
label3.translatesAutoresizingMaskIntoConstraints = false
label3.text = "label3"
label3.numberOfLines = 0
label3.tag = 1
self.containerView.addSubview(label3)
let label4 = UILabel()
label4.translatesAutoresizingMaskIntoConstraints = false
label4.text = "label4"
label4.numberOfLines = 0
label4.tag = 1
self.containerView.addSubview(label4)
let label5 = UILabel()
label5.translatesAutoresizingMaskIntoConstraints = false
label5.text = "label5"
label5.numberOfLines = 0
label5.tag = 1
self.containerView.addSubview(label5)
setConstraint(to: [label5, label1, label2, label3, label4])
private func setConstraint(to views: [UIView])
var iterator = views.makeIterator()
var prev: UIView = self.containerView
while let next = iterator.next()
NSLayoutConstraint(item: next, attribute: .top, relatedBy: .equal, toItem: prev, attribute: .top, multiplier: 1, constant: 16).isActive = true
NSLayoutConstraint(item: next, attribute: .leading, relatedBy: .equal, toItem: self.containerView, attribute: .leadingMargin, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: next, attribute: .trailing, relatedBy: .equal, toItem: self.containerView, attribute: .trailingMargin, multiplier: 1, constant: 0).isActive = true
prev = next
【讨论】:
我真正想要实现的是 - 我想在任何事件的父视图的特定索引处插入一个视图。父视图已经加载并且有许多带有约束的视图。可以说事件是在同一个父视图内切换。在点击开关时,我想在开关后在索引处插入一个视图,在关闭时添加的视图应该被删除。我的问题是所有约束都已经存在,并且有许多不同类型的视图。所有约束都是动态的,如 self.containerView.subviews[self.containerView.subviews.count - 2]。我是否必须删除约束并再次添加它们? 是的。 contentView.removeConstraints(contentView.constraints) 然后添加新的约束。以上是关于索引处的 Swift 方法 insertSubview 效果很好。但是如何重新定位所有子视图为插入的子视图腾出空间的主要内容,如果未能解决你的问题,请参考以下文章
代码转换 swift 2 --> 3 导致索引路径处的二进制运算符错误