如何相对于图像在背景图像上定位 UI 元素
Posted
技术标签:
【中文标题】如何相对于图像在背景图像上定位 UI 元素【英文标题】:How to position UI elements on background image relative to the image 【发布时间】:2018-08-13 10:03:50 【问题描述】:我之前曾在这里提问How to make full screen background image inside ScrollView and keep aspect ratio 并从“ekscrypto”得到很好的回答,再次感谢您。
我在图像上有带有文本的按钮(1、2、3、4、5 等)以前我使用硬编码的 X 和 Y 坐标来定位背景图像上的 UI 元素(按钮),这个解决方案适用于所有iPhone 设备,而不是 iPad。 我根据从“ekscrypto”收到的解决方案更改了我的代码,现在这个解决方案当然不适用于任何设备。
图片上有一条路,我需要在这条路上安排这些按钮。无论设备和图像比例如何,我如何才能相对于图像正确定位此按钮?
附: Ekscrypto 也提供了 UI 元素定位的解决方案,但我不明白它是如何工作的。
这是我目前尝试创建按钮的方式:
let imageOne = UIImage(named: "level1") as UIImage?
let levelOne = UIButton(type: UIButtonType.system)
levelOne.frame = CGRect.init(x: 10, y: 10, width: 100, height: 45)
levelOne.setImage(imageOne, for: .normal)
scrollView.addSubview(levelOne)
但 iPhone 和 iPad 的按钮位置和大小应该不同。我怎样才能让它们相对于图像正确放置?
非常感谢 ekscrypto,很抱歉延迟回答。您的代码正在运行,并且解决了我的问题,但是有一个小问题。
必须将这一行 let button = UIButton(type: .system) 更改为 .custom,或者将背景图像改为蓝色填充按钮。
带有背景图片的按钮太大,特别是在 iPhone 5 上,将 let backgroundDesignHeight: CGFloat = 330.0: CGFloat = 330.0 改为 730 以使其更小
iPhone 和 iPad 上的所有按钮都在同一个位置,除了«plus devices»,底部(向下)按钮的偏移量应该稍高
在某些设备上,按钮上的背景图像有点模糊,这是在我将 backgroundDesignHeight 更改为 730 后发生的【问题讨论】:
没有可以在这里提供帮助的 ios 人员? 由于您的 UI 是在代码中创建的,您能否展示您当前尝试创建按钮的方式? ekscrypto 感谢您的帮助。代码如下: let imageOne = UIImage(named: "level1") as UIImage? let levelOne = UIButton(type: UIButtonType.system) levelOne.frame = CGRect.init(x: 10, y: 10, width: 100, height: 45) levelOne.setImage(imageOne, for: .normal) scrollView.addSubview(一级) 我在下面添加了我的答案。让我知道是否需要进一步澄清或是否给您带来麻烦 如果您想避免图像模糊,您需要创建适合各种设备大小的自定义按钮图像。使用单个图像并在代码中调整它的大小有时看起来不太好。如果您的按钮只有一组图像,请将其放大,以便在缩放时可以使用更多数据。 【参考方案1】:您可以通过以下几种方式解决此问题:
根据当前屏幕尺寸和“设计”尺寸手动计算最终 x/y 位置 手动创建基于纵横比的约束,让 iOS 为您计算最终位置假设您的设备/应用程序方向是恒定的(始终为横向或始终纵向)并且始终为全屏,手动计算可能更容易。
首先,您需要一个辅助函数来调整图像大小:
private func scaledImage(named imageName: String, scale: CGFloat) -> UIImage?
guard let image = UIImage(named: imageName) else return nil
let targetSize = CGSize(width: image.size.width * scale, height: image.size.height * scale)
return resizeImage(image: image, targetSize: targetSize)
// Adapted from https://***.com/questions/31314412/how-to-resize-image-in-swift
private func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage?
let size = image.size
let widthRatio = targetSize.width / size.width
let heightRatio = targetSize.height / size.height
// Figure out what our orientation is, and use that to form the rectangle
var newSize: CGSize
if(widthRatio > heightRatio)
newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
else
newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
// This is the rect that we've calculated out and this is what is actually used below
let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
// Actually do the resizing to the rect using the ImageContext stuff
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
接下来,我们将创建一个函数来计算按钮的位置,以及基于图像大小的按钮大小:
private func positionScaledButton(x designX: CGFloat, y designY: CGFloat, imageName: String) -> UIButton
// First, compute our "designScale"
let screenHeight = UIScreen.main.bounds.size.height
let backgroundDesignHeight: CGFloat = 330.0 // ** see below
let designScale = screenHeight / backgroundDesignHeight
// Create button
let button = UIButton(type: .custom)
// Get image to use, and scale it as required
guard let image = scaledImage(named: imageName, scale: designScale) else return button
button.frame = CGRect(x: designX * designScale, y: designY * designScale, width: image.size.width, height: image.size.height)
button.setImage(image, for: .normal)
scrollView.addSubview(button)
return button
** 上面代码中的“330.0”值是指滚动条中背景图片的高度,从这里测量按钮的x/y坐标。
假设按钮的左上角应该在 x: 10, y: 10,对于图像“levelOne”:
let levelOneButton = positionScaledButton(x: 10, y: 10, imageName: "imageOne")
// To do: addTarget event handler
【讨论】:
我尝试摆脱模糊图像,为不同的设备创建不同的图像,还尝试了非常大的图像甚至矢量图像,不走运,图像仍然模糊。作为解决方法,我只是在创建按钮后更改了图像。 @dakath 如果您为每个设备使用自定义图像,您将希望摆脱 scaledImage 和 resizeImage 函数并在创建按钮时直接使用您的图像。 我无法正确设置 backgroundDesignHeight。我的背景图片高度为 1242 像素,并且 positionScaledButton 函数返回非常小的按钮(图片),特别是在 iPhone 5 上。你有什么解决方法的想法吗? 鉴于您用于背景的设计,我敢说是的,您的按钮在 iPhone 5 上会非常小。您可能必须为这些小型设备提供不同的背景图像,尽管我不再为 iPhone 5 设计;我认为 Apple 积极销售和支持的最小设备是 iPhone 6s。 不幸的是,在 iphone 6 和 iPad 上的按钮也太小了。什么是最简单的解决方案?也许最好只是让背景图像高度更小,对于 exp。小两倍?【参考方案2】:使用相对点,而不是绝对点。
因此,不要说按钮 1 位于 (30, 150)
处,而是使用屏幕尺寸的分数,使其位于 (0.0369, 0.4)
- 然后使用这些分数来创建您的自动布局约束。
【讨论】:
我不明白。能否请您更详细地解释一下?假设我们有一台屏幕尺寸为 414x736 点的 iPhone 6 plus。在 iPone 6 plus 上需要的地方有 30、150 个坐标点。 1. 如何获得相对积分? 2. 如何使用这个相对点来创建自动布局的约束? 简单除法 - 给定坐标的相对位置为 (30/414, 150/736) =(0.0725, 0.2038)
好的,如何使用相对坐标定位按钮? button1.centerXAnchor.constraint(equalTo: "等于什么?").isActive = true button1.centerYAnchor.constraint(equalTo: "等于什么?").isActive = true 提前致谢。
@dakath 不需要设置约束,设置位置即可以上是关于如何相对于图像在背景图像上定位 UI 元素的主要内容,如果未能解决你的问题,请参考以下文章
无法使用适用于 iOS 混合应用程序的 appium 检查作为背景图像存在的元素