Date
1 - 3 of 3
SwiftUI AttributedString on Watch
Gerriet M. Denkmann
I have a Watch-App using SwiftUI.
let fontSize = 40.0
struct WatchContentView: View
{
@State var timeAttributedStr = AttributedString("--")
let timer = Timer.publish(every: 1, tolerance: 0.1, on: .main, in: .common).autoconnect()
var body: some View
{
VStack
{
Text(timeAttributedStr)
}
.onReceive(timer)
{ currentTime in
timeAttributedStr = … make from currentTime using fontSize …
// compare size of timeAttributedStr to window and decrease fontSize if needed
// no idea how to do this
}
}
}
The Problem:
I want to make fontSize as big as possible. And then do:
if timeAttributedStr.size.width > window.size.width then decrease fontSize
But sadly, AttributedString has no size.
A fixed fontSize is less than ideal, because the optimal timeAttributedStr will depend both on Locale and Watch model.
Gerriet.
let fontSize = 40.0
struct WatchContentView: View
{
@State var timeAttributedStr = AttributedString("--")
let timer = Timer.publish(every: 1, tolerance: 0.1, on: .main, in: .common).autoconnect()
var body: some View
{
VStack
{
Text(timeAttributedStr)
}
.onReceive(timer)
{ currentTime in
timeAttributedStr = … make from currentTime using fontSize …
// compare size of timeAttributedStr to window and decrease fontSize if needed
// no idea how to do this
}
}
}
The Problem:
I want to make fontSize as big as possible. And then do:
if timeAttributedStr.size.width > window.size.width then decrease fontSize
But sadly, AttributedString has no size.
A fixed fontSize is less than ideal, because the optimal timeAttributedStr will depend both on Locale and Watch model.
Gerriet.
Laurent Daudelin
Doesn’t AttributedString uses a dictionary to set its attributes, including font and font size?
toggle quoted message
Show quoted text
On Nov 7, 2022, at 07:06, Gerriet M. Denkmann <gerriet@...> wrote:I have a Watch-App using SwiftUI.
let fontSize = 40.0
struct WatchContentView: View
{
@State var timeAttributedStr = AttributedString("--")
let timer = Timer.publish(every: 1, tolerance: 0.1, on: .main, in: .common).autoconnect()
var body: some View
{
VStack
{
Text(timeAttributedStr)
}
.onReceive(timer)
{ currentTime in
timeAttributedStr = … make from currentTime using fontSize …
// compare size of timeAttributedStr to window and decrease fontSize if needed
// no idea how to do this
}
}
}
The Problem:
I want to make fontSize as big as possible. And then do:
if timeAttributedStr.size.width > window.size.width then decrease fontSize
But sadly, AttributedString has no size.
A fixed fontSize is less than ideal, because the optimal timeAttributedStr will depend both on Locale and Watch model.
Gerriet.
Alex Zavatone
Would you use a sizeToFit or sizeThatFits method call to do that for you even after you’ve set the attributed text?
Here’s a chunk of it. You can see how I apply the font size to the dictionary. Cheers!
// Set base font & size.
CGFloat fontSize = 20.0;
UIFont *fnt = [UIFont fontWithName:@"Helvetica" size:fontSize]; // never initialize a font with a size of 0.0, or it will always be Helvetica
// Define base string.
NSString *myString;
//myString = @"beauty club®"; // with R
myString = @"beauty club™"; // with TM
// Define base color and font definitions.
fontSize = 24;
UIColor *myBlue = [UIColor colorWithRed:.02 green:.48 blue:.66 alpha:1.0]; // Unused. Kept as an example.
UIColor *myPink = [UIColor colorWithRed:.93 green:.36 blue:.62 alpha:1.0];
UIFont *thickFont = [UIFont fontWithName:@"HelveticaNeue-Bold" size:fontSize];
UIFont *thinFont = [UIFont fontWithName:@"HelveticaNeue-Light" size:fontSize];
thinFont = [UIFont fontWithName:@"HelveticaNeue-Medium" size:fontSize];
// Define attributes dictionary for bold text.
NSDictionary *boldAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
thickFont, NSFontAttributeName,
myPink, NSForegroundColorAttributeName,
nil];
// Find range of text to make bold.
NSString *textToBeBoldAndPink = @"beauty";
NSRange boldAndPinkRange = [myString rangeOfString:textToBeBoldAndPink];
// Define attributes dictionary for thin text.
NSDictionary *thinAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
thinFont, NSFontAttributeName,
myPink, NSForegroundColorAttributeName,
nil];
// Find range of text to make thin.
NSString *textToBeThin;
// textToBeThin= @"club®"; // with R
textToBeThin= @"club™"; // with TM
NSRange thinTextRange = [myString rangeOfString:textToBeThin];
// Make the basic attributed string
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:myString
attributes:@{NSFontAttributeName: [fnt fontWithSize:fontSize]}];
// Apply bold and thin formatting to strings using appropriate ranges.
[attributedString setAttributes:boldAttributes range:boldAndPinkRange];
[attributedString setAttributes:thinAttributes range:thinTextRange];
// AZ - find position of desired character to superscript in string
NSString *charToFind;
//charToFind = @"®"; // In case we are using R instead. Just an example.
charToFind = @"™"; // In case we are using TM instead. Just an example.
NSRange positionOfSuperscriptCharacter = [myString rangeOfString:charToFind];
// Setting the point sizes using exact numbers
// NSInteger superscriptCharSize = 12;
// CGFloat pointsToRaiseBaseLineOfSupercriptChar = 8.0;
// UIColor *colorOfSuperText = myPink;
// NSNumber *characterBaselineOffsetUp = [NSNumber numberWithFloat:pointsToRaiseBaseLineOfSupercriptChar];
// Set point size of superscript text relative to display font size as a percentage of original.
CGFloat superscriptCharacterPercentOfFullsizeText = 0.60f; // 12 pt if original is 20 point
NSInteger superscriptCharSize = fontSize * superscriptCharacterPercentOfFullsizeText ;
// Set points to raise superscript text relative to font size as a percentage of original.
CGFloat superscriptCharacterPercentOfFullsizeTextToRaiseChar = 0.40f; // 8 points if original is 20 point
CGFloat pointsToRaiseBaseLineOfSupercriptChar = fontSize * superscriptCharacterPercentOfFullsizeTextToRaiseChar ;
NSNumber *characterBaselineOffsetUp = [NSNumber numberWithFloat:pointsToRaiseBaseLineOfSupercriptChar];
// Set color for text.
UIColor *colorOfSuperText = myPink;
// Set attributes to be applied to string.
NSDictionary *superTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
[fnt fontWithSize:superscriptCharSize], NSFontAttributeName,
colorOfSuperText, NSForegroundColorAttributeName,
characterBaselineOffsetUp, NSBaselineOffsetAttributeName,
nil];
// Apply the formatting for the superscript to the range of text for the string.
[attributedString setAttributes:superTextAttributes range:positionOfSuperscriptCharacter];
return attributedString;
On Nov 7, 2022, at 6:06 AM, Gerriet M. Denkmann <gerriet@...> wrote:I have a Watch-App using SwiftUI.
let fontSize = 40.0
struct WatchContentView: View
{
@State var timeAttributedStr = AttributedString("--")
let timer = Timer.publish(every: 1, tolerance: 0.1, on: .main, in: .common).autoconnect()
var body: some View
{
VStack
{
Text(timeAttributedStr)
}
.onReceive(timer)
{ currentTime in
timeAttributedStr = … make from currentTime using fontSize …
// compare size of timeAttributedStr to window and decrease fontSize if needed
// no idea how to do this
}
}
}
The Problem:
I want to make fontSize as big as possible. And then do:
if timeAttributedStr.size.width > window.size.width then decrease fontSize
But sadly, AttributedString has no size.
A fixed fontSize is less than ideal, because the optimal timeAttributedStr will depend both on Locale and Watch model.
Gerriet.