Каков «правильный» способ сделать это?
Мое текущее решение просто проходит через подпредставления и все ограничения текущего родительского представления и проверяет, находится ли он между родительским и подпредставлением или между двумя подпредставлениями. Ограничения соответствия сохраняются и применяются к новому родительскому элементу:
Код: Выделить всё
var constraints = [NSLayoutConstraint]()
for subview in oldParent.subviews {
for constraint in oldParent.constraints {
if let newConstraint = moveConstraint(constraint, ofView: subview, fromView: oldParent, toView: newParent) {
let active = oldConstraint.isActive
oldParent.removeConstraint(constraint)
newConstraint.isActive = active
constraints.append(newConstraint)
}
}
newParent.addSubview(subview)
}
newParent.addConstraints(constraints)
func moveConstraint(_ constraint: NSLayoutConstraint, ofView view: UIView, fromView prevSuperview: UIView, toView newSuperview: UIView) -> NSLayoutConstraint? {
// Check prevSuperview + Layout Guides
var prevSuperviewIsFirstItem: Bool = constraint.firstItem === prevSuperview
if !prevSuperviewIsFirstItem {
for layoutGuid in prevSuperview.layoutGuides {
if constraint.firstItem === layoutGuid {
prevSuperviewIsFirstItem = true
break
}
}
}
var prevSuperviewIsSecondItem: Bool = constraint.secondItem === prevSuperview
if !prevSuperviewIsSecondItem {
for layoutGuid in prevSuperview.layoutGuides {
if constraint.secondItem === layoutGuid {
prevSuperviewIsSecondItem = true
break
}
}
}
// Move constraints between prevSuperview + View
var newConstraint: NSLayoutConstraint? = nil
if prevSuperviewIsFirstItem && constraint.secondItem === view {
newConstraint = NSLayoutConstraint(item: newSuperview, attribute: constraint.firstAttribute, relatedBy: constraint.relation, toItem: view, attribute: constraint.secondAttribute, multiplier: constraint.multiplier, constant: constraint.constant)
} else if prevSuperviewIsSecondItem && constraint.firstItem === view {
newConstraint = NSLayoutConstraint(item: view, attribute: constraint.firstAttribute, relatedBy: constraint.relation, toItem: newSuperview, attribute: constraint.secondAttribute, multiplier: constraint.multiplier, constant: constraint.constant)
}
if let newConstraint = newConstraint {
// handle newConstraint.isActive only after oldConstraint has
// been removed to avoid conflicts
newConstraint.identifier = constraint.identifier
newConstraint.priority = constraint.priority
newConstraint.shouldBeArchived = constraint.shouldBeArchived
return newConstraint
}
// Move constraints between view and other subview
if constraint.firstItem === view || constraint.secondItem === view {
return constraint
}
return nil
}
Итак: достаточно ли процесса копирования для правильной передачи подпредставлений и их ограничений? Или есть что-нибудь еще, что стоит рассмотреть? Или есть лучший способ?
РЕДАКТИРОВАТЬ: Контекст
Одним из вариантов использования может быть UICollectionViewCell с карточной раскладкой. Я последовал подсказке в другом ответе, чтобы добиться этого, добавив два подпредставления в contentView, которые действуют как оболочка и применяют тень и закругленные углы через свойства своего слоя. Цель состояла в том, чтобы создать подкласс UICollectionViewCell, который автоматически добавляет эти подпредставления-оболочки в пробуждениеFromNib() и перемещает все подпредставления contentView в это представление-оболочку.
Конечно, можно легко добавить эти оболочки в InterfaceBuilder, но при обработке большого количества разных ячеек в разных проектах хорошим решением будет общий подход, который обрабатывает это автоматически.>
Подробнее здесь: https://stackoverflow.com/questions/677 ... ints-intac