Adjusting Font Size to fit View Rectangle


Dave
 

Hi All,

Is there a Cocoa method I can use that will return the best fitting Font Size for a given String and Font?

I seem to remember using a method that does it but can’t seem to find it any more…..

All the Best
Dave


Sandor Szatmari
 

Multiline, or single line?

Sandor

On Sep 19, 2018, at 14:29, Dave <dave@...> wrote:

Hi All,

Is there a Cocoa method I can use that will return the best fitting Font Size for a given String and Font?

I seem to remember using a method that does it but can’t seem to find it any more…..

All the Best
Dave




Alex Zavatone
 

There are two that I am aware of. sizeToFit and sizeThatFits.

On Sep 19, 2018, at 1:29 PM, Dave <dave@...> wrote:

Hi All,

Is there a Cocoa method I can use that will return the best fitting Font Size for a given String and Font?

I seem to remember using a method that does it but can’t seem to find it any more…..

All the Best
Dave




Dave
 

Hi,

Those two methods alter the frame size, I want to keep the same Frame Size but reduce the Font Size of the Content until it fit into the Displayable Area. I’m 99% sure there is a method to do it but maybe its iOS only?

All the Best
Dave

On 20 Sep 2018, at 02:02, Alex Zavatone via Groups.Io <zav@...> wrote:

There are two that I am aware of. sizeToFit and sizeThatFits.
On Sep 19, 2018, at 1:29 PM, Dave <dave@...> wrote:

Hi All,

Is there a Cocoa method I can use that will return the best fitting Font Size for a given String and Font?

I seem to remember using a method that does it but can’t seem to find it any more…..

All the Best
Dave





Dave
 

Hi,

Couldn’t find it so wrote my own:

(NSInteger) adjustFontSize:(NSInteger) theFontSize toFitWidth:(NSInteger) theWidth
{
NSInteger myFontSize;
NSFont* myFont;
NSSize myContentSize;

myFontSize = theFontSize;
while (YES)
{
myFont = [NSFont fontWithName:self.font.fontName size:myFontSize];
[self setFont:myFont];

myContentSize = [self.attributedStringValue size];
if (myContentSize.width < theWidth)
break;

myFontSize--;
if (myFontSize <= 0)
break;
}

return myFontSize;
}

This is on an NSTextField subclass and works a treat!

All the Best
Dave

On 20 Sep 2018, at 11:51, Dave <dave@...> wrote:

Hi,

Those two methods alter the frame size, I want to keep the same Frame Size but reduce the Font Size of the Content until it fit into the Displayable Area. I’m 99% sure there is a method to do it but maybe its iOS only?

All the Best
Dave

On 20 Sep 2018, at 02:02, Alex Zavatone via Groups.Io <zav@...> wrote:

There are two that I am aware of. sizeToFit and sizeThatFits.
On Sep 19, 2018, at 1:29 PM, Dave <dave@...> wrote:

Hi All,

Is there a Cocoa method I can use that will return the best fitting Font Size for a given String and Font?

I seem to remember using a method that does it but can’t seem to find it any more…..

All the Best
Dave






Sandor Szatmari
 

This was for macOS… not sure how to go about it on iOS. I’d guess it would work, but there may be an easier method. I don’t know though.

I have used this method to dynamically size formatted multiline text (text that includes line breaks) to find the maximum font size for a fixed container size. Granted there may be an easier solution that I am not aware of, but I am also counting the number of line of text being laid out, so this solution works for me.

