Getting an existing NSLayoutConstraint for the width?
Solution 1
Every contraint has an attribute [constraint firstAttribute]
It returns an enum NSLayoutAttribute
typedef NS_ENUM(NSInteger, NSLayoutAttribute) {
NSLayoutAttributeLeft = 1,
NSLayoutAttributeRight,
NSLayoutAttributeTop,
NSLayoutAttributeBottom,
NSLayoutAttributeLeading,
NSLayoutAttributeTrailing,
NSLayoutAttributeWidth,
NSLayoutAttributeHeight,
NSLayoutAttributeCenterX,
NSLayoutAttributeCenterY,
NSLayoutAttributeBaseline,
NSLayoutAttributeNotAnAttribute = 0
};
so you can check NSLayoutAttributeWidth for width.
Sample code:
NSArray constraints = [self constraints];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstAttribute = %d", NSLayoutAttributeWidth];
NSArray *filteredArray = [constraints filteredArrayUsingPredicate:predicate];
if(filteredArray.count == 0){
return nil;
}
NSLayoutConstraint *constraint = [constraints objectAtIndex:0];
Solution 2
Here is the swift 3 version tested on Xcode 8.2.1 and macOS 10.12.2.
The code shows how to get a button's width and height constraints, but you could filter whatever you want from NSLayoutAttribute
enum.
let cons = signInButton.constraints.filter {
$0.firstAttribute == NSLayoutAttribute.width || $0.firstAttribute == NSLayoutAttribute.height /// or other from `NSLayoutAttribute`
}
// do something with the constraints array, e.g.
NSLayoutConstraint.deactivate(cons)
Related videos on Youtube
IluTov
I'm a Swiss developer. Just a guy who enjoys programming.
Updated on September 16, 2022Comments
-
IluTov over 1 year
I'm trying to animate a control in Cocoa with auto layout.
Now, I can set
[[constraint animator] setConstant:newWidth];
, which works. But how can I get the right constraint?With
[self constraints]
you can get all the constraints, and in this case I can just selectconstraints[0]
, but the order of the constraints may vary.How can I be certain I always have the right constraint? The constraints are set in Interface Builder. I have seen that you can add a IBOutlet to it, but it doesn't seem necessary.
My solution
Thanks, it worked great. I wrote a little category.
NSView+NSLayoutConstraintFilter.h
#import <Cocoa/Cocoa.h> @interface NSView (NSLayoutConstraintFilter) - (NSLayoutConstraint *)constraintForAttribute:(NSLayoutAttribute)attribute; - (NSArray *)constaintsForAttribute:(NSLayoutAttribute)attribute; @end
NSView+NSLayoutConstraintFilter.m
#import "NSView+NSLayoutConstraintFilter.h" @implementation NSView (NSLayoutConstraintFilter) - (NSArray *)constaintsForAttribute:(NSLayoutAttribute)attribute { NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstAttribute = %d", attribute]; NSArray *filteredArray = [[self constraints] filteredArrayUsingPredicate:predicate]; return filteredArray; } - (NSLayoutConstraint *)constraintForAttribute:(NSLayoutAttribute)attribute { NSArray *constraints = [self constaintsForAttribute:attribute]; if (constraints.count) { return constraints[0]; } return nil; } @end
-
IluTov over 11 yearsGreat answer, worked like a charm, I wrote a category, take a look.
-
funmania over 7 yearsif(filteredArray.count == 0){ return nil; } NSLayoutConstraint *constraint = [constraints objectAtIndex:0]; this can be avoided by using NSLayoutConstraint *constraint = [constraints lastIndex];
-
Sentry.co almost 6 yearsWhen I use this, some constraints are missing