有没有办法使用几何阅读器将我的 SwiftUI 图像的宽度定义为相对于屏幕尺寸?
Posted
技术标签:
【中文标题】有没有办法使用几何阅读器将我的 SwiftUI 图像的宽度定义为相对于屏幕尺寸?【英文标题】:Is there a way to define the width of my SwiftUI Image to be relative to screen size using Geometry Reader? 【发布时间】:2020-06-13 14:32:03 【问题描述】:我正在通过一个示例应用程序来熟悉 Swift 和 SwiftUI,并且我想结合使用自定义视图和 GeometryReader 的复合布局的想法来确定设备的屏幕大小。
我正在尝试构建的页面是一个可滚动的朋友列表,其中每个行项都是一个按钮,可以选择该按钮来展开列表以查看每个朋友的更多详细信息。我已经将按钮和所有包含视图构建为FriendView
,以便在我的FriendListView
内部使用。我在FriendListView
中定义了2 个GeometryReader
视图,但不知道如何从FriendView
中定义每一行的大小以使其保持适当的大小。
对此的需求来自于并非用户稍后可以为其朋友设置的每张图片都具有相同的尺寸,因此我希望保持一致。我知道我可以设置 .frame()
修饰符并对宽度进行硬编码,但我希望它与屏幕相关,以便在所有手机屏幕上保持一致。
示例:当一行未展开时,图像应占设备宽度的一半。当它展开时,我希望它占据设备屏幕宽度的四分之一。
截图
Application View
示例代码
struct FriendListView: View
var pets = ["Woofer", "Floofer", "Booper"]
var body: some View
GeometryReader geo1 in
NavigationView
GeometryReader geo2 in
List(self.pets, id: \.self) pet in
FriendView(name: pet)
// End of List
.navigationBarTitle(Text("Furiends"))
// End of NavigationView
// End of GeometryReader geo1
// End of body
struct FriendView: View
@State private var isExpanded = false
var randomPic = Int.random(in: 1...2)
var name = ""
var breed = "Dawg"
var body: some View
Button(action: self.toggleExpand)
HStack
VStack
Image("dog\(self.randomPic)")
.resizable()
.renderingMode(.original)
.scaledToFill()
.clipShape(Circle())
if self.isExpanded == false
Text(self.name)
.font(.title)
.foregroundColor(.primary)
if self.isExpanded == true
VStack
Text(self.name).font(.title)
Text(self.breed).font(.headline)
.foregroundColor(.primary)
// End of Button
func toggleExpand()
isExpanded.toggle()
【问题讨论】:
【参考方案1】:您可以在顶层FriendListView
中定义一个GeometryReader
并将屏幕宽度传递给FriendView
:
struct FriendListView: View
var pets = ["Woofer", "Floofer", "Booper"]
var body: some View
GeometryReader geo in
NavigationView
List(self.pets, id: \.self) pet in
FriendView(name: pet, screenWidth: geo.size.width)
.navigationBarTitle(Text("Furiends"))
然后使用.frame
设置图像的最大宽度。
struct FriendView: View
...
var screenWidth: CGFloat
var imageWidth: CGFloat
isExpanded ? screenWidth / 4 : screenWidth / 2
var body: some View
Button(action: self.toggleExpand)
HStack
VStack
Image("dog\(self.randomPic)")
.resizable()
.renderingMode(.original)
.scaledToFill()
.clipShape(Circle())
.frame(width: imageWidth, height: imageWidth) // <- add frame boundaries
if self.isExpanded == false
Text(self.name)
.font(.title)
.foregroundColor(.primary)
if self.isExpanded == true
VStack
Text(self.name).font(.title)
Text(self.breed).font(.headline)
.foregroundColor(.primary)
func toggleExpand()
isExpanded.toggle()
如果您希望图片居中,可以使用Spacer
:
HStack
Spacer()
FriendView(name: pet, screenWidth: geo.size.width)
Spacer()
【讨论】:
这有助于我理解如何将宽度传递到新视图中。我在框架修改器中尝试了不同的参数,包括您提供的参数,但图像仍然呈现为不同的宽度。关于我应该如何构建框架修改器的任何建议? 我不确定...我提供的示例已经过测试,它对我有用。我选择了两张图片(一张正方形和一张长方形)。在上面的视图中,两者的大小相同。您是尝试了我的整个代码还是部分代码? (我只使用了一个 GeometryReader)。 是的,我删除了额外的 GeometryReader,并认为它与 clipShape 有关。与我在原始帖子中的屏幕截图相同的行为。如果您想尝试使用这些确切的图片,我已将所有文件上传到 repo。 github.com/MichaelWDanko/furiends 是的,这是正确的。我看到圆形的细微差别。抱歉,如果我没有解释清楚。感谢帮助 太棒了!我确实必须将其更改为使用width:height
与maxWidth:maxHeight
,但我终于能够排队了。我知道这是一个小调整,但感谢您的帮助。我将您的答案标记为解决此问题的答案。以上是关于有没有办法使用几何阅读器将我的 SwiftUI 图像的宽度定义为相对于屏幕尺寸?的主要内容,如果未能解决你的问题,请参考以下文章