Get available widget height and width depending on the device's screenSize?

Hello,

according to the widget documentation in Apple’s HIG the height and width of the three widget sizes (small, medium, large) vary greatly depending on the device’s screenSize.

  • 414x896 pt devices are the XR, 11, 11 Pro Max
  • 375x812 pt devices are the X, XS, 11 Pro
  • 414x736 pt devices are the 6/7/8(S) Plus
  • 375x667 pt devices are the 6/7/8(S) and SE (2nd Gen.)
  • 320x568 pt devices is the SE (1st Gen.)

(Note: The iPhone 12, 12 Pro and 12 Pro Max, which have new base resolutions are still missing in the HIG.)

It would be great to have Scriptable provide the according widget height and width as numeric values. (@simonbs)

By that, it would be possible to accurately calculate the available remaining canvas given a set padding.

For example: On an iPhone 11 Pro Max the 169 pt width of a widget with 2x 16 pt padding (safe area) would result in 137 pt of remaining space.
On the 11 Pro (155 pt) this would just result in 123 pt.

Also, I am not sure about the iPad device sizes. The iPad Pro 12.9 seems to have a small widget width of 170 pt.
I assume the iPad Pro 11 is at 155pt.

Sure I could query for all those device types in my widget and derive various sizing scales from it, but I feel that those 30-40 lines of code should be part of the framework provided by Scriptable.

… unless, I have simply missed it in the docs. :sweat_smile:

Thanks a lot!

5 Likes

It would be even greater if one could specify relative units for the various dimensions in Scriptable.

thank you for the research you’ve done on the subject!

with the information available, i came use with the getWidgetSizeInPoint to quickly retrieve the corresponding widget size.

  • if running inside a widget, it can be called without parameter to get the corresponding size of the widget running in.
  • if not running inside a widget, a parameter of the desired widget family to be provided: small, medium, or large

i’ll see if i can find out the proper sizes for various iPad models later for an update.

function getWidgetSizeInPoint(widgetSize = (config.runsInWidget ? config.widgetFamily : null)) {
  // stringify device screen size
  const devSize = `${Device.screenSize().width}x${Device.screenSize().height}`
  // screen size to widget size mapping for iPhone, excluding the latest iPhone 12 series. iPad size
  const sizeMap = {
    // iPad Mini 2/3/4, iPad 3/4, iPad Air 1/2. 9.7" iPad Pro
    // '768x1024': { small: [0, 0], medium: [0, 0], large: [0, 0] },
    // 10.5" iPad Pro
    // '834x1112': { small: [0, 0], medium: [0, 0], large: [0, 0] },
    // 12.9" iPad Pro
    // '1366x1024': { small: [0, 0], medium: [0, 0], large: [0, 0] },
    // XR, 11, 11 Pro Max
    '414x896': { small: [169, 169], medium: [360, 169], large: [360, 376] },
    // X, XS, 11 Pro
    '375x812': { small: [155, 155], medium: [329, 155], large: [329, 345] },
    // 6/7/8(S) Plus
    '414x736': { small: [159, 159], medium: [348, 159], large: [348, 357] },
    // 6/7/8(S) and 2nd Gen SE
    '375x667': { small: [148, 148], medium: [322, 148], large: [322, 324] },
    // 1st Gen SE
    '320x568': { small: [141, 141], medium: [291, 141], large: [291, 299] }
  }
  let widgetSizeInPoint = null

  if (widgetSize) {
    let mappedSize = sizeMap[devSize]
    if (mappedSize) {
      widgetSizeInPoint = new Size(...mappedSize[widgetSize])
    }
  }
  return widgetSizeInPoint
}
1 Like

Thanks a lot! Out of frustration, I created a similar map yesterday for myself.

I went even deeper on iPads and can fill in some gaps … and sadly potentially create some new ones (heck screen sizes have become a mess for Apple devices!):

function getWidgetSizeInPoint(widgetSize = (config.runsInWidget ? config.widgetFamily : null)) {
  // stringify device screen size
  const devSize = `${Device.screenSize().width}x${Device.screenSize().height}`
  // screen size to widget size mapping for iPhone, excluding the latest iPhone 12 series. iPad size
  const sizeMap = {
    // iPad Mini 2/3/4, iPad 3/4, iPad Air 1/2. 9.7" iPad Pro
    // '768x1024': { small: [0, 0], medium: [0, 0], large: [0, 0] },
    // 10.2" iPad
    // '1080x810': { small: [0, 0], medium: [0, 0], large: [0, 0] },
    // 10.5" iPad Pro, 10.5" iPad Air 3rd Gen
    // '1112x834': { small: [0, 0], medium: [0, 0], large: [0, 0] },
    // 10.9" iPad Air 4th Gen
    // '1180x820': { small: [0, 0], medium: [0, 0], large: [0, 0] },
    // 11" iPad Pro
    '1194x834': { small: [155, 155], medium: [329, 155], large: [345, 329] },
    // 12.9" iPad Pro
    '1366x1024': { small: [170, 170], medium: [332, 170], large: [382, 332] },
    // 12 Pro Max
    // '428x926': { small: [0, 0], medium: [0, 0], large: [0, 0] },
    // XR, 11, 11 Pro Max
    '414x896': { small: [169, 169], medium: [360, 169], large: [360, 376] },
    // 12, 12 Pro
    // '390x844': : { small: [0, 0], medium: [0, 0], large: [0, 0] },
    // X, XS, 11 Pro, 12 Mini
    '375x812': { small: [155, 155], medium: [329, 155], large: [329, 345] },
    // 6/7/8(S) Plus
    '414x736': { small: [159, 159], medium: [348, 159], large: [348, 357] },
    // 6/7/8(S) and 2nd Gen SE
    '375x667': { small: [148, 148], medium: [322, 148], large: [322, 324] },
    // 1st Gen SE
    '320x568': { small: [141, 141], medium: [291, 141], large: [291, 299] }
  }
  let widgetSizeInPoint = null

  if (widgetSize) {
    let mappedSize = sizeMap[devSize]
    if (mappedSize) {
      widgetSizeInPoint = new Size(...mappedSize[widgetSize])
    }
  }
  return widgetSizeInPoint
}

