Как заполнить высоту изображения до его родительского HStack?

Ответ на аналогичный вопрос для Android Compose был дан в этом посте . Мне было интересно, можно ли сделать то же самое для SwiftUI?

Пример:

HStack {
    VStack {
        ContentWithUnknownHeight()
        NextContentWithUnknownHeight()
    }
    .frame(width: geometry.size.width * 0.8)
    Image("User")
        .resizable()
        .frame(width: geometry.size.width * 0.2)
}
.frame(minHeight: 100)

Высота HStack не должна быть фиксированной, а должна увеличиваться, если это делают его дочерние элементы. Если VStack выше изображения, как я могу заполнить высоту изображения до высоты его родителя, не влияя на его высоту?

Что у меня есть:

Ожидаемый результат:

Как насчет того, чтобы поставить .fixedSize(horizontal: false, vertical: true) на HStack? В зависимости от того, что представляет собой желто-зеленый вид, вам потребуется выполнить с ним некоторые дополнительные действия. Для образа достаточно сделать resizable, и не стоит этого делать .scaledToFit().

Sweeper 19.05.2024 12:12

Я бы предложил отредактировать вопрос, чтобы было ясно, какой тип представления вы хотите расширить, чтобы заполнить стек. Различные взгляды ведут себя по-разному. Если вы имеете в виду Image, сделайте формулировку менее общей.

Sweeper 19.05.2024 12:16

@Sweeper Привет, спасибо! .fixedSize(horizontal: false, vertical: true) это действительно то, что я искал! Также спасибо за предложение - исправил мой вопрос и детали для ясности. Я понял, что scaledToFit неприменимо к моему случаю, поэтому удалил его, но scaleToFill сделал свое дело. Если вы также можете опубликовать ответ, я приму его.

6rchid 19.05.2024 23:53
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
90
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

HStack автоматически принимает рост самого высокого ребенка.

Однако ваш вопрос, похоже, больше касается высоты ребенка внутри HStack, и в вашем примере кода изображение находится в этой позиции. Предполагая, что вы действительно хотите масштабировать изображение для заполнения (в отличие от масштабирования по размеру, как это реализовано в коде), то один из способов — показать изображение в виде наложения поверх HStack:

  • Удалите модификатор .frame, который устанавливает фиксированную высоту для HStack.
  • Замените Image внутри HStack на Spacer.
  • Затем высоту HStack будет определять первый ребенок.
  • Примените наложение с помощью alignment: .trailing.
  • Наложение автоматически принимает рамку представления, к которому оно применяется, поэтому его высота также будет высотой первого дочернего элемента.
  • Масштабируйте изображение до заполнения, а затем обрезайте его до границ кадра.
HStack {
    VStack {
        SomeMoreContentWithUnknownHeight()
    }
    .frame(width: geometry.size.width * 0.8)
    Spacer()
}
.overlay(alignment: .trailing) {
    Image("User")
        .resizable()
        .scaledToFill()
        .frame(width: geometry.size.width * 0.2)
        .clipped()
}

Screenshot

Если SomeMoreContentWithUnknownHeight — единственный контент, оставшийся в HStack, то вам даже не нужно использовать HStack, вместо этого вы можете применить наложение непосредственно к этому контенту. Просто используйте отступы, чтобы зарезервировать место для содержимого наложения:

SomeMoreContentWithUnknownHeight()
    .frame(maxWidth: .infinity)
    .padding(.trailing, geometry.size.width * 0.2)
    .overlay(alignment: .trailing) {
        Image("User")
            .resizable()
            .scaledToFill()
            .frame(width: geometry.size.width * 0.2)
            .clipped()
    }
Ответ принят как подходящий

Чтобы HStack не вырастал выше, чем нужно самому высокому ребенку, добавьте

.fixedSize(horizontal: false, vertical: true)

в HStack.

Затем, если другие представления являются представлениями, которые естественным образом расширяются (например, Divider, Rectangle, Image(...).resizable()), они будут расширяться, автоматически заполняя высоту. Для изображения вы можете захотеть, чтобы оно было scaledToFill, как в ответе Бензи Низа.

Для представлений, которые не расширяются естественным образом, например Text, вы можете заставить их делать это, поместив их как наложение на какое-либо представление, которое расширяется естественным образом, плюс maxHeight: .infinity.

Color.clear // Colors naturally expand
    .overlay {
        Text("Foo")
            .frame(maxHeight: .infinity)
            .background(.yellow) // this background will fill the whole height
    }

Некоторые виды, такие как Button, могут нуждаться в специальной обработке, чтобы расширить область касания, а не только рамку. См. также SwiftUI: увеличение области касания/перетаскивания для взаимодействия с пользователем

Button("Foo") { /* ... */ }
    .frame(maxHeight: .infinity)
    .background(.yellow)
    .contentShape(Rectangle())

Другие вопросы по теме