How can I create a UIButton that supports dynamic multi-line text with an image background?

I am trying to create a user interface element in iOS that expands or compresses to fit dynamic, often multi-line text. I need to put an image under the text, which is very similar to a message bubble. However, I only need one of them in my entire user interface, so looking at a table seems unnecessary - if that is not reasonable.

I tried using UILabel for this purpose, but there seems to be very limited support for background images. I can only get it in order to draw an image that I don’t want.

It seems that a UIButton - the most simple design, which should reasonably do what I ask, but I can not make it work. Here's a distilled form of code in another empty application with one view.

- (void)viewDidLoad {
  [super viewDidLoad];

  NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
  UIImage *image = [[UIImage imageNamed:@"speak_bubble_solid"] resizableImageWithCapInsets:UIEdgeInsetsMake(16, 24, 30, 12)];

  UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  [button setBackgroundImage:image forState:UIControlStateNormal];
  [button setTitle:text forState:UIControlStateNormal];
  button.titleLabel.textColor = [UIColor whiteColor];
  button.titleLabel.textAlignment = NSTextAlignmentLeft;
  button.titleLabel.numberOfLines = 0;
  button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
  button.contentEdgeInsets = UIEdgeInsetsMake(16, 10, 30, 10);
  button.translatesAutoresizingMaskIntoConstraints = NO;

  [self.view addSubview:button];
  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-[button]-|"
                                                                    options:NSLayoutFormatAlignAllTop
                                                                    metrics:0
                                                                      views:NSDictionaryOfVariableBindings(button)]];

}

Here's what it looks like when I launch the application:

screenshot

Obviously, I'm looking for a button for an extension to contain its contents. Thus, even the initial render is erroneous, but I also need it to be correctly detected when I change the text dynamically later.

How can I create this? I need to see the answer in the code, since I'm still very new to iOS development.

0
source share
2 answers

. : .

  • . , .

  • .

  • , , .

  • , , .

  • "", , .

, , , :

enter image description here

enter image description here

, . / , . , , , , , , ; , (iv) (lab):

override func viewDidLayoutSubviews() {
    iv.bounds.size.height = lab.bounds.size.height + 60
    iv.frame.origin.y = lab.frame.origin.y - 20
}

: ; , github: https://github.com/mattneub/MessageBubble

+3

, . , , , . UIView RDLabelView, . text, , .

#import "RDLabelView.h"

@interface RDLabelView ()
@property (strong,nonatomic) UILabel *label;
@property (strong,nonatomic) CAShapeLayer *bubble;
@end

@implementation RDLabelView

-(void)awakeFromNib {

    self.tapper = [UITapGestureRecognizer new];
    [self addGestureRecognizer:self.tapper];
    self.bubble = [CAShapeLayer layer];
    self.bubble.fillColor = [UIColor colorWithRed:.5 green:1 blue:1 alpha:1].CGColor;
    [self.layer addSublayer:self.bubble];
    self.label = [UILabel new];
    self.label.numberOfLines = 0;
    self.label.translatesAutoresizingMaskIntoConstraints = NO;
    [self addSubview:self.label];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[label]-10-|" options:0 metrics:nil views:@{@"label":self.label}]];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[label]-10-|" options:0 metrics:nil views:@{@"label":self.label}]];
}

-(void)setColor:(UIColor *)color { // The color property is declared in the .h file to allow color changes to the bubble
    _color = color;
    self.bubble.fillColor = _color.CGColor;
}

-(void)setText:(NSString *)text { // The text property is declared in the .h file to allow you to set the text as you would for a UILabel
    _text = text;
    self.label.text = text;
}

-(UIBezierPath *)appendShapeToRoundedRect:(UIBezierPath *) shape {
    CGPoint lowerLeftCorner = CGPointMake(0, shape.bounds.size.height);
    CGPoint pointToStart = CGPointMake(lowerLeftCorner.x + 30, lowerLeftCorner.y);
    UIBezierPath * arrow = [UIBezierPath bezierPath];
    [arrow moveToPoint:pointToStart];
    [arrow addLineToPoint:CGPointMake(pointToStart.x, pointToStart.y + 20)];
    [arrow addLineToPoint:CGPointMake(pointToStart.x + 10, pointToStart.y)];
    [shape appendPath:arrow];
    return shape;
}


-(void)layoutSubviews {
    [super layoutSubviews];
    UIBezierPath *shape = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:16];
    shape = [self appendShapeToRoundedRect:shape];
    self.bubble.path = shape.CGPath;
}
+1

Source: https://habr.com/ru/post/1626059/


All Articles