Swiftui-仅显示视图的百分比

时间:2020-05-30 23:40:48

标签: ios swiftui

我有一个RoundedRectangle,我的目标是在其上放置另一个RoundedRectangle,使覆盖图显示“完成百分比”。不过,我似乎找不到合适的方法。

认为理想情况下,重叠广告应该以某种方式仅显示其自身的百分比。调整自身大小以匹配百分比会歪曲叠加层的形状。

import PlaygroundSupport

struct ContentView: View {

    @State private var value: Double = 0

    var body: some View {
        GeometryReader { geom in
            VStack {
                Slider(value: self.$value, in: 0...1, step: 0.01)

                ZStack {
                    ZStack(alignment: .leading) {

                        // The main rectangle
                        RoundedRectangle(cornerRadius: 10)
                            .fill(Color.blue)
                            .frame(width: geom.size.width,
                                   height: 200)

                        // The progress indicator...
                        RoundedRectangle(cornerRadius: 10)
                            .fill(Color.red)
                            .opacity(0.5)
                            .frame(width: CGFloat(self.value) * geom.size.width,
                                   height: 200)
                    }

                    Text("\(Int(self.value * 100)) %")
                }
            }
        }
        .padding()
    }
}

PlaygroundPage.current.setLiveView(ContentView())

在上面的游乐场中,如果您查看1、2甚至3%,则可以看到红色叠加层超出了左上和左下的蓝色背景矩形范围。参见下图。

Red overlay out of bounds...

我觉得这不是适当的解决方案,但我也找不到正确的组合(尝试scaleEffect,一堆offsetposition数学)真的很钉。

对我来说,就像我在上面说的那样,当值是0.4时,覆盖层应该能够说“仅使我最左边的40%可见”。

那太长了,对此我深表歉意。如果您已经读了那么多书,并且有任何建议要发表,我将非常感激。

谢谢!

2 个答案:

答案 0 :(得分:3)

如果我正确理解了您的担忧,请采取以下解决方案。在Xcode 11.4 / iOS 13.4上进行了测试。

demo

ZStack {
    ZStack(alignment: .leading) {

        // The main rectangle
        RoundedRectangle(cornerRadius: 10)
            .fill(Color.blue)
            .frame(width: geom.size.width,
                   height: 200)

        // The progress indicator...
        RoundedRectangle(cornerRadius: 10)
            .fill(Color.red)
            .opacity(0.5)
            .frame(width: CGFloat(self.value) * geom.size.width,
                   height: 200)
    }
    .clipShape(RoundedRectangle(cornerRadius: 10))    // << here !!

答案 1 :(得分:1)

这是我的处理方式,因此我不必管理多个cornerRadius

VStack {
    ZStack(alignment: .leading) {

        // The main rectangle
        Rectangle()
            .fill(Color.blue)
            .frame(width: geom.size.width,
                   height: 200)

        // The progress indicator...
        Rectangle()
            .fill(Color.red)
            .opacity(0.5)
            .frame(width: CGFloat(self.value) * geom.size.width,
                   height: 200)
    }
    .cornerRadius(10)