1. Get text
2. Setup your mutable paragraph style, set properties, justification, wrapping… etc.
3. Create a layout manager… set properties, hyphenation, etc. Important, set the layout mgr’s delegate (I used self for simplicity). You will receive callbacks about the layout process via delegation.
3a. Define delegate method -layoutManager:didCompleteLayoutForTextContainer:atEnd: (you will receive these callbacks where you can flag ‘clipping’ I.e. text too big) set a flag here indicating clipping has occurred. I used an iVar.
4. Create a mutable attributes dict, this contains the para style keyed on NSParagraphStyleAttributeName. (You will add/update the font later stored in this dict with different sizes later)
5. Create a text storage object with text and para style
6. Now loop… do while (notClipped && other things you care about)
Loop Body
a. Adjust font size
b. Create new NSFont object with new size. Set font in attributes dict keyed on NSFontAttributeName
c. Adjust paragraph style as needed/desired (optional)
d. Reapply (Set) the updated attributes dict for the entire range of text in your text storage object -setAtteibutes:range:
e. Ask the layout manager/text storage to layout the text. If the text is too big the container parameter in your callback will be nil indicating that ‘clipping’ occurred. Use nil container to flag clipping thus communicating with your loop.

Rinse, repeat… till desired font size reached


The text generated using this approach is displayed in widgets that are part of a complex visual graph of objects all of which are the same size and which contain dynamic multiline text. I have additional logic that counts the number of lines to ensure that there are always three lines. Each line contains a different property of the object being represented. IP, hostname, etc… Think graphical displays of networks and such, with text inside the network components.

Sandor

On Sep 20, 2018, at 05:51, Dave <dave@...> wrote:

Hi,

Those two methods alter the frame size, I want to keep the same Frame Size but reduce the Font Size of the Content until it fit into the Displayable Area. I’m 99% sure there is a method to do it but maybe its iOS only?

All the Best
Dave

On 20 Sep 2018, at 02:02, Alex Zavatone via Groups.Io <zav@...> wrote:

There are two that I am aware of. sizeToFit and sizeThatFits.
On Sep 19, 2018, at 1:29 PM, Dave <dave@...> wrote:

Hi All,

Is there a Cocoa method I can use that will return the best fitting Font Size for a given String and Font?

I seem to remember using a method that does it but can’t seem to find it any more…..

All the Best
Dave



Dave
 

Hi,

I think it should work ok on iOS, will find out soon, there maybe some differences in method names etc.

I should have been more clear, this is for a single line, it should work for multiple lines too, but probably not as well as your suggestion, which is overkill for what I want it for.

All the Best
Dave

On 20 Sep 2018, at 15:00, Sandor Szatmari <admin.szatmari.net@...> wrote:

This was for macOS…  not sure how to go about it on iOS.  I’d guess it would work, but there may be an easier method.  I don’t know though.

I have used this method to dynamically size formatted multiline text (text that includes line breaks) to find the maximum font size for a fixed container size.  Granted there may be an easier solution that I am not aware of, but I am also counting the number of line of text being laid out, so this solution works for me.

1. Get text
2. Setup your mutable paragraph style, set properties, justification, wrapping… etc.
3. Create a layout manager… set properties, hyphenation, etc.  Important, set the layout mgr’s delegate (I used self for simplicity). You will receive callbacks about the layout process via delegation.
3a. Define delegate method -layoutManager:didCompleteLayoutForTextContainer:atEnd: (you will receive these callbacks where you can flag ‘clipping’ I.e. text too big) set a flag here indicating clipping has occurred.  I used an iVar.
4. Create a mutable attributes dict, this contains the para style keyed on NSParagraphStyleAttributeName.  (You will add/update the font later stored in this dict with different sizes later)
5. Create a text storage object with text and para style
6. Now loop… do while (notClipped && other things you care about)
Loop Body
a. Adjust font size
b. Create new NSFont object with new size.  Set font in attributes dict keyed on NSFontAttributeName
c. Adjust paragraph style as needed/desired (optional)
d. Reapply (Set) the updated attributes dict for the entire range of text in your text storage object -setAtteibutes:range:
e. Ask the layout manager/text storage to layout the text.  If the text is too big the container parameter in your callback will be nil indicating that ‘clipping’ occurred.  Use nil container to flag clipping thus communicating with your loop.

Rinse, repeat… till desired font size reached


