Abhishek
Abhishek

Reputation: 1702

UIButton dynamic width using autolayout

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

Answers (5)

Hassaan Fayyaz
Hassaan Fayyaz

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.

Attached is a screenshotenter image description here

Upvotes: 2

Srikanth
Srikanth

Reputation: 1930

Just by telling [button invalidateIntrinsicContentSize];, it should do what you are expecting it to do.

Upvotes: 4

yoshiiiiiiii
yoshiiiiiiii

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

Peter
Peter

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

bhavik
bhavik

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

Related Questions