How to handle a change in system level font size on iOS with React Native? - ios

We have a situation where if a user decides to increase the "Larger Text" size in iOS Settings (see image below), it then messes up our view layouts in React Native, as the font size will now be larger.
For example here is a ListView row BEFORE changing the "Larger Text" setting in iOS system settings:
And here is the same row AFTER increasing the "Larger Text" setting:
What is best practice to handle such font scale increase in React Native ? This is obviously just one example, and there are other scenario's such as a View that only contains Text, but we do not want to increase the height of that View at runtime.
Appreciate anyone's advice on this, thanks!

You can do the following to block such changes (do it on your root js file):
Text.defaultProps.allowFontScaling = false;

you could use ITEM_SIZE * PixelRatio.getFontScale()

Related

Programmatically Collapse NavigationSplitView to One Column

I have developed a SwiftUI NavigationSplitView app with two columns and it works as expected.
I have chosen dynamic fonts and crafted the visual elements to respond to user settings
for visual accessibility. I know that a number of the users who will employ this app will have
the font size set to the largest available. While that enhances their view of the detail
screen, it pretty much makes the sidebar unreadable. I'm trying to find a way to change
the app's behavior based on the size of the dynamic type. Specifically, I'd like to have
the iPad behavior the same as an iPhone behavior based on a font size that I define.
As it is, the app on an iPhone collapses to a single column. I have not been able to
find a way to programmatically do this on an iPad.
I have tried:
Setting the horizontalSizeClass and as expected, this is a getter only.
.horizontalSizeClass = .compact
I have tried setting the column width of the detail to 0.
.navigationSplitViewColumnWidth(0)
that does not work
I have tried using the old stack function.
.navigationViewStyle(StackNavigationViewStyle())
that does not work.
Clearly, this can be done, since it is automatic when the device is an iPhone. I guess
I could create two views - one stacked and one split and choose based on a State variable
but that seems a bit crude.
Any guidance would be appreciated. Xcode 14 beta 6, iOS 16
This is a great idea and can be achieved by overriding the horizontalSizeClass in the environment depending on the environment value of dynamicTypeSize as follows:
struct NavigationSplitViewTest: View {
#Environment(\.dynamicTypeSize) var dynamicTypeSize
var body: some View {
ViewContainingSplitView()
.environment(\.horizontalSizeClass, dynamicTypeSize > .large ? .compact : .none)
}
}
I tested it by launching the app on iPad simulator and it was in 2 column, then switching to Settings to increase the type size by one notch then back to app and it had switched to single column. However when attempting to switch the size back I noticed the show/hide column button disappeared so I think we have some feedback to submit.
I still have not found an elegant way to do this, but my solution here does work.
Basically, I code for NavigationSplitView and for NavigationStack and change based on the
Environment(.dynamicTypeSize). Like this:
if dynamicTypeSize <= .xxLarge {
NavigationSplitView(columnVisibility: $columnVisibility) {
//all the code
} detail: {
//all the code
}
} else {
NavigationStack {
//all the code
}
}
For others, I was confused by the terms involved here. There is DynamicTypeSize, dynamic
fonts and Larger Accessibility Sizes. Dynamic fonts are those pre-built fonts that
support dynamic type out of the box - .title, .headline, .body etc. Dynamic type size is
the slider in settings that allows the user to scale the dynamic fonts to suit their
needs - all the dynamic fonts scale with the slider setting. Then on top of the slider
in settings for these pre-made fonts, is the option for Larger Accessibility sizes
which gives the user even bigger options.
My scheme above supports all of those intermingled options for both iPad and iPhone.

iOS Swift: maximumContentSizeCategory not working on UILabel

According to this article:
https://useyourloaf.com/blog/restricting-dynamic-type-sizes/
And this WWDC 2021 video:
https://developer.apple.com/videos/play/wwdc2021/10059/?time=879
The minimumContentSizeCategory and maximumContentSizeCategory can limit the min and max font size when user uplevel/downlevel the font sizes in System Accessibility settings.
However I tried it out, and from the debugging info these two settings are properly set, but in view rendering, the font size still goes to very large if accessibility font size is very large.
// before setting
print(label.appliedContentSizeCategoryLimitsDescription)
label.minimumContentSizeCategory = .small
label.maximumContentSizeCategory = .accessibilityMedium
// after setting
print(label.appliedContentSizeCategoryLimitsDescription)
print results:
UILabel:0x7fd610a414a0: AX-L
--> AX-L
UILabel:0x7fd610a414a0: S <= (none->)AX-M <= AX-M
--> AX-M
How can I properly use these two settings?
Any ideas on how to properly use these two settings?
I hope that's the proper way because I use them as you did (and it works).
I created a blank project in Interface Builder (Xcode 13.4.1) as follows:
... and the Dynamic Type feature is blocked within the specified thresholds I defined like you (in the viewDidLoad of the view controller).
I think you should check out the way you created your label because, with the above one, it works like a charm.

