swiftswiftui

Popover height doesn't fit content with multiline text


let texts = [
    "Long long long long long long long long long long text",
    "text",
    "text",
    "text",
    "LAST"
]

ZStack {}
.popover(isPresented: .constant(true), arrowEdge: .trailing) {
    ForEach(texts, id: \.self) { text in
        Text(text)
            .multilineTextAlignment(.leading)
            .fixedSize(horizontal: false, vertical: true) 
            // ^ no multiline without fixedSize, but height fits
    }
    .presentationCompactAdaptation(.popover)
}

Multiline text seems to require the .fixedSize modifier. Sadly it leads to the popover height no longer fitting the content:

enter image description here

Without the multiline, the height fits all items:

enter image description here

Any way to solve this and have multiline text and a popover height that fits its content?


Solution

  • A similar issue is also seen when using .popoverTip (see TipViewStyle layout broken in iOS 18.4 – Tip message gets truncated) and .contextMenu preview (see Sizing of SwiftUI's contextMenu preview).

    It happens because the popover determines its size based on the ideal size of its content. By default, the ideal size of Text is when the text is on one line.

    To fix, try setting a sensible idealWidth for the content:

    ZStack {}
        .popover(isPresented: .constant(true), arrowEdge: .trailing) {
            ForEach(Array(texts.enumerated()), id: \.offset) { offset, text in
                Text(text)
                    .multilineTextAlignment(.leading)
            }
            .frame(idealWidth: 200) // 👈 here
            .presentationCompactAdaptation(.popover)
        }
    

    Screenshot