首页 > 解决方案 > 开发基于屏幕大小的 SwiftUI 算法

问题描述

所以我有一个滑块,我有一个小的 VStack 框架,里面有一些文本,当你触摸滑块时我想移动它们(我希望 VStack 一直保持在滑块的正上方)。我不确定是否有更好的方法来做到这一点,所以我尝试通过使其依赖于滑块的值来调整 VStack 的前导填充。这是我的代码:

struct ViewName: View {
    @State private var sliderValue: Double = 0.0
    var body: some View {
        VStack {
        HStack {
            VStack {
                Text("t")
            }.frame(height: 30).background(Color.white)
             .padding(.leading, CGFloat(CGFloat(DayRangeValue) * (UIScreen.main.bounds.width * 0.7)/24) + ((UIScreen.main.bounds.width * 0.15) + 10))
             //The above padding is the algorithm: the addition of (UIScreen.main.bounds.width * 0.15 + 10) essentially works; it tells the VStack the starting position, and works on diff device simulators.
             Spacer()
        }
        Slider(value: $sliderValue, in: 0...23).frame(width: UIScreen.main.bounds.width * 0.7)
        //Note: the 0...23 cannot be changed, and the width of the slider is a percentage of screen size because I figured it can't be some static value, as that would only work on one device
    }
}
}

长话短说,我希望“t”在滑块上方,无论它在哪里;在任何设备上。上述填充算法目前在其中一款 iPad 模拟器上运行良好,但在 iPhone 8 模拟器上无法正常运行(例如)。如果有人可以帮助我找出适用于所有设备的基于屏幕尺寸的填充算法,那就太棒了。

标签: swiftalgorithmswiftuipadding

解决方案


如果我正确理解了您的意图,这是可能的解决方案(与几何无关)。使用 Xcode 11.4 / iOS 13.4 测试

演示

let kKnobWidth = CGFloat(24)

struct DemoLabelAboveSlider: View {
    var range: ClosedRange<Double> = 0...23

    @State private var sliderValue: Double = 0.0

    var body: some View {
        VStack(alignment: .leading) {
            Slider(value: self.$sliderValue, in: self.range)
                .padding(.vertical)
                .overlay(GeometryReader { gp in
                    Text("t")
                        .position(x: CGFloat(self.sliderValue) * (gp.size.width - kKnobWidth) / CGFloat(self.range.upperBound) + kKnobWidth / 2, y: 0)
                })
        }
        .padding(.horizontal) // << this one is only for better demo
    }
}

推荐阅读