Reputation: 1702
I am having a button which has two different text in selected state and normal state, When I change state of button programatically button is not getting resized so text is not appearing properly, which is the best way to do this with autolayout?
I know one way setting outlet to UIButton's width constraint and change it manually but I am looking for better way
Upvotes: 9
Views: 8407
Reputation: 209
An alternate way for shrinking/expanding width of UIButton using autolayout is to add a width constraint and then change the priority of width constraint to less than Content Hugging Priority and Content Compression Resistance Priority.
In case we only want to expand the button based on their title, we can set the width constraint to the minimum value and the priority of width constraint to less than Content Compression Resistance Priority but more than Content Hugging Priority.
In the above cases we only need to
btn.setTitle("SomeTitle", for: .normal)
in the code and auto layout will take care of the rest.
Upvotes: 2
Reputation: 1930
Just by telling [button invalidateIntrinsicContentSize];
, it should do what you are expecting it to do.
Upvotes: 4
Reputation: 944
When you create constraints assign it to variables
@property (nonatomic, strong)NSLayoutConstraint *viewConstraintTop;
self.viewConstraintTop = [Your Constraint];//Initial state
On button tap check whether it is selected or not.Remove the constraints and reapply appropriate constraints.
[self.viewConstraintTop autoRemove];
self.viewConstraintTop = [Your Constraint];
Upvotes: 0
Reputation: 1109
You can use default button like this:
UIButton* button = [UIButton buttonWithType:UIButtonTypeSystem];
[button setTranslatesAutoresizingMaskIntoConstraints:NO];
[button setTitle:@"Normal" forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonTouched:) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:@"Selected" forState:UIControlStateSelected];
[self.view addSubview:button];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[button]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(button)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[button]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(button)]];
If you use custom button, then the easiest way I can think of is subclass UIButton and add your custom UILabel inside. Here is my short code of what I mean:
@interface CustomButton : UIButton
{
NSString* _normalTitle;
NSString* _selectedTitle;
}
@property UILabel* customLabel;
@end
@implementation CustomButton
@synthesize customLabel=_customLabel;
- (instancetype)init;
{
self = [super init];
if ( self ) {
[self setBackgroundColor:[UIColor greenColor]];
_customLabel = [UILabel new];
[_customLabel setTextColor:[UIColor whiteColor]];
[_customLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addSubview:_customLabel];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_customLabel]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_customLabel)]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_customLabel]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_customLabel)]];
}
return self;
}
- (void)setTitle:(NSString *)title forState:(UIControlState)state;
{
if ( state == UIControlStateNormal ) {
_normalTitle = title;
} else if ( state == UIControlStateSelected ) {
_selectedTitle = title;
}
[self setSelected:[self isSelected]];
}
- (void)setSelected:(BOOL)selected;
{
[super setSelected:selected];
if ( selected ) {
[_customLabel setText:_selectedTitle];
} else {
[_customLabel setText:_normalTitle];
}
}
@end
Upvotes: 0
Reputation: 1683
Try this
CGSize maxSize = CGSizeMake(btn.bounds.size.width, CGFLOAT_MAX);
CGSize textSize1 = [btn.titleLabel.text sizeWithFont:btn.titleLabel.font constrainedToSize:maxSize];
btn.frame=CGSizeMake(10,10,textSize1.width,30);
Upvotes: -2