Get rid of "Dynamic Text font size are unsupported" Warnings within Accessibility Inspector

I want to ask you - does anyone know how to get rid of the "Dynamic Text font sizes are unsupported" Warnings within Accessibility Inspector for iOS ?
I got a React Native application, I've disabled Font Scaling globally by overriding defaultProps (allowFontScalling: false) for Text and TextInput, but I still receive "Dynamic Text font sizes are unsupported" Warnings in the Accessibility Inspector that I use on the iOS Simulator.
How can I get rid of these Warnings I receive for TextInputs ? I can confirm that font is no longer scalable after doing that override.
The error is the exact opposite of what you think it means. The entire error message is:
"Issue: Dynamic Text font sizes are unsupported. User will not be able to change the font size of this element"
The last part is the important bit, what you have done means that a user cannot set the font size they prefer / require (which is an accessibility fail).
You should allow font sizes to be changed according to system preferences and so allowFontScaling should be set to true and your layout should adapt / be able to accommodate larger font sizes.
This is important for people with vision impairments in order to be able to use your App.

Vaadin Dialog resize programmatically

Vaadin 14.2.0.alpha7 added new functionality to Dialog component (https://vaadin.com/api/platform/14.2.0.alpha7/com/vaadin/flow/component/dialog/Dialog.html), especially the resizing availability. Unfortunately I was unable to find a way to have dialog being created with width I need neither to set the width programmatically after the dialog is opened.
Here are few lines of code I use for described purposes (unsuccessfully):
dialog.isResizable = true
dialog.width = "900px"
dialog.addOpenedChangeListener { event ->
println("!!!opened-changed event fired")
dialog.width = "900px"
println("!!!dialog width = ${dialog.width}")
}
dialog.addResizeListener { event ->
println("!!! on resize event width = ${dialog.width}")
}
When I open the dialog it appears with its limited width (around 500px), the OpenedChanged event being fired and prints that dialog has 900px width (while its not!), when I resize it manually the Resize event being fired and prints that dialog has around 600px width (after I increased it a bit manually using mouse).
I know that early versions of Dialog had limited width (around 500px) in templates and there is workaround with importing styles to adjust dialog width. I was hoping with new version to increase dialog width without touching templates and client-side.
Is there any way to set dialog width and adjust on being opened programmatically without touching client-side templates?
P.S. The 14.2.0 version announced to be published on April so I believe the question is suitable even for now its prerelease version.
This happens due to the max-width setting of ~560px to comply with the materials design. There is a ticket about it here: Dialog Size - Material Theme. (In the default Lumo theme this works out of the box. You can verify it by commenting out #Theme(value = Material::class, variant = Material.LIGHT) in MainLayout.kt)
Unfortunately, as style targets the overlay part, the only one way to overcome this is using style files. On the other hand, it should be pretty straightforward in the current version :)
I created a pull request to your repo with the changes needed. Feel free to use it, if you want Make width acccept values more than 500px :)

How to get iOS font size and set it to all labels of the app?

I want to make an app, where font size increase or decrease according to font size maintained in iOS in Settings. If you change font size of your iOS from settings, whatsapp font size displayed accordingly, I want same functionality.
The iOS functionality you're looking for is the Dynamic Type that only works for text with implemented text styles.
Basically, you must :
Use the text styles but beware, their availability depends on your iOS version.
Tick the adjustsFontForContentSizeCategory property (since iOS 10) in your interface builder or implement it in code so as to tell the system to handle automatically the Dynamic Type for the object it belongs to (text styles must be used of course).
Adapt all your constraints to the different sizes your app may encounter.
You can also follow the notifications related to the Dynamic Typeevents as indicated below :
Everything is well explained in this WWDC video detailed summary where all the contents and their video timelapses are indicated to reach rapidly the information.
There's also the possibility of adapting the graphical elements size as well with a Dynamic Type implementation.
All you have to do if to use Dynamic Type for your labels. This means not to set it explicitly but to use styles like Header 1 or caption. This styles are depends on user setting in Accessibility and will change automatically. https://www.raywenderlich.com/77092/text-kit-tutorial-swift
You can use system default sizes for Texts, like,
self.label.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
Please find documentation here.
For other components you can use like labelFontSize() and many more,
+ (CGFloat)labelFontSize;//Returns the standard font size used for labels.
+ (CGFloat)buttonFontSize;//Returns the standard font size used for buttons.
+ (CGFloat)smallSystemFontSize;//Returns the size of the standard small system font.
+ (CGFloat)systemFontSize;//Returns the size of the standard system font.

Resources