css – React Native (Expo managed) – How to disable “Display zoom view – Zoomed” on iOS

0
131


In almost finished Expo app, I encountered problem with one specific iOS settings – in Settings/Display & Brightness/View, there is an option to switch to “Zoomed”.

I am not sure what this actually does to the apps, but it feels like all Views and Text appear bigger, as if the resolution of device changes, but in quite a strange way.

I was easily able to solve the problem with Text by inserting

Text.defaultProps = Text.defaultProps || {};
Text.defaultProps.allowFontScaling = false;

which solved most of the problems and also prevented problems from other iOS settings Text Size, but the problem with Zoomed option still remains.

I could live with some lists not showing as much data as would be ideal (which ironically makes the app less accessible), but there is one screen that is complitely messed up with Zoomed settings (iPhone 12, happens also on other iPhones like SE):

Without zoom With zoom

For me, the best solution would be to turn this feature in the app completely as the UI is already designed to be accessible (core features of app are image and video based and require no text reading) and any settings from iOS is actually making things worse.

From my research, this is currently not possible, so I am posting a code snippet of one of the sections (the gray label with text and switch under it). Hopefully, there is some way to solve this problem at least locally as this is currently the only screen in such a bad shape.

<View style={SECTION_HEADER}>
   <Text style={SECTION_HEADER_TEXT} tx="Notifications preference" />
   <View style={ITEM_SWITCH}>
      <Text style={ITEM_TEXT} tx="Turn off phone notifications" />
      <Switch style={SWITCH} /> {/** logic omitted as it's not important for question */}
   </View>
</View>

and styles used

const SECTION_HEADER: ViewStyle = {
  paddingTop: spacing[4], // 16
  backgroundColor: color.palette.offWhite,
}

const SECTION_HEADER_TEXT: TextStyle = {
  paddingHorizontal: spacing[6], // 32
  color: color.palette.lightGrey,
  fontSize: typography.fontSize(14), // scale font based on screen size, code at the end
  ...typography.regular,
}

const ITEM: ViewStyle = {
  flexDirection: "row",
  alignItems: "center",
  height: typography.fontSize(72),
  marginTop: spacing[1], // 4
  paddingVertical: spacing[5], // 24
  paddingHorizontal: spacing[6], // 32
  backgroundColor: color.palette.white,
}

const ITEM_SWITCH: ViewStyle = {
  ...ITEM,
  paddingVertical: spacing[3], // 12
}

const ITEM_TEXT: TextStyle = {
  flexGrow: 1,
  color: color.palette.black,
  fontSize: typography.fontSize(16),
  ...typography.regular,
}

const SWITCH: ViewStyle = {
  margin: 0,
  padding: 0,
}

This is how we scale font size based on device screen

fontSize: (baseSize: number) => {
    const widthBaseScale = SCREEN_WIDTH / 393
    const heightBaseScale = SCREEN_HEIGHT / 767
    const baseScale = SCREEN_WIDTH < SCREEN_HEIGHT ? widthBaseScale : heightBaseScale

    return Math.round(PixelRatio.roundToNearestPixel(baseScale * baseSize))
  },

I am interested in any solution, either “hacky” way to disable this feature, or “correct” way to handle it according the best practices.