SwiftUI获取对象以响应另一个对象的大小

时间:2019-12-04 16:05:35

标签: swiftui

我正在设计音乐播放器,然后从情节提要界面转移到SwiftUI。我希望时间显示为沿着轨迹图稿底部边缘的进度条(白线)。在大尺寸的画布上,它们都处于一条直线上,因为它们都可以伸展减去两边的空白边距20。但是,使用较小的画布时,会发生以下问题。将作品缩小以适合所有其他视图,而进度条(高度为2的矩形)保持较大。如何设置该矩形,以便如果我的作品变小,则条形也变小?

这是我的代码:

struct PlayerArtwork: View {
    var body: some View {
        VStack {
            ZStack(alignment: .bottom) {
                        Image("Pumpy Artwork")
                                .resizable()
                            .aspectRatio(contentMode: .fit)
                        ProgressBar()
            }
            .padding([.top, .leading, .trailing], 20.0)
            HStack {
                Text("0:00")
                .foregroundColor(Color.white)
                Spacer()
                Text("3:52")
                .foregroundColor(Color.white)
            }
            .padding([.leading, .bottom, .trailing], 20.0)
        }
    }
}

struct ProgressBar: View {
    var body: some View {
        ZStack {
            Rectangle()
                .fill(Color.gray)
            .frame(height: 2)

            Rectangle()
                .fill(Color.white)
                .frame(height: 2)
        }
    }
}

1 个答案:

答案 0 :(得分:1)

在这里可以使用alignmentGuide。这个想法是根据您的情况ProgressBar通过从可用于对齐指南的尺寸中获取的宽度来更新一个视图的宽度。

注意:也许您应该对时间标签进行相同的设置,但这取决于您

struct PlayerArtwork: View {
    @State private var boundWidth: CGFloat = 10.0 // any initial value
    var body: some View {
        VStack {
            ZStack(alignment: .bottom) {
                Image("Pumpy Artwork")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .alignmentGuide(.bottom, computeValue: { d in
                        DispatchQueue.main.async {
                            self.boundWidth = d.width // avoid change state during update
                        }
                        return d[.bottom]
                    })
                ProgressBar()
                    .frame(width: self.boundWidth)
            }
            .padding([.top, .leading, .trailing], 20.0)
            HStack {
                Text("0:00")
                    .foregroundColor(Color.white)
                Spacer()
                Text("3:52")
                    .foregroundColor(Color.white)
            }
            .padding([.leading, .bottom, .trailing], 20.0)
        }
    }
}