1

I am loading a custom UIView from xib. The UILabel text may be long with multiline. There is a UIButton below the UILabel. The UIView is loading as a custom subclass from the xib.

I need to resize whole UIView depending on the amount of text. But it is keeping the frame height which is set in xib. How can resize the UIView elastically with the UILabel text, as well as keep all the autolayout constraint intact.

I need the UIView frame size since I am showing it as a drop down view from top with animation.

The UILabel is sized ok. But text goes beyond UIView. The UIView need to be resized and I need the updated frame size.

xib with constraints

Problem is showing here, enter image description here

These lines fixes the autoresize, but I am not sure that's the right way.

CGRect myFrame = self.frame;
self.frame = CGRectMake(myFrame.origin.x, myFrame.origin.y, 
    myFrame.size.width, 
    self.labelMessage.frame.size.height + self.btClose.frame.size.height + 16); // magic number!

The whole class,

    #import "MessageView.h"

@implementation MessageView

@synthesize systemMessage = _systemMessage; //otherwise setter is not called

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    [self updateUI];
}

- (void) updateUI {
//  DLog(@"%@", _systemMessage);
    if (_systemMessage.actionType == MessageActionDisappearing || _systemMessage.actionType == MessageActionDismissableRetry) {
        _btTryAgain.hidden = NO;
    } else {
        _btTryAgain.hidden = YES;
    }
    if (_systemMessage.actionType == MessageActionDismissable || _systemMessage.actionType == MessageActionDismissableRetry) {
        _btClose.hidden = NO;
    } else {
        _btClose.hidden = YES;
    }
    _borderView.backgroundColor = [self getBorderColor];
    _labelMessage.text = _systemMessage.message;
    CGRect myFrame = self.frame;
    self.frame = CGRectMake(myFrame.origin.x, myFrame.origin.y, myFrame.size.width,
                            self.labelMessage.frame.size.height + self.btClose.frame.size.height + 16); // magic number!
}

- (instancetype)initWithFrame:(CGRect)frame {
//  DLog(@"");
    self = [super initWithFrame:frame];
    [self xibSetup];
    return self;
}

- (void)awakeFromNib {
//  DLog(@"");
    [super awakeFromNib];
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
//  DLog(@"");
    self = [super initWithCoder:aDecoder];
    if (self.subviews.count == 0) {
        [self xibSetup];
    }
    return self;
}

- (void) xibSetup {
    UIView *v = [self loadViewFromXib];
    v.frame = self.bounds;
    [self addSubview:v];
}

- (UIView *)loadViewFromXib {
    UIView *v = [[[NSBundle mainBundle] loadNibNamed:@"MessageView" owner:self options:nil] firstObject];
    return v;
}

// isn't called!
- (CGSize)intrinsicContentSize
{
    DLog(@"%@", _labelMessage.text);
    CGSize size = self.labelMessage.intrinsicContentSize;
    size.height = size.height + _btTryAgain.frame.size.height + 16;
    size.width = self.intrinsicContentSize.width;
//  size.width  += 16;
    return size;
}

#pragma mark - Methods

/** Refresh the UI when message content is changed. */
- (void)setSystemMessage:(SystemMessage *)systemMessage {
    _systemMessage = systemMessage;
    [self updateUI];
}

- (UIColor *)getBorderColor {
    if (_systemMessage.messageType == MessageTypeWarning) {
        return [UIColor yellowColor];
    } else if (_systemMessage.messageType == MessageTypePositive) {
        return [UIColor greenColor];
    } else {
        return [UIColor blueColor];
    }
}

- (void) hideButtonWithId:(MessageViewButtonId)buttonId {
    if (buttonId == MessageViewButtonIdClose) {
        _btClose.hidden = YES;
    } else if (buttonId == MessageViewButtonIdTryAgain) {
        _btTryAgain. hidden = YES;
    }
}

- (NSString *)description {
    return [NSString stringWithFormat:@"%@, systemMessage: %@", [super description], _systemMessage];
}

#pragma mark - Actions

- (IBAction)didPressCloseButton:(id)sender {
    if ([_delegate respondsToSelector:@selector(messageView:didPressButtonWithId:)]) {
        [_delegate messageView:self didPressButtonWithId:MessageViewButtonIdClose];
    }
}

- (IBAction)didPressTryAgainButton:(id)sender {
    if ([_delegate respondsToSelector:@selector(messageView:didPressButtonWithId:)]) {
        [_delegate messageView:self didPressButtonWithId:MessageViewButtonIdTryAgain];
    }
}
Rishil Patel
  • 1,977
  • 3
  • 14
  • 30
karim
  • 15,408
  • 7
  • 58
  • 96
  • In case if you are giving fix height to your view then please remove that & only give button bottom constraint from the view. – Virender Jun 12 '17 at 09:34
  • I am not giving fixed height to view in the xib. But it has height in the size inspector and during runtime that size is fixed. – karim Jun 12 '17 at 10:48
  • You have used autolayout or autoresizing? – Aanchal Chaurasia Jun 12 '17 at 11:36
  • autolayout with constraints. – karim Jun 12 '17 at 14:05
  • First of all, you are using the wrong approach for this. You are adding message view inside message view (check xib setup method). Another thing I want to know how actually you are using this view in your application. – Virender Jun 13 '17 at 10:47
  • As in the screenshot, it will drop down from top. so it will be added as a subview on top of the current view, animated drop down. – karim Jun 13 '17 at 12:58
  • Check this . it will Help you https://stackoverflow.com/a/36862795/4910767 – Badal Shah Jun 13 '17 at 12:59
  • i saw that, but thats not loading from xib. in my case the parent view keeps it size as it was in xib. – karim Jun 13 '17 at 13:00

0 Answers0