14

I have an NSButton (Push Button) with some temporary title text built in Interface Builder / Xcode. Elsewhere, the title text inside the button is changed programmatically to a string of unknown length (actually, many times to many different lengths).

I'd like the button to automatically be resized (with a fixed right position--so it grows out to the left) to fit whatever length of string is programmatically inserted as button text. But I can't figure it out. Any suggestions? Thanks in advance!

Ryan
  • 474
  • 1
  • 3
  • 12

2 Answers2

16

If you can't use Auto Layout as suggested by @jtbandes (it's only available in Lion), then you can call [button sizeToFit] after setting its string value, which will make the button resize to fit its string. You would then need to adjust its frame based on the new width.

You can't do this automatically, but it would be easy to do in a subclass of NSButton.

@implementation RKSizeToFitButton
- (void)setStringValue:(NSString*)aString
{
    //get the current frame
    NSRect frame = [self frame];

    //button label
    [super setStringValue:aString];

    //resize to fit the new string
    [self sizeToFit];

    //calculate the difference between the two frame widths
    NSSize newSize = self.frame.size;
    CGFloat widthDelta = newSize.width - NSWidth(frame);
    //set the frame origin
    [self setFrameOrigin:NSMakePoint(NSMinX(self.frame) - widthDelta, NSMinY(self.frame))];
}
@end

This way you can just set your button's class to RKSizeToFitButton in Interface Builder and then calling setStringValue: on the button to change its label will "just work" with no additional code.

Rob Keniger
  • 45,830
  • 6
  • 101
  • 134
  • 2
    A more appropriate name for that method would be `setStringValueAndSizeToFit:`. – titaniumdecoy Aug 27 '11 at 05:49
  • 3
    Sure, but I was anticipating that the subclass would be called something like `RKSizeToFitButton` and that you wouldn't need to change your code at all for it to be a drop-in replacement for `NSButton`. The OP wants an automatic method to do this, after all. – Rob Keniger Aug 27 '11 at 06:24
8

Sure! Just use Auto Layout! :)

jtbandes
  • 115,675
  • 35
  • 233
  • 266
  • 1
    My fault; I should have been clearer. How to do this in 10.6 (and earlier)? – Ryan Aug 27 '11 at 04:56
  • @jtbandes How do you use autolayout to do that? – Just a coder Aug 14 '15 at 16:29
  • 1
    @Jai with autolayout enabled, the button will automatically try to be the right size. You just have to tell it where else to be — in OP's case, this would mean a constraint to align its right (trailing) edge with the superview. – jtbandes Aug 14 '15 at 16:31
  • hmm.. this is where i am stuck. If the button's right trailing edge is aligned to its superview, wont the button grow with the size of the superview. I was wondering how to get the button to be the size of its text. Sorry if im not understanding correctly – Just a coder Aug 14 '15 at 16:36
  • 1
    If the button's right edge is aligned to the superview, but the left edge remains unconstrained, it will fit the size of its text and stay right-aligned. – jtbandes Aug 14 '15 at 17:00
  • this link is dead – tofutim Dec 14 '17 at 21:44