我有一个视图,包含一个背景图/动画和前景的控制按钮。我想把按钮
但是,背景必须是一个动画。我在
这样就可以完美地垂直对齐-灰色顶部中央标记和底部中心按钮被渲染在正确的位置上- 然而,它会影响水平对齐。底部右侧按钮相对于视频对齐,而不是跟屏幕对齐,因此对齐超出了屏幕的范围(请参见第二张图片)。
我需要背景填满整个屏幕,并使覆盖层适当对齐。视频采用肖像录制,但
对我最有益的事情是学习如何相对于屏幕而不是父级在叠加堆栈中
代码
以下代码不是真正的代码,只是生成演示的代码。提供此代码是因为评论中有位绅士礼貌地要求它。图像是最终的真相来源。实际的代码要大得多,具有随机(和基于应用程序状态的)选择要播放的
.overlay
在背景上,在底部Leading、中心和Trailing对齐 - 请参见下面的截图(不显示实际背景)。但是,背景必须是一个动画。我在
AVPlayer
周围使用一个包装视图来处理这个问题。播放的视频是纵向的,但被填充为横向,因此宽度比屏幕更宽。我需要它填充屏幕的垂直空间。那意味着我必须使用.frame(maxWidth: .infinity, maxHeight: .infinity).scaledToFill()
。这样就可以完美地垂直对齐-灰色顶部中央标记和底部中心按钮被渲染在正确的位置上- 然而,它会影响水平对齐。底部右侧按钮相对于视频对齐,而不是跟屏幕对齐,因此对齐超出了屏幕的范围(请参见第二张图片)。
我需要背景填满整个屏幕,并使覆盖层适当对齐。视频采用肖像录制,但
AVPlayer
让它们以黑色填充的横向方式呈现,因此除非可以调整这一点,否则我无法更改视频的宽高比。对我最有益的事情是学习如何相对于屏幕而不是父级在叠加堆栈中
align components
。是否有一种方法可以实现这一点?如果没有,是否有解决我的问题的解决方案(使按钮水平对齐)?代码
以下代码不是真正的代码,只是生成演示的代码。提供此代码是因为评论中有位绅士礼貌地要求它。图像是最终的真相来源。实际的代码要大得多,具有随机(和基于应用程序状态的)选择要播放的
AVPlayer
mp4视频的机制。我认为这不应该很重要(封装和其他东西),但如果它很重要,请告诉我为什么它会影响代码结构,并在评论中添加更多细节。private func bigBgImage() -> some View {
self.backgroundChooser.render()
.resizable()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.scaledToFill()
}
在这里,backgroundChooser.render()
被视为黑盒子。你可以放入一个虚拟的 Image
。
期望的布局
通过在 GeometryReader
中使用虚拟图像来实现此演示。这是解决 bigBgImage
具有 maxWidth: .infinity
的覆盖范围的变通方法。由于 GeometryReader
会影响动画对齐,因此我不希望在最终代码中使用它。尽管如此,这是片段代码:
GeometryReader { _ in
self.bigBgImage()
}
.overlay(alignment: .top) { self.title() }
.overlay(alignment: .bottom) { self.resetButton() }
.overlay(alignment: .bottomTrailing) { self.toggleButton() }
布局有误
self.bigBgImage()
.overlay(alignment: .top) { self.title() }
.overlay(alignment: .bottom) { self.resetButton() }
.overlay(alignment: .bottomTrailing) { self.toggleButton() }
backgroundChooser
的机制过于复杂,无法在一个有意义的SO问题中予以说明。您只需随意添加任何图像即可。
maxWidth: .infinity
裁剪超出边缘的基础视图的情况下,前导/尾随对齐。请参见 @Asperi 的答案以使按钮正确对齐(使用带有background
和overlay
的虚拟视图)。这会破坏背景的对齐方式,我只能通过解决方法来解决 - 请参见我的答案。 - DrunkCoder