SwiftUIでListを使用していて
UITableViewCellのように各行をダイナミックな高さで表示をしようとする際に
layoutPriorityを使うと簡単に実現することができます。
https://developer.apple.com/documentation/swiftui/view/3278584-layoutpriority
実際に行っているのはQiitaAPIから取得したデータをリストに表示しています。
左側にユーザのアイコン
真ん中に記事のタイトルとユーザ名
右側に静的ないいねマークの画像といいねの数
を表示します。
まずはlayoutPriorityがない状態です。
struct QiitaView: View {
    let item: QiitaItemViewModel
    var body: some View {
        HStack {
            ImageLoadingView(loader: ImagePath(path: item.profileImageURL))
                .frame(width: 44, height: 44)
                .clipShape(Circle())
                .overlay(Circle().stroke(Color.white, lineWidth: 4))
                .shadow(radius: 10)
            VStack(alignment: .leading) {
                Text(item.title)
                    .lineLimit(nil)
                    .padding([.bottom], 12)
                Text(item.userName)
                    .lineLimit(nil)
            }
            .padding([.leading, .trailing], 12)
            Spacer()
            VStack(alignment: .center) {
                Image(systemName: "faceid")
                    .resizable()
                    .frame(width: 44, height: 44)
                Text("\(item.likesCount)")
            }
            .frame(width: 60)
        }
    }
}
真ん中のラベルの横幅は想定よりも狭くなってしまっています。
これをlayoutPriorityを用いて改善していきます。
まずは真ん中のVStackにlayoutPriorityを設定します。
layoutPriorityはデフォルトが0で
1を設定することで優先度を他よりも高くすることができます。
struct QiitaView: View {
    let item: QiitaItemViewModel
    var body: some View {
        HStack {
            ImageLoadingView(loader: ImagePath(path: item.profileImageURL))
                .frame(width: 44, height: 44)
                .clipShape(Circle())
                .overlay(Circle().stroke(Color.white, lineWidth: 4))
                .shadow(radius: 10)
            VStack(alignment: .leading) {
                Text(item.title)
                    .lineLimit(nil)
                    .padding([.bottom], 12)
                Text(item.userName)
                    .lineLimit(nil)
            }
            .padding([.leading, .trailing], 12)
            .layoutPriority(1) // ← ここに追加
            Spacer()
            VStack(alignment: .center) {
                Image(systemName: "faceid")
                    .resizable()
                    .frame(width: 44, height: 44)
                Text("\(item.likesCount)")
            }
            .frame(width: 60)
        }
    }
}
すると下記のイメージのような状態になります。
 
横幅は改善されました。
しかし、まだタイトルが切れてしまっている状態です。
そこでTextにもlayoutPriorityを設定します。
struct QiitaView: View {
    let item: QiitaItemViewModel
    var body: some View {
        HStack {
            ImageLoadingView(loader: ImagePath(path: item.profileImageURL))
                .frame(width: 44, height: 44)
                .clipShape(Circle())
                .overlay(Circle().stroke(Color.white, lineWidth: 4))
                .shadow(radius: 10)
            VStack(alignment: .leading) {
                Text(item.title)
                    .lineLimit(nil)
                    .padding([.bottom], 12)
                    .layoutPriority(1) // ← ここに追加
                Text(item.userName)
                    .lineLimit(nil)
            }
            .padding([.leading, .trailing], 12)
            .layoutPriority(1)
            Spacer()
            VStack(alignment: .center) {
                Image(systemName: "faceid")
                    .resizable()
                    .frame(width: 44, height: 44)
                Text("\(item.likesCount)")
            }
            .frame(width: 60)
        }
    }
}
すると下記のような形になります。
 
もし何か参考になりましたら幸いです。
逆に間違いや他に良い方法があれば
教えていただけると嬉しいです🙇🏻♂️
