0

I have the following UI in storyboard.

enter image description here

The structure is as follows

  • Parent (UIView)
    • ThinBlock (UIView) (green one)
      • MusicStaffView (UIView) (musical notation, actually it's UILabel as loaded via through setting via custom class)

My goal is to place another UILabel which contains an individual musical note, or say a string with length 1 on top of specific location when the music plays.

The end result should be like this.

enter image description here

The setup as you see above is based on auto-layout. My understand is that if I need to manually place something individually on top, thus I don't need auto-layout enabled for that element.

So it seems that I need to find absolute position of individual character inside UILabel, create UILabel on the fly, then add it as a child of UIViewController's view. But I can't achieve that, it always placed on the top left no matter what.

Here is the code I use to get the target string, its absolute position, creation of UILabel and place it at that position on the fly.

// calculate prefix size
NSRange range = NSMakeRange(2, 1);
NSString *prefix = [self.leftPattern.scoreLabel.text substringToIndex:range.location];
NSDictionary *attributes = @{NSFontAttributeName: self.leftPattern.scoreLabel.font};
CGSize size = [prefix sizeWithAttributes:attributes];
CGPoint p = CGPointMake(size.width, 0);
NSLog(@"prefix width: %f",p.x);
NSLog(@"prefix height: %f",p.y);

// calculate size of target string
NSString *targetString = [self.leftPattern.scoreLabel.text substringWithRange:range];
CGSize targetSize = [targetString sizeWithAttributes:attributes];

NSLog(@"Old point %@", NSStringFromCGPoint(self.leftPattern.frame.origin));

// find absolute point to place our UILabel later
CGPoint localPoint = self.leftPattern.scoreLabel.frame.origin;
CGPoint absolutePoint = [self.leftPattern.scoreLabel convertPoint:localPoint toView:[self.view window]];

NSLog(@"Absolute point %@", NSStringFromCGPoint(absolutePoint));

// create UILabel to place at calculated absolute point
UILabel *newLabel = [[UILabel alloc]initWithFrame:CGRectMake(absolutePoint.x + p.x, absolutePoint.y - 10, targetSize.width, targetSize.height)];
NSLog(@"newLabel frame: %@", NSStringFromCGRect(newLabel.frame));
newLabel.text = targetString;
newLabel.font = self.leftPattern.scoreLabel.font;
newLabel.numberOfLines = 1;
newLabel.baselineAdjustment = UIBaselineAdjustmentAlignBaselines; // or UIBaselineAdjustmentAlignCenters, or UIBaselineAdjustmentNone
newLabel.adjustsFontSizeToFitWidth = NO;
newLabel.clipsToBounds = YES;
newLabel.backgroundColor = [UIColor clearColor];
newLabel.textColor = [UIColor redColor];
newLabel.textAlignment = NSTextAlignmentCenter;
[newLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:newLabel];
[self.view layoutIfNeeded];

What I got from NSLog() is as follows

prefix is |\
prefix width: 18.780000
prefix height: 0.000000
Old point {8, 0}
Absolute point {49.333333333333314, 101.33333333333331}
newLabel frame: {{68.113333333333316, 101.33333333333331}, {16, 43}}

Also, it gets worse and more difficult when I rotate the device into landscape, UILabel is aligned center thus introduce space in front in which I don't know how to calculate its space width too.

Solution or suggestion to solve this will be really appreciated!

haxpor
  • 2,431
  • 3
  • 27
  • 46
  • Did you check http://stackoverflow.com/questions/19417776/how-do-i-locate-the-cgrect-for-a-substring-of-text-in-a-uilabel ? – markov Feb 23 '16 at 13:09
  • Also i'd strongly recommend to use thie method for determining content size of label https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/index.html#//apple_ref/occ/instm/UIView/sizeThatFits: - just make a copy of your label, and set prefix text to it, then you'll get ecact offset as label's size. Then set the string that you want to coverup and size will define bounds. But i'm pretty sure there should be smarter way – markov Feb 23 '16 at 13:12
  • @markov Thank you for your chiming in. I took a look at the link you gave to me, and similar solution towards calculating rectangle position for target substring. It turns out it's not working for me despite it can calculating x position (seems correctly). The hard part I need to tackle is alignment and auto-layout of `UILabel` as part of the storyboard and how it set up. Thus I changed my approach to programmatically create `UILabel` via code and set up auto-layout (constraints). It works now. I might come back and add my solution as answer when it's stable. – haxpor Feb 26 '16 at 08:36

0 Answers0