2

I've got an UITextField and I intend to programmatically add an UIButton to its right side when user touches the TextField and brings up the keyboard.

------------------------------
|--------------------------- |
||     textfield           | |
|--------------------------- |
------------------------------

when keyboard is been brought up:

------------------------------
|------------------          |
||     textfield  |  BUTTON  |
|------------------          |
------------------------------

I use Storyboard with AutoLayout for interface building and these elements are all well connected.

When I was trying to change the width of the UITextField, it didn't change at all, resulting the Button was put "inside" the textfield, like the screenshot shown below:

enter image description here

Here's my code:

// code to add the button
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    // dynamically add a "reply" button
    button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [self.replyViewBox addSubview:button];
    [button setTitle:@"Reply" forState:UIControlStateNormal];
    // change button size & position
    button.frame = CGRectMake(265.0, 10.0, 46.0, 30.0);
//    [button sizeToFit];
    // change replyText size
    CGRect frameRct = replyText.frame;
    frameRct.size.width = 248.0;
    replyText.frame = frameRct;

    [replyViewBox addSubview:button];

}

I've set the constraints via Storyboard, so is there anyway to let me change the width programmatically whilst maintaining the AutoLayout?

dumbfingers
  • 7,001
  • 5
  • 54
  • 80
  • since you're using autolayout, you must change the constraints, not the frames. here's a decent answer on the topic: http://stackoverflow.com/questions/15893022/setting-constraints-programatically – danh Jun 06 '14 at 23:06
  • @danh thx for the link. However, after I removed the constraints of TextField, I still cannot change its width. why? – dumbfingers Jun 06 '14 at 23:58
  • did you turn off auto layout? – danh Jun 07 '14 at 00:19

1 Answers1

1

I figured I'd give this a try for fun. Here's what I did:

1) Setup a parent view for the text field and the button, create constraints to place the text field's right edge a constant distance from it's parent's right edge. See the highlighted constraint here...

enter image description here

2) Create outlets for that constraint, the button and the text view:

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet UIButton *button;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textHorizontalTrailConstraint;

@end

3) Add a method that lets us inquire about the state of that constraint. Keyboard mode is on when that constraint has a non-zero constant.

- (BOOL)keyboardModeIsOn {
    return self.textHorizontalTrailConstraint.constant > 0;
}

4) Finally, a method to adjust the constraint and hide/unhide the button based on a bool. For fun, I added an optional bool to make the transition animated. Call this from your keyboard notification.

- (void)setKeyboardModeOn:(BOOL)on animated:(BOOL)animated {

    if (on == [self keyboardModeIsOn]) return;

    CGFloat htrailConst = (on)? 132 : 0;
    CGFloat alpha = (on)? 1.0 : 0;
    NSTimeInterval duration = (animated)? 0.5 : 0;

    [self.view layoutIfNeeded];
    [UIView animateWithDuration:duration animations:^{
        self.textHorizontalTrailConstraint.constant = htrailConst;
        self.button.alpha = alpha;
        [self.view layoutIfNeeded];
    }];
}

I tested this and it looked good.

danh
  • 62,181
  • 10
  • 95
  • 136