ios - 如何在 ScrollView 中制作全屏背景图像并保持纵横比
问题描述
我在 ScrollView 中使用了 @2x 7360x828px 和 @3x 11040x1242px 的背景图像,在所有 iPhone(全屏)上看起来都不错,但在 iPad 上,背景图像仅占屏幕高度的一半。
我尝试了很多变体,有自动布局和没有,有不同的 contentMode,但我无法实现我的目标,背景图像非常拉伸,或者具有正确纵横比的图像小于 ScrollView。
我的最后一个代码:
var imageView = UIImageView(image: UIImage(named: "map.png"))
lazy var scrollView = UIScrollView(frame: view.bounds)
override func viewDidLoad() {
super.viewDidLoad()
makeScrollView()
}
func makeScrollView() {
// For iPad
scrollView.backgroundColor = UIColor.black
scrollView.contentSize = imageView.bounds.size
scrollView.clipsToBounds = true
scrollView.contentMode = .scaleAspectFit
print("Scroll size: == ")
print(scrollView.contentSize)
scrollView.autoresizingMask = UIViewAutoresizing.flexibleWidth
scrollView.autoresizingMask = UIViewAutoresizing.flexibleHeight
scrollView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)
scrollView.contentInsetAdjustmentBehavior = .never
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
scrollView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
imageView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(imageView)
imageView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
imageView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
imageView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 7360 / 2).isActive = true
imageView.contentMode = .scaleAspectFit
}
如何为 iPad 制作全屏背景图像并保持纵横比?
该应用程序仅在横向模式下使用。
截图:
1) contentMode = .scaleAspectFit
2) contentMode = .scaleAspectFill
解决方案
我准备了一个示例项目来演示如何仅使用故事板来定位所有内容。当您的设置正确完成后,iOS 会为您处理缩放和定位所有内容。您也可以在代码中执行此操作,只需按照本指南中有关使用纵横比的提示进行操作。
这是 GitHub 项目:https ://github.com/ekscrypto/Scaled-Scroller-Demo
接下来,设置将充当 UI 不同部分的容器的容器视图,这个容器视图将容纳整个图像,完全缩放并匹配图像纵横比。只需在滚动视图中放置一个常规 UIView,将其对超级视图容器的前导/尾随/顶部/底部布局约束设置为 0。它会抱怨无法定位它,直到您在下一步添加图像..
现在这里是大部分魔法发生的地方。在您刚刚放入的 UIView 中插入一个 UIImageView。首先将此 UIImageView 设置为 UIView 容器 0 的前导/尾随/顶部/底部布局约束。
然后,在 UIView 的宽度和高度之间设置纵横比约束,并确保将乘数值设置为要使用的图像的宽度:高度。就我而言,这是 1600 x 330。
纵横比非常重要,因为这将确保图像不失真,这也将迫使父视图拉伸并保持该纵横比。另一个非常重要的约束是确保这个 UIImageView 的高度等于视图控制器的根视图。这确保图像从屏幕底部到顶部,无论您使用的是 iPad 还是 iPhone。
注意没有设置为特定值的宽度或高度,只有纵横比。这就是一切的规模。
虽然这足以回答您的问题,但我还添加了几个 UI 元素定位示例,因此它们始终具有相同的比例,并且始终相对于图像正确定位,无论设备如何。基本上对于您想要相对于图像定位的每个 UI 元素,您设置一个隐藏的 UIView,其纵横比等于您想要它们的 X 和 Y 距离。
然后,您将“定位” UIView 隐藏起来,并将您的实际 UI 元素(按钮等)放置在与该视图右下角相关的位置。最终结果是在 iPhone 和 iPad 上正确缩放的界面。
尽管您的图像已经在图像中烘焙了“按钮”,但您可能仍希望在地图上的每个“级别标记”顶部放置一个透明按钮,以便用户可以点击它。
推荐阅读
- cakephp - Cakephp 传递条件以包含抛出 InvalidArgumentException
- javascript - 如何使用 $GET 来调用弹出窗口
- tableau-api - 如何在 Tableau 中编写动态 sql 查询?
- c# - 如果该行包含特定元素 C# 如何从文本文件中删除该行
- javascript - 递归函数JS中级联的多个异步调用
- php - 选择用户确认删除(laravel)
- f# - F# 对 Range 和 Index 类型有特殊的语法吗?
- c# - 我如何使用 Jquery 在表中追加行?
- angular - Angular - 只能在 localhost 上访问的资产图像
- php - Laravel:使用 Linode 的存储对象作为 AWS S3 的替代品