I think it is safe to assume that the iPad Mini will run with the 141pt small widget class.
The 10.2" iPad maybe at 149pt.
Also I’d say that the 10.9" and 10.5" iPads, will be in the 155pt class.

It will be interesting to see how the jump up to 428x926 for the iPhone 12 Pro Max and up to (for the 12 Pro) or sadly down to (for the 12, as a successor to the XR/11) to 390x844 will affect widget sizing.

I really hope that we can keep it updated and find more people to try and test :slight_smile:
The app adaptivity does a rally great job!

thank you for the great addition!

  • forgetful me completely forgot about device rotation. this now properly cater for that.
  • added widgetSize checking in case the parameter is entered improperly.
function getWidgetSizeInPoint(widgetSize = (config.runsInWidget ? config.widgetFamily : null)) {
  // RegExp to verify widgetSize
  const sizes = /^(?:small|medium|large)$/
  // stringify device screen size
  const devSize = (({width: w, height: h}) => w > h ? `${h}x${w}` : `${w}x${h}`)(Device.screenSize())
  // screen size to widget size mapping for iPhone, excluding the latest iPhone 12 series. iPad size
  const sizeMap = {
    // iPad Mini 2/3/4, iPad 3/4, iPad Air 1/2. 9.7" iPad Pro
    // '768x1024': { small: [0, 0], medium: [0, 0], large: [0, 0] },
    // 10.2" iPad
    // '810x1080': { small: [0, 0], medium: [0, 0], large: [0, 0] },
    // 10.5" iPad Pro, 10.5" iPad Air 3rd Gen
    // '834x1112': { small: [0, 0], medium: [0, 0], large: [0, 0] },
    // 10.9" iPad Air 4th Gen
    // '820x1180': { small: [0, 0], medium: [0, 0], large: [0, 0] },
    // 11" iPad Pro
    '834x1194': { small: [155, 155], medium: [329, 155], large: [345, 329] },
    // 12.9" iPad Pro
    '1024x1366': { small: [170, 170], medium: [332, 170], large: [382, 332] },
    // 12 Pro Max
    // '428x926': { small: [0, 0], medium: [0, 0], large: [0, 0] },
    // XR, 11, 11 Pro Max
    '414x896': { small: [169, 169], medium: [360, 169], large: [360, 376] },
    // 12, 12 Pro
    // '390x844': { small: [0, 0], medium: [0, 0], large: [0, 0] },
    // X, XS, 11 Pro, 12 Mini
    '375x812': { small: [155, 155], medium: [329, 155], large: [329, 345] },
    // 6/7/8(S) Plus
    '414x736': { small: [159, 159], medium: [348, 159], large: [348, 357] },
    // 6/7/8(S) and 2nd Gen SE
    '375x667': { small: [148, 148], medium: [322, 148], large: [322, 324] },
    // 1st Gen SE
    '320x568': { small: [141, 141], medium: [291, 141], large: [291, 299] }
  }
  let widgetSizeInPoint = null

  if (widgetSize && sizes.test(widgetSize)) {
    let mappedSize = sizeMap[devSize]
    if (mappedSize) {
      widgetSizeInPoint = new Size(...mappedSize[widgetSize])
    }
  }
  return widgetSizeInPoint
}

now i’m off to search about the screen sizes for various iPads…

1 Like

Hi, seeing this documentation about the displays, I noticed that in the docs, the iPhone 6/6S Plus have a size of 375x667 pt instead of 414x736 pt (iPhone 7/8 Plus), despite they have the same hardware resolution(1080x1920) and same screen scale factor (3x), how this works? I’m a bit confused because that doesn’t make any sense since they have basically the same screen. :woozy_face:

Edit: Can someone with an iPhone 6/6S Plus confirm this using Device.screenSize()?

Edit 2: Nevermind, seems like that documentation is wrong and outdated, I found this one that seems more updated.