Я работаю над сложным пользовательским интерфейсом, и при попытке его создания постоянно сталкиваюсь с проблемами. Во-первых, это мой текущий код:
var body: some View {
HStack {
VStack (alignment: .leading) {
if showNewBadge {
NewBadge(title: "NEW")
}
Text("jfsdbf hjksdb fhjkdsb ")
.dynamicFont(.Cloud9.paragraph)
.lineLimit(2)
if let subtext {
Text("djfb dsjhbf jsdhk fbjsdhk fbjdshkf bjs")
.dynamicFont(.Cloud9.caption)
.lineLimit(3)
}
if let parterLogoUrl {
KFImage(parterLogoUrl)
.useHatchFade()
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 65, height: 20)
.clipped()
}
if showCTA {
Button(action: tapOnCTAAction, label: {
Label("Listen Now", systemImage: "play")
})
.buttonStyle(.outlineSmall)
}
}
.padding(.leading)
if let parterLogoUrl {
KFImage.url(parterLogoUrl)
.resizable()
.aspectRatio(contentMode: .fit)
.overlay(
LinearGradient(gradient: Gradient(colors: [Color.black.opacity(0.5), Color.clear]), startPoint: .leading, endPoint: .trailing)
)
}
}
.background(
RoundedRectangle(cornerRadius: .cornerRadiusDefault)
.foregroundColor(.blue))
}
Теперь я объясню, в чем заключаются проблемы и чего я хочу достичь. Итак, первая проблема заключается в том, что на изображении, которое находится в правой части HStack, я хочу, чтобы оно занимало всю высоту контейнера и половину его ширины. Я попробовал использовать программу чтения геометрии, но градиент вышел за пределы. Если кто-то знает, как заставить его работать с программой чтения геометрии, я был бы признателен. Во-вторых, я пытаюсь заставить изображение медленно смешиваться по мере его перемещения влево к центру с цветом фона. Под смешиванием я имею в виду, что он может постепенно исчезать, поэтому мы начинаем видеть цвет фона только после того, как достигнем центра.
Конечная цель — получить карточку, в правой половине которой есть изображение, а в левой — некоторая информация. Изображение медленно исчезает по мере продвижения к центру. Информация и изображение занимают половину ширины карты. Если мой подход не идеален, пожалуйста, дайте мне знать.
Спасибо.





Соотношение сторон вашего изображения сбивает с толку. Если вы установите ширину вашего HStack и изображения на половину размера читателя геометрии, это сбалансирует ситуацию. Когда вы меняете размер контейнера и соотношение изображения становится проблематичным, оно центрирует изображение в контейнере, оставляя пустое пространство слева и справа. Проще всего .fillваше изображение вместо .fit.
Если вам нужно использовать изображение .fit, я бы предложил присвоить вашему HStack фиксированную высоту, которая вам подходит.
Чтобы смешать градиент, просто установите первый цвет градиента в соответствии с цветом фона.
GeometryReader { geo in
HStack {
VStack (alignment: .leading) {
if showNewBadge {
NewBadge(title: "NEW")
}
Text("jfsdbf hjksdb fhjkdsb ")
.lineLimit(2)
Text("djfb dsjhbf jsdhk fbjsdhk fbjdshkf bjs")
.lineLimit(3)
Text("@") // logo
Button("Listen Now") {
print("some action")
}
}
.padding(.leading)
.frame(width: geo.size.width / 2) // set width, not height.
HStack {
Spacer() // when the radio mixes things up...push to end
Image("demos")
.resizable()
// .aspectRatio(contentMode: .fit) // <- the aspect ratio is whats making it difficult to calculate.
.aspectRatio(contentMode: .fill)
.overlay(
LinearGradient(gradient: Gradient(colors: [Color.blue, Color.clear]), startPoint: .leading, endPoint: .trailing)
)
// set width, not height.
}.frame(width: geo.size.width / 2)
}
// fixed height here
.background(.blue)
.mask(RoundedRectangle(cornerRadius: 10)) // rounds off image too!
}
А как насчет установки высоты HStack на половину ширины? Таким образом, изображение будет квадратным и может предотвратить его взрыв. .frame(высота: geo.size.width / 2)
Это решает проблему, спасибо!
Большое спасибо за подробный ответ. На самом деле я предпочитаю использовать .fill, но когда я это делаю, карточка занимает весь экран. Даже сейчас, когда я скопировал и вставил ваш код, та же проблема возникла с .fill, и весь экран стал цветом фона.