繁体   English   中英

如何实现一个 slider,它的最小轨道颜色是从 SwiftUI 中没有离开的中心(值=0)开始的

[英]How to implement a slider whose minimum track color is begin from center(value=0) not left in SwiftUI

我想在SwiftUI中自定义Slider,就这样吧。

在此处输入图像描述

我用 GeometryReader 尝试了 Slider 但它不起作用。

//MARK: Left - Right Balance
GeometryReader { geo in
    VStack {
        Text("\(String(format: "%.2f", balanceVolume))")
        HStack {
            Text("L")
            Slider(value: $balanceVolume, in: minValue...maxValue, step: 0.1) {editing in
                print("editing", editing)
                isEditing = editing
                if !editing {
                    player.pan = Float(balanceVolume)
                }
             }
             .tint(.none)
             .accentColor(.gray)
             Text("R")
        }
     }
     .padding(20)
}

谢谢大家。

我创建了一个简单的自定义 slider,希望对您有所帮助

Output: 在此处输入图像描述

利用:

struct slider: View {
    @State var sliderPosition: Float = 50
    var body: some View {
        SliderView(value: $sliderPosition, bounds: 1...100).padding(.all)
        
    }
}

代码:

struct SliderView: View {
    let currentValue: Binding<Float>
    let sliderBounds: ClosedRange<Int>
    
    public init(value: Binding<Float>, bounds: ClosedRange<Int>) {
        self.currentValue = value
        self.sliderBounds = bounds
    }
    
    var body: some View {
        GeometryReader { geomentry in
            sliderView(sliderSize: geomentry.size)
        }
    }
    
    
    @ViewBuilder private func sliderView(sliderSize: CGSize) -> some View {
        let sliderViewYCenter = sliderSize.height / 2
        let sliderViewXCenter = sliderSize.width / 2
        ZStack {
            RoundedRectangle(cornerRadius: 2)
                .fill(Color.gray)
                .frame(height: 3)
            ZStack {
                let sliderBoundDifference = sliderBounds.count
                let stepWidthInPixel = CGFloat(sliderSize.width) / CGFloat(sliderBoundDifference)
                
                
                let thumbLocation = CGFloat(currentValue.wrappedValue) * stepWidthInPixel
                
                // Path between starting point to thumb
                lineBetweenThumbs(from: .init(x: sliderViewXCenter, y: sliderViewYCenter), to: .init(x: thumbLocation, y: sliderViewYCenter))
                
                // Thumb Handle
                let thumbPoint = CGPoint(x: thumbLocation, y: sliderViewYCenter)
                thumbView(position: thumbPoint, value: Float(currentValue.wrappedValue))
                    .highPriorityGesture(DragGesture().onChanged { dragValue in
                        
                        let dragLocation = dragValue.location
                        let xThumbOffset = min(dragLocation.x, sliderSize.width)
                        
                        let newValue = Float(sliderBounds.lowerBound / sliderBounds.upperBound) + Float(xThumbOffset / stepWidthInPixel)
                        if newValue > Float(sliderBounds.lowerBound) && newValue < Float(sliderBounds.upperBound + 1) {
                            currentValue.wrappedValue = newValue
                            
                        }
                    })
                
                
            }
        }
    }
    
    @ViewBuilder func lineBetweenThumbs(from: CGPoint, to: CGPoint) -> some View {
        Path { path in
            path.move(to: from)
            path.addLine(to: to)
        }.stroke(Color.blue, lineWidth: 4)
    }
    
    @ViewBuilder func thumbView(position: CGPoint, value: Float) -> some View {
        ZStack {
            Text(String(round(value)))
                .font(.headline)
                .offset(y: -20)
            Circle()
                .frame(width: 24, height: 24)
                .foregroundColor(.accentColor)
                .shadow(color: Color.black.opacity(0.16), radius: 8, x: 0, y: 2)
                .contentShape(Rectangle())
        }
        .position(x: position.x, y: position.y)
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM