1

我正在尝试在 UIKit 中实现一些非常容易的事情——一个视图始终位于中心(图像),第二个视图(文本)位于其顶部,两个视图之间有一些间距。我尝试了许多不同的方法(主要是使用alignmentGuide但没有任何我想要的方法)。

代码:

ZStack {
    Rectangle()
        .foregroundColor(Color.red)
    
    VStack {
        Text("Test")
            .padding([.bottom], 20) // I want to define spacing between two views
        
        Image(systemName: "circle")
            .resizable()
            .alignmentGuide(VerticalAlignment.center, computeValue: { value in
                value[VerticalAlignment.center] + value.height
            })
            .frame(width: 20, height: 20)
    }
}
.frame(width: 100, height: 100)

结果:

在此处输入图像描述

如您所见,图像不是完全居中的,它实际上取决于Text. 有没有办法强制垂直和水平对齐在超级视图和布局第二个视图中居中而不影响居中视图?

4

3 回答 3

4

我认为这样做的“正确”方法是定义自定义对齐方式:

extension VerticalAlignment {
    static var custom: VerticalAlignment {
        struct CustomAlignment: AlignmentID {
            static func defaultValue(in context: ViewDimensions) -> CGFloat {
                context[VerticalAlignment.center]
            }
        }
        return .init(CustomAlignment.self)
    }
}

然后,告诉您ZStack使用custom对齐方式,并使用在您的圆圈上alignmentGuide显式设置对齐方式:custom

PlaygroundPage.current.setLiveView(
    ZStack(alignment: .init(horizontal: .center, vertical: .custom)) {
        Color.white

        Rectangle()
            .fill(Color.red)
            .frame(width: 100, height: 100)

        VStack {
            Text("Test")
            Circle()
                .stroke(Color.white)
                .frame(width: 20, height: 20)
                .alignmentGuide(.custom, computeValue: { $0.height / 2 })
        }
    }
            .frame(width: 300, height: 300)
)

结果:

在此处输入图像描述

于 2020-08-07T15:32:44.740 回答
2

您可以Image通过将其移至来居中ZStack。然后.alignmentGuide申请Text

struct ContentView: View {
    var body: some View {
        ZStack {
            Rectangle()
                .foregroundColor(Color.red)

            Text("Test")
                .alignmentGuide(VerticalAlignment.center) { $0[.bottom] + $0.height }

            Image(systemName: "circle")
                .resizable()
                .frame(width: 20, height: 20)
        }
        .frame(width: 100, height: 100)
    }
}

请注意,当您明确指定宽度/高度时Image

Image(systemName: "circle")
    .resizable()
    .frame(width: 20, height: 20)

您也可以明确指定.alignmentGuide

.alignmentGuide(VerticalAlignment.center) { $0[.bottom] + 50 }
于 2020-08-07T14:29:48.660 回答
0

这是可能的替代方案,使用自动空间消耗功能

使用 Xcode 12 / iOS 14 测试

演示

struct ContentView: View {
    var body: some View {
        ZStack {
            Rectangle()
                .foregroundColor(Color.red)

            VStack(spacing: 0) {
                Color.clear
                    .overlay(
                        Text("Test").padding([.bottom], 10),
                        alignment: .bottom)

                Image(systemName: "circle")
                    .resizable()
                    .frame(width: 20, height: 20)

                Color.clear
            }
        }
        .frame(width: 100, height: 100)
    }
}

注意:在我用于此Spacer()目的之前,但在 Swift 2.0 中,spacer 似乎总是只是一个 spacer,即。没有任何东西可以附加到它 - 也许是错误。

于 2020-08-07T15:00:39.850 回答