The text generated using this approach is displayed in widgets that are part of a complex visual graph of objects all of which are the same size and which contain dynamic multiline text.   I have additional logic that counts the number of lines to ensure that there are always three lines.  Each line contains a different property of the object being represented.  IP, hostname, etc…  Think graphical displays of networks and such, with text inside the network components.

Sandor

On Sep 20, 2018, at 05:51, Dave <dave@...> wrote:

Hi,

Those two methods alter the frame size, I want to keep the same Frame Size but reduce the Font Size of the Content until it fit into the Displayable Area. I’m 99% sure there is a method to do it but maybe its iOS only?

All the Best
Dave

On 20 Sep 2018, at 02:02, Alex Zavatone via Groups.Io <zav@...> wrote:

There are two that I am aware of.  sizeToFit and sizeThatFits.
On Sep 19, 2018, at 1:29 PM, Dave <dave@...> wrote:

Hi All,

Is there a Cocoa method I can use that will return the best fitting Font Size for a given String and Font?

I seem to remember using a method that does it but can’t seem to find it any more…..

All the Best
Dave







Alex Zavatone
 

I do think that based on your requirements, there will have been others who have solved this. I just found a few solutions on Stack Overflow that could be adopted to MacOS.

Will send off list.

On Sep 20, 2018, at 4:51 AM, Dave <dave@...> wrote:

Hi,

Those two methods alter the frame size, I want to keep the same Frame Size but reduce the Font Size of the Content until it fit into the Displayable Area. I’m 99% sure there is a method to do it but maybe its iOS only?

All the Best
Dave

On 20 Sep 2018, at 02:02, Alex Zavatone via Groups.Io <zav@...> wrote:

There are two that I am aware of. sizeToFit and sizeThatFits.
On Sep 19, 2018, at 1:29 PM, Dave <dave@...> wrote:

Hi All,

Is there a Cocoa method I can use that will return the best fitting Font Size for a given String and Font?

I seem to remember using a method that does it but can’t seem to find it any more…..

All the Best
Dave







Sandor Szatmari
 

Yes, I’m sure single line (text field) instead of multiline (text view) can be accomplished with less rigor.  Let me know if you find anything interesting.

Sandor

On Sep 20, 2018, at 09:12, Dave <dave@...> wrote:

Hi,

I think it should work ok on iOS, will find out soon, there maybe some differences in method names etc.

I should have been more clear, this is for a single line, it should work for multiple lines too, but probably not as well as your suggestion, which is overkill for what I want it for.

All the Best
Dave

On 20 Sep 2018, at 15:00, Sandor Szatmari <admin.szatmari.net@...> wrote:

This was for macOS…  not sure how to go about it on iOS.  I’d guess it would work, but there may be an easier method.  I don’t know though.

I have used this method to dynamically size formatted multiline text (text that includes line breaks) to find the maximum font size for a fixed container size.  Granted there may be an easier solution that I am not aware of, but I am also counting the number of line of text being laid out, so this solution works for me.

1. Get text
2. Setup your mutable paragraph style, set properties, justification, wrapping… etc.
3. Create a layout manager… set properties, hyphenation, etc.  Important, set the layout mgr’s delegate (I used self for simplicity). You will receive callbacks about the layout process via delegation.
3a. Define delegate method -layoutManager:didCompleteLayoutForTextContainer:atEnd: (you will receive these callbacks where you can flag ‘clipping’ I.e. text too big) set a flag here indicating clipping has occurred.  I used an iVar.
4. Create a mutable attributes dict, this contains the para style keyed on NSParagraphStyleAttributeName.  (You will add/update the font later stored in this dict with different sizes later)
5. Create a text storage object with text and para style
6. Now loop… do while (notClipped && other things you care about)
Loop Body
a. Adjust font size
b. Create new NSFont object with new size.  Set font in attributes dict keyed on NSFontAttributeName
c. Adjust paragraph style as needed/desired (optional)
d. Reapply (Set) the updated attributes dict for the entire range of text in your text storage object -setAtteibutes:range:
e. Ask the layout manager/text storage to layout the text.  If the text is too big the container parameter in your callback will be nil indicating that ‘clipping’ occurred.  Use nil container to flag clipping thus communicating with your loop.

