Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to add a UIButton within a UILabel / UITextView?

Here is an interesting scenario. I have the following text sending from server:

I go to school by #option#

In iOS App, I have to convert it into:

I go to school by [UIButton]

The challenge is to measure the length of the previous text ("I go to school by "), in order to set the location (the origin) of the UIButton. The problem will be more problematic when the UILabel has multiple lines, and multiple appearance of UIButton, such as:

I go to school by #option#. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus fringilla, massa ut pharetra ultricies, elit nunc accumsan libero, ut elementum est justo sed lacus. Proin mi tellus, suscipit in magna a, auctor laoreet eros. #option# Quisque rhoncus ac mauris ac interdum. Etiam a odio augue. Mauris porttitor purus ac maximus faucibus. Suspendisse velit felis, varius lobortis turpis venenatis, tempor placerat magna. Integer in semper justo, ut pretium nunc. Aliquam laoreet vehicula finibus.#option#

Here are some of my solutions I can think of :

Method 1

NSString * testText = @"demo title";
CGSize stringSize = [testText sizeWithAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:17.0f]}];

This method can measure the size of a single line text, but for multiple lines text, the CGSize will be incorrect.

Method 2

NSTextStorage *textStorage = [[NSTextStorage alloc] initWithString:@"hello"];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
NSTextContainer *textContainer = [[NSTextContainer alloc] init];

[layoutManager addTextContainer:textContainer];
[textStorage addLayoutManager:layoutManager];

//Figure out the bounding rectangle
NSRect stringRect = [layoutManager boundingRectForGlyphRange:NSMakeRange(0, [layoutManager numberOfGlyphs]) inTextContainer:textContainer];

This is much more complex. (Still figuring out how to build the layout)

My question is: Any simpler method to achieve my goal?

like image 988
Raptor Avatar asked Nov 16 '15 04:11

Raptor


1 Answers

Using UITextView you can solve your problem just add below method

-(void)addButtons{
    NSRange searchRange = NSMakeRange(0, [self.localTextView.text length]);
    NSLog(@"%d", self.localTextView.text.length);
    while(searchRange.location != NSNotFound){
        searchRange = [self.localTextView.text rangeOfString:@"#option#" options:NSCaseInsensitiveSearch range:searchRange];
        if (searchRange.location != NSNotFound)
        {
            NSLog(@"%d", searchRange.location);
            UITextPosition *beginning = self.localTextView.beginningOfDocument;
            UITextPosition *start = [self.localTextView positionFromPosition:beginning offset:searchRange.location];
            UITextPosition *end = [self.localTextView positionFromPosition:start offset:searchRange.length];
            UITextRange *range = [self.localTextView textRangeFromPosition:start toPosition:end];
            CGRect result1 = [self.localTextView firstRectForRange:range];
            NSLog(@"%f, %f", result1.origin.x, result1.origin.y);

            UIButton* btn = [UIButton buttonWithType:UIButtonTypeCustom];
            [btn addTarget:self action:@selector(doAction:) forControlEvents:UIControlEventTouchUpInside];
            [btn setTitle:@"Click" forState:UIControlStateNormal];
            [btn setBackgroundColor:[UIColor blackColor]];
            [btn setFrame:result1];
            [self.localTextView addSubview:btn];

            searchRange = NSMakeRange(searchRange.location + searchRange.length, self.localTextView.text.length - (searchRange.location + searchRange.length));
        }
    }
}

localTextView is IBOutlet taken from storyboard, finally just call [self addButtons]; in your viewDidAppear

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    [self addButtons];
}

set the button appearance and action method as you wish i just made a black background with a title. Here is the Output which i got

enter image description here

like image 68
harsha yarabarla Avatar answered Oct 05 '22 13:10

harsha yarabarla