iOS Widget小组件大小和位置(透明组件)
Posted 时光不染
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS Widget小组件大小和位置(透明组件)相关的知识,希望对你有一定的参考价值。
小组件大小和位置
## size小组件获取组件大小
1.在Widget获取比较容易,通过context.displaySize
获取
context.displaySize
struct SmallProvider: IntentTimelineProvider
func getTimeline(for configuration: SmallIntent, in context: Context, completion: @escaping (Timeline<SmallEntry>) -> Void)
print(context.displaySize)
func placeholder(in context: Context) -> SmallEntry
print(context.displaySize)
func getSnapshot(for configuration: SmallIntent, in context: Context, completion: @escaping (SmallEntry) -> ())
print(context.displaySize)
2.在主程序获取
机型 | 屏幕尺寸(pt) | 小组件(pt) | 中组件(pt) | 大组件(pt) |
---|---|---|---|---|
5 / 5s /SE | 320x568 | 140x140 | 291x140 | 291x310 |
6 / 6s / 7 / 8 / SE2 | 375x667 | 148x148 | 321x148 | 321x324 |
6p / 6sp / 7p / 8p | 375x812 | 155x155 | 329x155 | 329x345 |
x / xs / 11pro / 12mini | 390x844 | 158x158 | 338x158 | 338x354 |
xr / xsmax / 11 / 11promax | 414x736 | 157x157 | 348x157 | 348x351 |
12 / 12pro | 414x896 | 169x169 | 360x169 | 369x379 |
12promax | 428x926 | 170x170 | 364x170 | 364x382 |
小号组件坐标
机型 | 屏幕尺寸(pt) | 左上(CGPoint) | 右上(CGPoint) | 左中(CGPoint) | 右中(CGPoint) | 左下(CGPoint) | 右下(CGPoint) |
---|---|---|---|---|---|---|---|
5 / 5s /SE | 320x568 | (x:14,y:30) | (x:165,y:30) | (x:14,y:200) | (x:165,y:200) | (x:-,y:-) | (x:-,y:-) |
6 / 6s / 7 / 8 / SE2 | 375x667 | (x:27,y:30) | (x:200,y:30) | (x:27,y:206) | (x:200,y:206) | (x:27,y:382) | (x:200,y:382) |
6p / 6sp / 7p / 8p | 375x812 | (x:23,y:71) | (x:197,y:71) | (x:23,y:261) | (x:197,y:261) | (x:23,y:451) | (x:197,y:451) |
x / xs / 11pro / 12mini | 390x844 | (x:26,y:77) | (x:206,y:77) | (x:26,y:273) | (x:206,y:273) | (x:26,y:469) | (x:206,y:469) |
xr / xsmax / 11 / 11promax | 414x736 | (x:33,y:38) | (x:224,y:38) | (x:33,y:232) | (x:224,y:232) | (x:33,y:426) | (x:224,y:426) |
12 / 12pro | 414x896 | (x:27,y:76) | (x:218,y:76) | (x:27,y:286) | (x:218,y:286) | (x:27,y:496) | (x:218,y:496) |
12promax | 428x926 | (x:32,y:82) | (x:226,y:82) | (x:32,y:294) | (x:226,y:294) | (x:32,y:506) | (x:226,y:506) |
中号组件坐标
机型 | 屏幕尺寸(pt) | 上(CGPoint) | 中(CGPoint) | 下(CGPoint) |
---|---|---|---|---|
5 / 5s /SE | 320x568 | (x:14,y:30) | (x:14,y:200) | (x:-,y:-) |
6 / 6s / 7 / 8 / SE2 | 375x667 | (x:27,y:30) | (x:27,y:206) | (x:27,y:382) |
6p / 6sp / 7p / 8p | 375x812 | (x:23,y:71) | (x:23,y:261) | (x:23,y:451) |
x / xs / 11pro / 12mini | 390x844 | (x:26,y:77) | (x:26,y:273) | (x:26,y:469) |
xr / xsmax / 11 / 11promax | 414x736 | (x:33,y:38) | (x:33,y:232) | (x:33,y:426) |
12 / 12pro | 414x896 | (x:27,y:76) | (x:27,y:286) | (x:27,y:496) |
12promax | 428x926 | (x:32,y:82) | (x:32,y:294) | (x:32,y:506) |
大号组件坐标
机型 | 屏幕尺寸(pt) | 上(CGPoint) | 下(CGPoint) |
---|---|---|---|
5 / 5s /SE | 320x568 | (x:14,y:30) | (x:-,y:-) |
6 / 6s / 7 / 8 / SE2 | 375x667 | (x:27,y:30) | (x:27,y:206) |
6p / 6sp / 7p / 8p | 375x812 | (x:23,y:71) | (x:23,y:261) |
x / xs / 11pro / 12mini | 390x844 | (x:26,y:77) | (x:26,y:273) |
xr / xsmax / 11 / 11promax | 414x736 | (x:33,y:38) | (x:33,y:232) |
12 / 12pro | 414x896 | (x:27,y:76) | (x:27,y:286) |
12promax | 428x926 | (x:32,y:82) | (x:32,y:294) |
代码
以下是测量的小组件在屏幕上的几个位置坐标,小组件大小和位置都可以通过以下数据换算得到
数组结构为[X1,X2,X3,Y1,Y2,Y3]
let deviceInfos:[String:Array<Int>] = [
"320x568":[14,165,305,30,200,370], // 5 5s SE。小组件只能放4个,中组件2个,大组件1个
"375x667":[27,200,348,30,206,382], // 6 6s 7 8 SE2
"375x812":[23,197,352,71,261,451], // x xs 11pro 12mini
"390x844":[26,206,364,77,273,469], // 12 12pro
"414x736":[33,224,381,38,232,426], // 6p 6sp 7p 8p
"414x896":[27,218,387,76,286,496], // xr xsmax 11 11promax
"428x926":[32,226,396,82,294,506], // 12promax
]
获取组件宽度
小组件尺寸为X3-X2
的正方形
中组件宽度为X3-X1
,高度等同小组件 X3-X2
大组件宽度为X3-X1
, 高度为(Y2-Y1) + (X3-X2)
小组件高度为X3-X2
func GetWidgetSize(_ widgetType:WidgetSizeEnum) -> CGSize
let wxh:String = "\\(Int(WIDTH))x\\(Int(HEIGHT))"
// TODO 外层做异常处理。告知用户 “您的机型暂不支持透明组件”
if !deviceInfos.keys.contains(wxh)
return CGSize(width: -1, height: -1)
switch widgetType
case .small:
let smallWidth = deviceInfos[wxh]![2] - deviceInfos[wxh]![1]
return CGSize(width: smallWidth, height: smallWidth)
case .medium:
let mediumWidth = deviceInfos[wxh]![2] - deviceInfos[wxh]![0]
let mediumHeight = deviceInfos[wxh]![2] - deviceInfos[wxh]![1]
return CGSize(width: mediumWidth, height: mediumHeight)
case .large:
let largeWidth = deviceInfos[wxh]![2] - deviceInfos[wxh]![0]
let largeHeight = deviceInfos[wxh]![4] - deviceInfos[wxh]![3] + deviceInfos[wxh]![2] - deviceInfos[wxh]![1]
return CGSize(width: largeWidth, height: largeHeight)
enum WidgetSizeEnum
case small
case medium
case large
获取小组件位置
320x568
的机型同屏只有4个位置能放小组件,其他尺寸比例的机型为6个
//小组件位置枚举
enum WidgetSizeEnum
case topLeft
case topRight
case middleLeft
case middleRight
case bottomLeft
case bottomRight
// 小组件。获取在不同位置的x,y坐标
func GetSmallWidgetPos(_ widgetPos:SWidgetPosEnum)->CGPoint
let wxh:String = "\\(Int(WIDTH))x\\(Int(HEIGHT))"
// TODO 外层做异常处理。告知用户 “您的机型暂不支持透明组件”
if !deviceInfos.keys.contains(wxh)
return CGPoint(x: -1, y: -1)
if(wxh == "320x568")
switch widgetPos
case .topLeft:
return CGPoint(x: deviceInfos[wxh]![0], y: deviceInfos[wxh]![3])
case .topRight:
return CGPoint(x: deviceInfos[wxh]![1], y: deviceInfos[wxh]![3])
case .middleLeft, .bottomLeft:
return CGPoint(x: deviceInfos[wxh]![0], y: deviceInfos[wxh]![4])
case .middleRight, .bottomRight:
return CGPoint(x: deviceInfos[wxh]![1], y: deviceInfos[wxh]![4])
else
switch widgetPos
case .topLeft:
return CGPoint(x: deviceInfos[wxh]![0], y: deviceInfos[wxh]![3])
case .topRight:
return CGPoint(x: deviceInfos[wxh]![1], y: deviceInfos[wxh]![3])
case .middleLeft:
return CGPoint(x: deviceInfos[wxh]![0], y: deviceInfos[wxh]![4])
case .middleRight:
return CGPoint(x: deviceInfos[wxh]![1], y: deviceInfos[wxh]![4])
case .bottomLeft:
return CGPoint(x: deviceInfos[wxh]![0], y: deviceInfos[wxh]![5])
case .bottomRight:
return CGPoint(x: deviceInfos[wxh]![1], y: deviceInfos[wxh]![5])
获取中组件位置
320x568
的机型同屏只有上下2个位置能放中组件,其他尺寸比例的机型为上中下3个
//中组件位置枚举
enum WidgetSizeEnum
case top
case middle
case bottom
// 中组件。获取在不同位置的x,y坐标
func GetMiddleWidgetPos(_ widgetPos:MWidgetPosEnum)->CGPoint
let wxh:String = "\\(Int(WIDTH))x\\(Int(HEIGHT))"
// TODO 外层做异常处理。告知用户 “您的机型暂不支持透明组件”
if !deviceInfos.keys.contains(wxh)
return CGPoint(x: -1, y: -1)
if(wxh == "320x568")
switch widgetPos
case .top:
return CGPoint(x: deviceInfos[wxh]![0], y: deviceInfos[wxh]![3])
case .middle, .bottom:
return CGPoint(x: deviceInfos[wxh]![0], y: deviceInfos[wxh]![4])
else
switch widgetPos
case .top:
return CGPoint(x: deviceInfos[wxh]![0], y: deviceInfos[wxh]![3])
case .middle:
return CGPoint(x: deviceInfos[wxh]![0], y: deviceInfos[wxh]![4])
case .bottom:
return CGPoint(x: deviceInfos[wxh]![0], y: deviceInfos[wxh]![5])
获取大组件位置
320x568
的机型同屏只有1个位置能放大组件,其他尺寸比例的机型为上中下2个
//大组件位置枚举
enum WidgetSizeEnum
case top
case bottom
// 大组件。获取在不同位置的x,y坐标
func GetLargeWidgetPos(_ widgetPos:LWidgetPosEnum)->CGPoint
let wxh:String = "\\(Int(WIDTH))x\\(Int(HEIGHT))"
// TODO 外层做异常处理。告知用户 “您的机型暂不支持透明组件”
if !deviceInfos.keys.contains(wxh)
return CGPoint(x: -1, y: -1)
if(wxh == "320x568")
return CGPoint(x: deviceInfos[wxh]![0], y: deviceInfos[wxh]![3])
else
switch widgetPos
case .top:
return CGPoint(x: deviceInfos[wxh]![0], y: deviceInfos[wxh]![3])
case .bottom:
return CGPoint(x: deviceInfos[wxh]![0], y: deviceInfos[wxh]![4])
case .unknown,.alpha1:
return CGPoint(x: 0, y: 0)
以上是关于iOS Widget小组件大小和位置(透明组件)的主要内容,如果未能解决你的问题,请参考以下文章
Qt入门系列开发教程基础控件篇小部件(所有控件的基类QWidget)
iOS14 Widget小组件开发(Widget Extension)