Есть ли способ определить ширину моего изображения SwiftUI относительно размера экрана с помощью Geometry Reader?
Я работаю с образцом приложения, чтобы познакомиться со Swift и SwiftUI, и хочу объединить идеи составных макетов с использованием настраиваемых представлений и GeometryReader для определения размера экрана устройства.
Страница, которую я пытаюсь создать, представляет собой прокручиваемый список друзей, где каждый элемент строки представляет собой кнопку, которую можно выбрать, чтобы развернуть список, чтобы увидеть более подробную информацию о каждом друге. Я создал кнопку и все содержащие представления какFriendView
использовать внутри моего FriendListView
. Я определил 2GeometryReader
взгляды в FriendListView
но не знаю, как определить размер каждой строки из FriendView
чтобы сохранить соответствующий размер.
Необходимость в этом возникает из-за того, что не каждое изображение, которое пользователь может позже установить для своего друга, будет иметь одинаковые размеры, поэтому я хочу сохранить его согласованность. Я понимаю, что могу установить.frame()
модификатор и жестко закодируйте ширину, но я бы хотел, чтобы она относилась к экрану, чтобы она была единообразной на всех экранах телефонов.
Пример: если строка не развернута, изображение должно занимать половину ширины устройства. Когда он будет расширен, я бы хотел, чтобы он занимал четверть ширины экрана устройства.
Скриншот
Образец кода
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 ответ
Вы можете определить GeometryReader
на верхнем уровне FriendListView
и передайте ширину экрана в 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()
}