Rinse, repeat… till desired font size reached


The text generated using this approach is displayed in widgets that are part of a complex visual graph of objects all of which are the same size and which contain dynamic multiline text.   I have additional logic that counts the number of lines to ensure that there are always three lines.  Each line contains a different property of the object being represented.  IP, hostname, etc…  Think graphical displays of networks and such, with text inside the network components.

Sandor

On Sep 20, 2018, at 05:51, Dave <dave@...> wrote:

Hi,

Those two methods alter the frame size, I want to keep the same Frame Size but reduce the Font Size of the Content until it fit into the Displayable Area. I’m 99% sure there is a method to do it but maybe its iOS only?

All the Best
Dave

On 20 Sep 2018, at 02:02, Alex Zavatone via Groups.Io <zav@...> wrote:

There are two that I am aware of.  sizeToFit and sizeThatFits.
On Sep 19, 2018, at 1:29 PM, Dave <dave@...> wrote:

Hi All,

Is there a Cocoa method I can use that will return the best fitting Font Size for a given String and Font?

I seem to remember using a method that does it but can’t seem to find it any more…..

All the Best
Dave







Alex Zavatone
 

You also might want to check the height of a descender appears below the bounding NSTextField.

On Sep 20, 2018, at 5:21 AM, Dave <dave@...> wrote:

Hi,

Couldn’t find it so wrote my own:

(NSInteger) adjustFontSize:(NSInteger) theFontSize toFitWidth:(NSInteger) theWidth
{
NSInteger myFontSize;
NSFont* myFont;
NSSize myContentSize;

myFontSize = theFontSize;
while (YES)
{
myFont = [NSFont fontWithName:self.font.fontName size:myFontSize];
[self setFont:myFont];

myContentSize = [self.attributedStringValue size];
if (myContentSize.width < theWidth)
break;

myFontSize--;
if (myFontSize <= 0)
break;
}

return myFontSize;
}

This is on an NSTextField subclass and works a treat!

All the Best
Dave

On 20 Sep 2018, at 11:51, Dave <dave@...> wrote:

Hi,

Those two methods alter the frame size, I want to keep the same Frame Size but reduce the Font Size of the Content until it fit into the Displayable Area. I’m 99% sure there is a method to do it but maybe its iOS only?

All the Best
Dave

On 20 Sep 2018, at 02:02, Alex Zavatone via Groups.Io <zav@...> wrote:

There are two that I am aware of. sizeToFit and sizeThatFits.
On Sep 19, 2018, at 1:29 PM, Dave <dave@...> wrote:

Hi All,

Is there a Cocoa method I can use that will return the best fitting Font Size for a given String and Font?

I seem to remember using a method that does it but can’t seem to find it any more…..

All the Best
Dave








Ben Kennedy
 

On 20 Sep 2018, at 2:51 am, Dave <dave@...> wrote:

Those two methods alter the frame size, I want to keep the same Frame Size but reduce the Font Size of the Content until it fit into the Displayable Area. I’m 99% sure there is a method to do it but maybe its iOS only?
UILabel has `adjustsFontSizeToFitWidth` and `minimumScaleFactor` properties that aim to support that type of thing automatically. Could you employ it?

b


Dave
 

This is a Mac project and those methods are not available…..

On 20 Sep 2018, at 19:58, Ben Kennedy <ben-groups@...> wrote:

On 20 Sep 2018, at 2:51 am, Dave <dave@...> wrote:

Those two methods alter the frame size, I want to keep the same Frame Size but reduce the Font Size of the Content until it fit into the Displayable Area. I’m 99% sure there is a method to do it but maybe its iOS only?
UILabel has `adjustsFontSizeToFitWidth` and `minimumScaleFactor` properties that aim to support that type of thing automatically. Could you employ it?

b