在 iOS 16.4 中,我们现在可以在
.presentationCompactAdaptation(.none)
中使用 .popover
在 iOS 上实现真正的弹出窗口(紧凑的屏幕尺寸)。
SomeView()
.popover(isPresented: $isPopoverOpen) {
Text("Hello world!")
.fixedSize(horizontal: false, vertical: true)
.padding()
.presentationCompactAdaptation(.none)
}
这会给我们类似的东西:
太棒了,它按预期工作!
当弹出窗口中的
Text()
跨越多行时,就会出现问题。由于某种原因,弹出窗口的高度只会增长到一定高度(~3 行,带有非动态 .body
字体)。下面是使用一些 Lorem Ipsum 文本来说明该问题。请注意,由于弹出窗口高度太短,末端如何被剪掉:
如何使弹出框适合
Text()
内容?我可以静态定义高度,但我希望弹出窗口能够完美地适合内容。
您可以使用此方法获取文本元素的高度。
为此,您将获取文本的高度并设置您收到的高度。 这就是代码的样子
struct ContentLengthPreference: PreferenceKey {
static var defaultValue: CGFloat { 0 }
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = nextValue()
}
}
struct ContentView: View {
@State private var isPopoverOpen = true
@State var textHeight: CGFloat = 0 // <-- this
var body: some View {
Text("Hello, World!")
.popover(isPresented: $isPopoverOpen) {
Text("""
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
"""
)
.overlay(
GeometryReader { proxy in
Color
.clear
.preference(key: ContentLengthPreference.self,
value: proxy.size.height) // <-- this
}
)
.onPreferenceChange(ContentLengthPreference.self) { value in // <-- this
DispatchQueue.main.async {
print (value)
self.textHeight = value
}
}
.fixedSize(horizontal: false, vertical: true)
.frame(height: textHeight)
.padding()
.presentationCompactAdaptation(.none)
}
}
}
快乐编码!
你觉得这个怎么样?
您可以使用布局协议协商大小。
import SwiftUI
struct PopoverContainer: Layout {
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
guard subviews.count == 1 else {
fatalError("You need to implement your layout!")
}
var p = proposal
p.width = p.width ?? UIScreen.main.bounds.width
p.height = p.height ?? UIScreen.main.bounds.height
return subviews[0].sizeThatFits(p) // negotiates possible size
}
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
// entrusts default
}
}
struct ContentView: View {
@State private var isPopoverOpen = true
var body: some View {
Text("Hello, World!")
.popover(isPresented: $isPopoverOpen) {
PopoverContainer {
Text("""
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
"""
)
.fixedSize(horizontal: false, vertical: true)
.padding()
}
.presentationCompactAdaptation(.none)
}
}
}