Я новичок в SwiftUI. Я пытаюсь создать представление, подобное сердечной карточке, но не могу разместить vStack сердца и буквы в правом верхнем (topTrailing) углу прямоугольника.
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 5.0)
.fill(.white)
.stroke(.gray, style: StrokeStyle(lineWidth: 2.0))
.frame(width: 100, height: 150)
.shadow(color: Color(.black).opacity(0.3), radius: 5)
VStack(spacing: 0) {
Text("A")
.font(.callout)
Image(systemName: "heart.fill")
.resizable()
.frame(width: 10, height: 10)
}.frame(alignment: .topTrailing)
}
}
вот что я получаю на выходе.
Может кто-нибудь, пожалуйста, помогите.
Если вы хотите указать ZStack выровнять свои подвиды, вам нужно использовать свойство выравнивания ZStack, что-то вроде:
ZStack(alignment: topLeading) {
...
}
Вы можете попробовать этот альтернативный способ:
var body: some View {
RoundedRectangle(cornerRadius: 5.0)
.fill(.white)
.stroke(.gray, style: StrokeStyle(lineWidth: 2.0))
.frame(width: 100, height: 150)
.shadow(color: Color(.black).opacity(0.3), radius: 5)
.overlay(alignment: .topLeading) {
VStack(spacing: 0) {
Text("A")
.font(.callout)
Image(systemName: "heart.fill")
.resizable()
.frame(width: 10, height: 10)
}
.padding(5)
}
.overlay(alignment: .bottomTrailing) {
VStack(spacing: 0) {
Text("A")
.font(.callout)
Image(systemName: "heart.fill")
.resizable()
.frame(width: 10, height: 10)
}
.scaleEffect(CGSize(width: 1, height: -1)) //<- make the view up side down
.padding(5)
}
}
Выход:
Если вы добавите рамку к VStack
, вы увидите, как содержимое VStack
полностью заполняет его рамку:
VStack(spacing: 0) {
// as before
}
.frame(alignment: .topTrailing)
.border(.orange)
Модификатор .frame
выравнивает содержимое VStack
внутри рамки того же размера. Но поскольку контент уже заполняет кадр, это не имеет значения.
С этими изменениями можно заставить работать:
Переместите модификатор .frame
, задающий размер карточки, с RoundedRectangle
на ZStack
, который содержит все содержимое.
Добавьте maxWidth: .infinity, maxHeight: .infinity
к модификатору .frame
, установленному для VStack
, чтобы фрейм расширялся и использовал все доступное пространство.
Возможно, вы захотите добавить немного отступов к VStack
.
ZStack {
RoundedRectangle(cornerRadius: 5.0)
// as before, but without .frame
VStack(spacing: 0) {
// as before
}
.padding(8) // <- ADDED
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing) // <- maxWidth and maxHeight added
}
.frame(width: 100, height: 150) // <- moved from RoundedRectangle
Итак, это фиксирует размер ZStack
в соответствии с размером карты. RoundedRectangle
(как и любой Shape
) жадный, поэтому он расширяется, заполняя одно и то же пространство. Модификатор .frame
на VStack
теперь заставляет его расширяться до размера ZStack
, а параметр alignment
выравнивает содержимое так, как вы задумали.
или с рамкой на VStack
:
@Наташа Рада, что смогла помочь, спасибо, что приняли ответ. О двух вариантах .frame
: когда вы устанавливаете width
или height
, вы устанавливаете точный размер. Вот почему второй вариант на самом деле недействителен, потому что вы не можете использовать неконечное значение для width
или height
(если вы попробуете, то увидите ошибку в консоли). Но .infinity
можно использовать вместо maxWidth
и maxHeight
, и это позволит максимально расширить представление.
Спасибо вам за разъяснение. Однако у меня есть один вопрос: в чем разница между фреймом (maxWidth: .infinity, maxHeight: .infinity, выравнивание: .topTrailing) и фреймом (ширина: .infinity, высота: .infinity, выравнивание: .topTrailing)