Forum Xamarin.iOS

Announcement:

The Xamarin Forums have officially moved to the new Microsoft Q&A experience. Microsoft Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

To create new threads and ask questions head over to Microsoft Q&A for .NET and get involved today.

How to detect that the text created a new line in a lable

Let's Imagine that I have a label and this label has a text with X characters.
Always that text not fit into label the text created a new line.

How can I detect that it happened ?

I tried this way:

internal int ContarQuebrasLinhas()
{
    return LBLNomeEvento.Text.Split('\n').Length;
}

However it only works if I did it myself this way:

lable.Text = "aaaaa\naaaaa";

let show you the label with background blue:

Like you can see when it doesn't fit into line text goes to down.

Best Answer

  • LandLuLandLu Member, Xamarin Team Xamurai
    Accepted Answer

    @amadeuantunes We can calculate each text's position, then compare their Y's value. If its value is different from the last one's, it means the label has started a new line.
    Override your own label, and use the code below to calculate the position:

    public partial class MyLabel : UILabel
    {
        public MyLabel (IntPtr handle) : base (handle)
        {
        }
    
        public CGRect boundingRectForCharacterRange(NSRange range)
        {
            NSTextStorage textStorage = new NSTextStorage();
            textStorage.Append(AttributedText);
            NSLayoutManager layoutManager = new NSLayoutManager();
            textStorage.AddLayoutManager(layoutManager);
            NSTextContainer textContainer = new NSTextContainer(Bounds.Size);
            textContainer.LineFragmentPadding = 0;
            layoutManager.AddTextContainer(textContainer);
    
            NSRange glyphRange = new NSRange();
            layoutManager.CharacterRangeForGlyphRange(range, ref glyphRange);
    
            return layoutManager.BoundingRectForGlyphRange(glyphRange, textContainer);
        }
    }
    

    From the code above, we use NSAttributedString to calculate these positions. So please pay attention that we need to set the label's AttributedText, also this NSAttributedString should be pointed out a UIFont property. Or we won't get the correct Frame. Here is my usage of this custom Label:

    //Set the custom label instance's AttributedText 
    MySingleLabel.AttributedText = new NSAttributedString("Something you want to show...", UIFont.SystemFontOfSize(17));
    
    CGRect lastPosition = new CGRect();
    List<NSAttributedString> startStrings = new List<NSAttributedString>();
    List<NSRange> startRanges = new List<NSRange>();
    for (int i=0; i<MySingleLabel.AttributedText.Length; i++)
    {
        CGRect rect = MySingleLabel.boundingRectForCharacterRange(new NSRange(i, 1));
        if (rect.Y != lastPosition.Y)
        {
            startStrings.Add(MySingleLabel.AttributedText.Substring(i, 1));
            startRanges.Add(new NSRange(i, 1));
        }
        lastPosition = rect;
    }
    

    startStrings stores the new lines's first character and startRanges stores all the new lines' start position.

Answers

  • LandLuLandLu Member, Xamarin Team Xamurai
    Accepted Answer

    @amadeuantunes We can calculate each text's position, then compare their Y's value. If its value is different from the last one's, it means the label has started a new line.
    Override your own label, and use the code below to calculate the position:

    public partial class MyLabel : UILabel
    {
        public MyLabel (IntPtr handle) : base (handle)
        {
        }
    
        public CGRect boundingRectForCharacterRange(NSRange range)
        {
            NSTextStorage textStorage = new NSTextStorage();
            textStorage.Append(AttributedText);
            NSLayoutManager layoutManager = new NSLayoutManager();
            textStorage.AddLayoutManager(layoutManager);
            NSTextContainer textContainer = new NSTextContainer(Bounds.Size);
            textContainer.LineFragmentPadding = 0;
            layoutManager.AddTextContainer(textContainer);
    
            NSRange glyphRange = new NSRange();
            layoutManager.CharacterRangeForGlyphRange(range, ref glyphRange);
    
            return layoutManager.BoundingRectForGlyphRange(glyphRange, textContainer);
        }
    }
    

    From the code above, we use NSAttributedString to calculate these positions. So please pay attention that we need to set the label's AttributedText, also this NSAttributedString should be pointed out a UIFont property. Or we won't get the correct Frame. Here is my usage of this custom Label:

    //Set the custom label instance's AttributedText 
    MySingleLabel.AttributedText = new NSAttributedString("Something you want to show...", UIFont.SystemFontOfSize(17));
    
    CGRect lastPosition = new CGRect();
    List<NSAttributedString> startStrings = new List<NSAttributedString>();
    List<NSRange> startRanges = new List<NSRange>();
    for (int i=0; i<MySingleLabel.AttributedText.Length; i++)
    {
        CGRect rect = MySingleLabel.boundingRectForCharacterRange(new NSRange(i, 1));
        if (rect.Y != lastPosition.Y)
        {
            startStrings.Add(MySingleLabel.AttributedText.Substring(i, 1));
            startRanges.Add(new NSRange(i, 1));
        }
        lastPosition = rect;
    }
    

    startStrings stores the new lines's first character and startRanges stores all the new lines' start position.

  • @LandLu it solved my problem thank you :)

Sign In or Register to comment.