translatesautoresizingmaskintoconstraints - iOS-¿Encontrar la restricción superior para una vista?
swift constraints programmatically (5)
En lugar de iterar a través de self.constraints
, debe iterar a través de self.superview.constraints
.
Las restricciones self.constraints
solo contienen restricciones relacionadas solo con la vista (por ejemplo, restricciones de altura y anchura).
Aquí hay un ejemplo de código de cómo podría verse esto:
- (void)awakeFromNib
{
[super awakeFromNib];
if (!self.topConstraint) {
[self findTopConstraint];
}
}
- (void)findTopConstraint
{
for (NSLayoutConstraint *constraint in self.superview.constraints) {
if ([self isTopConstraint:constraint]) {
self.topConstraint = constraint;
break;
}
}
}
- (BOOL)isTopConstraint:(NSLayoutConstraint *)constraint
{
return [self firstItemMatchesTopConstraint:constraint] ||
[self secondItemMatchesTopConstraint:constraint];
}
- (BOOL)firstItemMatchesTopConstraint:(NSLayoutConstraint *)constraint
{
return constraint.firstItem == self && constraint.firstAttribute == NSLayoutAttributeTop;
}
- (BOOL)secondItemMatchesTopConstraint:(NSLayoutConstraint *)constraint
{
return constraint.secondItem == self && constraint.secondAttribute == NSLayoutAttributeTop;
}
Estoy tratando de encontrar la restricción superior de la vista en el código. La restricción superior se agrega en el guión gráfico, y no quiero usar un IBOutlet.
El registro del valor del primer atributo en el siguiente código parece devolver siempre una restricción de tipo NSLayoutAttributeHeight. ¿Alguna idea de cómo podría encontrar de manera confiable una restricción superior de una vista en código?
NSLayoutConstraint *topConstraint;
for (NSLayoutConstraint *constraint in self.constraints) {
if (constraint.firstAttribute == NSLayoutAttributeTop) {
topConstraint = constraint;
break;
}
}
Escribo una pequeña extensión en Swift:
extension UIButton { var topConstraints: [NSLayoutConstraint]? { return self.constraints.filter( { ($0.firstItem as? UIButton == self && $0.firstAttribute == .top) || ($0.secondItem as? UIButton == self && $0.secondAttribute == .top) }) } }
Establecer el identificador en el inspector en Xcode. Para eso está. Lo que sea Si eso no es suficiente, crea el IBOutlet.
Por lo general, establezco un identifier
de una restricción requerida en el IB y luego lo encuentro en el código como este (Swift):
if let index = constraints.index(where: { $0.identifier == "checkmarkLeftMargin" }) {
checkmarkImageViewLeftMargin = constraints[index]
}
O por @Tim Vermeulen
checkmarkImageViewLeftMargin = constraints.first { $0.identifier == "checkmarkLeftMargin" }
Usando swift y la extensión UIView
extension UIView {
func findConstraint(layoutAttribute: NSLayoutAttribute) -> NSLayoutConstraint? {
if let constraints = superview?.constraints {
for constraint in constraints where itemMatch(constraint: constraint, layoutAttribute: layoutAttribute) {
return constraint
}
}
return nil
}
func itemMatch(constraint: NSLayoutConstraint, layoutAttribute: NSLayoutAttribute) -> Bool {
if let firstItem = constraint.firstItem as? UIView, let secondItem = constraint.secondItem as? UIView {
let firstItemMatch = firstItem == self && constraint.firstAttribute == layoutAttribute
let secondItemMatch = secondItem == self && constraint.secondAttribute == layoutAttribute
return firstItemMatch || secondItemMatch
}
return false
}
}