下圖顯示了一個VStack三行文本。
位于VStackaZStack中,其中還包含一個藍色方塊。
我已經能夠定位藍色方塊,使其垂直中心等于Text顯示“第 1 行”的垂直中心。無論文本大小如何,都必須保持這種關系。換句話說,我不能硬編碼藍色方塊的垂直偏移的特定值,因為它取決于Text右側的大小。
注意文本上方和下方的綠線。這表示容器視圖的頂部和底部邊緣。
我想要做的(但不知道如何做)是將藍色方塊的前緣定位到與藍色方塊的頂部邊緣到頂部綠線的距離相同的位置。
例如,假設藍色框垂直放置后,它的頂部恰好從頂部的綠線向下 12 點。在這種情況下,盒子應該移動 12 點到容器左邊緣的右側。

這是我正在處理的代碼:
import SwiftUI
extension Alignment {
static let blueBoxAlignment = Alignment(horizontal: .blueBoxLeadingAlignment, vertical: .blueBoxCenterAlignment)
}
extension HorizontalAlignment {
private enum BlueBoxHorizontalAlignment: AlignmentID {
static func defaultValue(in d: ViewDimensions) -> CGFloat {
return d[HorizontalAlignment.leading]
}
}
static let blueBoxLeadingAlignment = HorizontalAlignment(BlueBoxHorizontalAlignment.self)
}
extension VerticalAlignment {
private enum BlueBoxCenterAlignment: AlignmentID {
static func defaultValue(in d: ViewDimensions) -> CGFloat {
return d[VerticalAlignment.center]
}
}
static let blueBoxCenterAlignment = VerticalAlignment(BlueBoxCenterAlignment.self)
}
struct TestView: View {
var body: some View {
ZStack(alignment: .blueBoxAlignment) {
VStack(spacing: 50) {
Text("Line 1")
.alignmentGuide(.blueBoxCenterAlignment) { d in d[VerticalAlignment.center] }
Text("Line 2")
Text("Line 3")
}
.padding([.top, .bottom], 50)
.frame(maxWidth: .infinity)
.border(.green)
Rectangle()
.fill(.blue)
.opacity(0.5)
.frame(width: 50, height: 50)
}
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
.edgesIgnoringSafeArea(.bottom)
}
}
uj5u.com熱心網友回復:
可能的方法是使用錨首選項,因為它們允許讀取目標視圖的不同位置屬性并在視圖布局周期內使用。
這是一個演示。使用 Xcode 13.2 / iOS 15.2 測驗

注意:使用padding代替offset,因為偏移量不影響布局,以防萬一。
struct PositionPreferenceKey: PreferenceKey { // << helper key !!
static var defaultValue: [Anchor<CGPoint>] = [] // << use something persistent
static func reduce(value: inout [Anchor<CGPoint>], nextValue: () -> [Anchor<CGPoint>]) {
value.append(contentsOf:nextValue())
}
}
struct TestView: View {
@State private var offset = CGFloat.zero
var body: some View {
ZStack(alignment: .blueBoxAlignment) {
VStack(spacing: 50) {
Text("Line 1")
.alignmentGuide(.blueBoxCenterAlignment) { d in d[VerticalAlignment.center] }
Text("Line 2")
Text("Line 3")
}
.padding([.top, .bottom], 50)
.frame(maxWidth: .infinity)
.border(.green)
Rectangle()
.fill(.blue)
.opacity(0.5)
.frame(width: 50, height: 50)
.anchorPreference(
key: PositionPreferenceKey.self,
value: .top // read position from top !!
) { [$0] }
.padding(.leading, offset) // << apply as X !!
}
.backgroundPreferenceValue(PositionPreferenceKey.self) { prefs in
GeometryReader { gr in
Color.clear.onAppear {
self.offset = gr[prefs[0]].y // << store Y !!
}
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/416306.html
標籤:
下一篇:如何有條件地將結構分配給變數?
