123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- //
- // CircularSliderView.swift
- // fiveConstant
- //
- // Created by 李建 on 2023/2/6.
- //
- // 弧形温度调节组件
- import SwiftUI
- struct CircularSliderView: View {
- @State var roomInfo: RoomInfo
- @State var temperatureValue: CGFloat
- @State var angleValue: CGFloat
- var onSetValue: ((Int)->Void)?
- let config = Config(minimumValue: 0,
- maximumValue: 14,
- totalValue: 14.0,
- knobRadius: 18.0,
- radius: 105.0)
- init(roomInfo: RoomInfo) {
- self.roomInfo = roomInfo
- let value = CGFloat(roomInfo.set_temp!)
- self.temperatureValue = value
- let fixAngle = (value - 16) / config.totalValue * (270 * .pi / 180)
- self.angleValue = fixAngle * 180 / .pi
- }
- var body: some View {
- ZStack {
- Circle()
- .trim(from: 0.125, to: 0.875)
- .stroke(roomInfo.power! ? Color("MainColor") : Color(hex: 0xF0F5F6, alpha: 1), lineWidth: 20)
- .frame(width: config.radius * 2, height: config.radius * 2)
- .rotationEffect(.degrees(90))
-
- ZStack {
- Circle()
- .fill(Color.white)
- .frame(width: config.knobRadius * 2, height: config.knobRadius * 2)
- .padding(10)
- .shadow(radius: 11, y: 5)
- .offset(y: -config.radius)
- .rotationEffect(Angle.degrees(angleValue))
- .zIndex(5)
- .gesture(DragGesture(minimumDistance: 0.0)
- .onChanged({ value in
- change(location: value.location)
- })
- .onEnded({ _ in
- self.onSetValue!(Int(temperatureValue))
- })
- )
- Circle()
- .fill(Color("MainColor"))
- .frame(width: 12, height: 12)
- .offset(y: -config.radius)
- .zIndex(6)
- .rotationEffect(Angle.degrees(angleValue))
- // 两头的小圆点
- Circle()
- .fill(roomInfo.power! ? Color("MainColor") : Color(hex: 0xF0F5F6, alpha: 1))
- .frame(width: 19, height: 19)
- .offset(y: -config.radius)
- Circle()
- .fill(roomInfo.power! ? Color("MainColor") : Color(hex: 0xF0F5F6, alpha: 1))
- .frame(width: 19, height: 19)
- .offset(y: -config.radius)
- .rotationEffect(Angle.degrees(270))
-
- }
- .rotationEffect(.degrees(225)) //
- HStack(spacing:0) {
- Text("\(String.init(format: "%.f", temperatureValue))")
- .font(.system(size: 60))
- .foregroundColor(Color("SecondColor"))
- .bold()
- Text("℃").font(.system(size: 20)).padding(.bottom, 30)
- }
- }
- }
- private func change(location: CGPoint) {
-
- let vector = CGVector(dx: location.x, dy: location.y)
- let angle = atan2(vector.dy - (config.knobRadius + 10), vector.dx - (config.knobRadius + 10)) + .pi/2.0
- let fixedAngle = angle < 0.0 ? angle + 2.0 * .pi : angle
- let value = fixedAngle / (270 * .pi / 180) * config.totalValue
- if value >= config.minimumValue && value <= config.maximumValue {
- temperatureValue = value + 16
- angleValue = fixedAngle * 180 / .pi
- }
- }
-
- }
- extension CircularSliderView {
- func onDragEnd(perform action: @escaping (Int)->Void) ->Self {
- var copy = self
- copy.onSetValue = action
- return copy
- }
- }
- struct Config {
- let minimumValue: CGFloat
- let maximumValue: CGFloat
- let totalValue: CGFloat
- let knobRadius: CGFloat
- let radius: CGFloat
- }
- struct CircularSliderView_Previews: PreviewProvider {
- static let json = """
- {"record_id":"1t7svi03170copjp9iimtd3z005isbfj","name":"样板间","home_id":"1t7svi01jj7copaplj7q47n170kd6hw6","home_name":"李建的家","is_master":true,"control_number":"1","user_id":"","power":true,"set_temp":21,"air_quality":0,"co2":0,"temperature":7,"humidity":0,"mode":2,"fan_speed":4,"fan_value":1,"timer_status":false,"duration":0}
- """.data(using: .utf8)!
- static var previews: some View {
- let decoder = JSONDecoder()
- let product = try? decoder.decode(RoomInfo.self, from: json)
- CircularSliderView(roomInfo: product!)
- }
- }
|