Выровнять изображения с одинаковым размером и соотношением сторон заливки в SwiftUI

Я использую SwiftUI для создания виджета, и я борюсь с чем-то довольно простым и понятным в Swift.

У меня есть 2 изображения, которые находятся рядом друг с другом, и я хочу, чтобы они были одинакового размера с заливкой соотношения сторон, но без выхода за границы.

На данный момент это работает так: у меня есть представление, которое представляет собой изображение и текст. И затем родительский вид, у которого есть HStack с двумя из этих представлений.

В основном я хочу добиться этого представления, но с правильными изображениями:

введите описание изображения здесь

Делается это так:

VStack() {
        Image(uiImage: image)
            .resizable()
    
    Text(affirmation.title)
        .font(.body)
        .foregroundColor(Color(UIColor.MAPurple()))
    }
}

И для родительского представления:

HStack {
                Spacer()
                CardView(text: text, image: firstImage)
                Spacer()
                CardView(text: text, image: secondImage)
                Spacer()
            }

Если я добавлю соотношение сторон для заливки, как в Swift, это будет выглядеть так:

введите описание изображения здесь

Обновить

Добавляем минимально воспроизводимый пример:

struct CardView: View {
    let text: String
    let image: UIImage

    var body: some View {
        VStack(alignment: .leading) {
            Image(uiImage: image)
                .resizable()
                //                    .aspectRatio(contentMode: .fill)
                .clipped()
            
            Text(text)
                .font(.body)
                .multilineTextAlignment(.leading)
                .foregroundColor(Color.blue)
            
        }
    }
}
struct ParentView: View {
    let firstText: String = "This is something"
    let firstImage: UIImage
    let secondText: String = "This is something else"
    let secondImage: UIImage
    
    let top: String = "This is the top string"

    var body: some View {
        VStack {
            Spacer()
            Spacer()

            Text(top)
                .font(.largeTitle)
                .foregroundColor(Color(UIColor.MAPurple()))
                .padding(.all, 10)
                .minimumScaleFactor(0.4)
            
            Spacer()
            Spacer()

            HStack {
                Spacer()
                CardView(text: firstText, image: firstImage)
                Spacer()
                CardView(text: secondText, image: secondImage)
                Spacer()
            }
            Spacer()
            Spacer()
        }
        .background(Color.yellow)
        .edgesIgnoringSafeArea(.all)
    }
}

person Joan Cardona    schedule 07.08.2020    source источник
comment
Не могли бы вы предоставить минимальный воспроизводимый пример для отладки?   -  person Asperi    schedule 07.08.2020
comment
@Asperi сделано в конце вопроса   -  person Joan Cardona    schedule 07.08.2020


Ответы (1)


Правильная высота изображения решает проблему.

Разделенные горизонтальные изображения и текстовые просмотры отдельно. Поскольку высота текста может увеличиваться в зависимости от содержимого, но изображение должно быть правильно выровнено. Дана максимальная ширина Text, поскольку она не должна выходить за пределы Image ширины.

CardTextView выравнивает оба текста на HStack изображениях ниже

struct CardTextView: View {
    let text: String
    
    var body: some View {
        return Text(text)
            .font(.body)
            .multilineTextAlignment(.leading)
            .lineLimit(nil)
            .foregroundColor(Color.blue)
            .frame(minWidth: 0, maxWidth:170)
    }
}

CardImageView выравнивает оба изображения в HStack под основным заголовком

struct CardImageView: View {
    let image: UIImage

    var body: some View {
        return Image(uiImage: image)
        .resizable()
        .frame(width:170, height: 170)
        .cornerRadius(12)
    }
}

Наконец ParentView: добавлен интервал для VStack и HStack

struct ParentView: View {
    let firstText: String = "This is something"
    let firstImage: UIImage
    let secondText: String = "This is something else a looonnnnnggggg texttttttttttt"
    let secondImage: UIImage
    
    let top: String = "This is the top string"

    var body: some View {
        VStack(spacing: 12) {
            Text(top)
                .font(.title)
                .foregroundColor(Color(UIColor.purple))
                .padding(.top, 20)

            HStack(spacing: 12) {
                CardImageView(image: firstImage)
                CardImageView(image: secondImage)
            }
            
            HStack(spacing: 12) {
                CardTextView(text: firstText)
                CardTextView(text: secondText)
            }.padding(.bottom, 20)
           
        }.padding(16)
        .background(Color.yellow).cornerRadius(14)
    }
}

Я думаю, это то, чего вы ожидаете.

Окончательный результат

person Sona    schedule 15.08.2020