iOS 屏幕坐标和缩放
Posted
技术标签:
【中文标题】iOS 屏幕坐标和缩放【英文标题】:iOS Screen coordinates and scaling 【发布时间】:2016-03-07 23:59:25 【问题描述】:我正在尝试在 CALayer 中的图像上绘图,但在绘图显示在不同尺寸的显示器上时遇到了问题。
func drawLayer()
let circleLayer = CAShapeLayer()
let radius: CGFloat = 30
let x = Thermo.frame.origin.x
let y = Thermo.frame.origin.y
let XX = Thermo.frame.width
let YY = Thermo.frame.height
print("X: \(x) Y: \(y) Width: \(XX) Height: \(YY)")
circleLayer.path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: 2.0 * radius, height: 2.0 * radius) , cornerRadius: radius).CGPath
circleLayer.fillColor = UIColor.redColor().CGColor
circleLayer.shadowOffset = CGSizeMake(0, 3)
circleLayer.shadowRadius = 5.0
circleLayer.shadowColor = UIColor.blackColor().CGColor
circleLayer.shadowOpacity = 0.8
circleLayer.frame = CGRectMake(0, 410, 0, 192);
self.Thermo.layer.addSublayer(circleLayer)
circleLayer.setNeedsDisplay()
在正确的位置画了一个圆圈……对于 iPhone 6s。但是,当封闭的 UIImageView 组件针对较小的设备进行缩放时,显然不会。我添加了 print() 来查看图像的大小和位置,并且......好吧,它在我在 X:192.0 Y:8.0 宽度:216.0 高度:584.0 上运行的每台设备上都完全相同,但显然它正在被缩放通过 AuoLayout 管理器中的约束。
所以,我的问题是,如果我不能使用封闭视图的尺寸和位置,我该如何确定不同屏幕尺寸的正确收音机和位置,因为这似乎永远不会改变?
这是我开始的图像,在 UIImageView 中,并试图绘制。 我当然会尝试根据来自外部设备的数据对其进行着色。非常感谢任何建议/示例代码!
【问题讨论】:
你在哪里打电话drawLayer()
?如果它在 UIView 的子类中,请将其移动到 viewDidLayoutSubviews()
或 layoutSubviews()
?
它不是 UIView 的子类,反正还不是。调用 setNeedsDisplay() 会导致视图被重新绘制。
调用 setNeedsDisplay 将图层标记为需要重绘(即,您可以连续调用 setNeedsDisplay 三次,并且它只会在像素被推送到屏幕时重绘一次)。您应该将代码移动到viewDidLayoutSubviews()
,正如我建议的那样,在自动布局引擎通过后调用它,因此最后一次调用viewDidLayoutSubviews()
Thermo.frame
将是正确的。
所以我已按照建议将其移至 viewDidLayoutSubviews() 。然而,仍然有一些奇怪的事情发生。这确实有助于(大部分)正确定位,但由于无论屏幕大小如何,缩放因子都不会改变——直到你使用 iPad 设备——它仍然看起来很奇怪,因为圆圈的大小不合适。显然 ios 正在缩放图像,但 Thermo.image.scale 在所有 iPhone 尺寸上都返回 1.0。这会导致不同屏幕尺寸上的尺寸错误,并且位置也略有错误(因为图像已缩放)。
您必须发布一个屏幕截图,说明最正确的含义以及您认为应该如何。我可能是错的,但我猜 Thermo.image.scale 会告诉你图像是@1x、@2x 还是@3x,如果你只提供一张图像,它总是会返回 1,因此伯爵格雷为什么建议你使用 @ 987654330@ 如果你在 UIView 的子类中进行绘图,除非你打算进行非常精确的绘图,否则你不必注意比例。尽管我怀疑您的绘图不正常可能是由比例以外的其他原因造成的。
【参考方案1】:
CALayer 及其子类,包括。 CAShapeLayer 有一个属性
var contentsScale: CGFloat
来自类参考:
对于您自己创建和管理的图层,您必须根据屏幕分辨率和您提供的内容自行设置此属性的值。 Core Animation 使用您指定的值作为提示来确定如何呈现您的内容。
所以你需要做的是在图层上设置比例,然后从 UIDevice 类中获取设备的比例
circleLayer.scale = UIScreen.mainScreen().scale
【讨论】:
以上是关于iOS 屏幕坐标和缩放的主要内容,如果未能解决你的问题,请参考以下文章