user2565076
user2565076

Reputation: 77

Different width of the first line of the label iOS

I want to set the width of the first line of the label, to be smaller then the rest of the lines.

Like in the image - because of the date, it needs to be shorter. How can i do that?

Label with different first line width

Upvotes: 1

Views: 409

Answers (3)

Daniel Rinser
Daniel Rinser

Reputation: 8855

Assuming that you are targeting iOS7 or above, you can use the very convenient exclusion paths introduced with TextKit.

The NSTextContainer (accessible via the UITextView's textContainer property) provides an exclusionPaths property, which you can set to one or multiple UIBezierPaths representing the areas where text should flow around.

So, first you need to determine the rect in which you don't want to see any text (in your case, the time label + some padding, I guess). Note, that we need this rect in the coordinate system of the text view, so you might need to convert, for example:

CGRect timeLabelRect = [self.timeLabel convertRect:self.timeLabel.bounds toView:self.textView];
CGRect exclusionRect = CGRectInset(timeLabelRect, -10.f, -10.f); // add padding

Once we have that rect, it's just a matter of creating a path from it and setting it as the (only) exclusion path on the text view's text container:

UIBezierPath *path = [UIBezierPath bezierPathWithRect:exclusionRect];
self.textView.textContainer.exclusionPaths = @[path];

That's it!


Full example in Swift (because I copy/pasted it from a Playground):

// just a plain container view
var container = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 400))

// the text view
var textView = UITextView(frame: CGRect(x: 0, y: 100, width: 300, height: 300))
textView.text = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
container.addSubview(textView)

// a box (representing the time label in your case)
var blueBox = UIView(frame: CGRect(x: 250, y: 100, width: 50, height: 50))
blueBox.backgroundColor = .blueColor()
container.addSubview(blueBox)

At this point it looks like this:

before exclusion path

Now, let's simply add the exclusion path:

// configure exclusion path
let blueBoxRect = textView.convertRect(blueBox.bounds, fromView: blueBox)
let path = UIBezierPath(rect: blueBoxRect)
textView.textContainer.exclusionPaths = [path]

After adding the exclusion path, it looks like this:

after adding exclusion path

Upvotes: 3

Shebin Koshy
Shebin Koshy

Reputation: 1192

UILabel *labelDate = [[UILabel alloc]initWithFrame:CGRectMake(_textView1.frame.size.width-100, 0, 100, 30)];
labelDate.text = @"4:32 PM";
[_textView1 addSubview:labelDate];//just added a sample label

Code for where to put '\n' in first line

int firstlineWidth = _textView1.frame.size.width - labelDate.frame.size.width;
int eachCharWidthSum = 0;
NSMutableString *stringToShow = [[NSMutableString alloc]init];
stringToShow = [_textView1.text mutableCopy];
int previousSpaceCharIndex = 0;
int initialPreviousSpaceCharIndex = 0;
BOOL isNeedNextSpace = NO;
for (int i =0; i<_textView1.text.length; i++)
{
   unichar charf = [_textView1.text characterAtIndex:i];
    NSString *eachString = [NSString stringWithFormat:@"%c",charf];
    CGSize stringSize = [eachString sizeWithFont:_textView1.font];
    eachCharWidthSum += stringSize.width;
    if ([eachString isEqualToString:@" "])
    {
        previousSpaceCharIndex = i;
    }
    int differance =  i - previousSpaceCharIndex;
    if (firstlineWidth<eachCharWidthSum&&differance<10)
    {
        [stringToShow insertString:@"\n" atIndex:previousSpaceCharIndex];
        break;
    }
    else if (firstlineWidth<eachCharWidthSum&&differance>10&&isNeedNextSpace==NO)
    {
        isNeedNextSpace = YES;
        initialPreviousSpaceCharIndex = previousSpaceCharIndex;
    }
    else if (isNeedNextSpace&&initialPreviousSpaceCharIndex!=previousSpaceCharIndex)
    {
        /*
         found new space char
         */
        [stringToShow insertString:@"\n" atIndex:previousSpaceCharIndex];
        break;
    }
}
_textView1.text = stringToShow;

Upvotes: 1

Saheb Roy
Saheb Roy

Reputation: 5967

You have to use NSAttributedString for this purpose.

NSMutableAttributedString *myAttributedString = [[NSMutableAttributedString alloc] initWithString:@"This is my text bla bla bla bla bla!"];
[myAttributedString addAttribute:NSFontAttributeName
          value:[UIFont systemFontOfSize:14.0]
          range:NSMakeRange(startingpoint, length)];

This is a way in which u can specify the first line (static in length suppsose 20 charecters) to be in a font size of 14, and the rest of the as a bigger size.

Emmulate the similar function to create another attributedString for the rest of the string. Now merge those 2 attributedString to form a single attributedString. and write myLabel.attributedText = myTotalAttributedText

OR you can go through this Core Text tutorial, by which you can get this same desired effect Link

Upvotes: 0

Related Questions