I believe this is because the behaviour of the arrowEdge
parameter (which has a default value of .top
which shows the popover below) in popover(isPresented:attachmentAnchor:arrowEdge:content:)
changed with the iOS 18 SDK. In iOS 17, it is used as a hint and is ignored if the content doesn’t fit, while on iOS 18 it is always used. There is a new popover(isPresented:attachmentAnchor:content:)
modifier available on iOS 18 which automatically chooses an edge, but this isn’t always available when the minimum deployment target is <iOS 18 and thus is not the overload selected by the complier.
You can work around it with this extension, where the compiler will select the new modifier on the iOS 18 branch and the old one on the other one.
extension View {
@ViewBuilder func autoEdgePopover<Content: View>(
isPresented: Binding<Bool>,
attachmentAnchor: PopoverAttachmentAnchor = .rect(.bounds),
@ViewBuilder content: @escaping () -> Content
) -> some View {
if #available(iOS 18, *) {
self
.popover(isPresented: isPresented, attachmentAnchor: attachmentAnchor, content: content)
} else {
self
.popover(isPresented: isPresented, attachmentAnchor: attachmentAnchor, content: content)
}
}
}