// // weightView.swift // anniversary_Project // // Created by 忆海16 on 2024/7/9. // import UIKit //let DISTANCELEFTANDRIGHT: CGFloat = 8.0 // 标尺左右距离 //let DISTANCEVALUE: CGFloat = 8.0 // 每隔刻度实际长度8个点 //let DISTANCETOPANDBOTTOM: CGFloat = 5.0 // 标尺上下距离 //class weightViewScrollView: UIScrollView { // // var maxValue: CGFloat = 500 // var minValue: CGFloat = 0 // var rulerAverage: CGFloat = 1 // // var rulerCount: Int { // return Int(maxValue - minValue) // } // // var isShowShortSymbol = true // var isSmallModel: Bool = true // // var binary: Int = 10 // var ruleFont = UIFont.systemFont(ofSize: 12) // // var longSymbolColor = UIColor.hexSting(color: "#B6BCC7", alpha: 1) { // didSet { // longSymbol.strokeColor = longSymbolColor.cgColor // } // } // var middleSymbolColor = UIColor.hexSting(color: "#B6BCC7", alpha: 1) { // didSet { // middleSymbol.strokeColor = middleSymbolColor.cgColor // } // } // var shortSymbolColor = UIColor.hexSting(color: "#B6BCC7", alpha: 1) { // didSet { // shortSymbol.strokeColor = shortSymbolColor.cgColor // } // } // // fileprivate lazy var longSymbol: CAShapeLayer = { // let shapeLayer = CAShapeLayer() // shapeLayer.strokeColor = longSymbolColor.cgColor // shapeLayer.fillColor = UIColor.clear.cgColor // shapeLayer.lineWidth = 3 // shapeLayer.lineCap = .round // return shapeLayer // }() // // fileprivate lazy var middleSymbol: CAShapeLayer = { // let shapeLayer = CAShapeLayer() // shapeLayer.strokeColor = middleSymbolColor.cgColor // shapeLayer.fillColor = UIColor.clear.cgColor // shapeLayer.lineWidth = 3 // shapeLayer.lineCap = .round // return shapeLayer // }() // // fileprivate lazy var shortSymbol: CAShapeLayer = { // let shapeLayer = CAShapeLayer() // shapeLayer.strokeColor = shortSymbolColor.cgColor // shapeLayer.fillColor = UIColor.clear.cgColor // shapeLayer.lineWidth = 3 // shapeLayer.lineCap = .round // return shapeLayer // }() // // override init(frame: CGRect) { // super.init(frame: frame) // setupSubviews() // } // // required init?(coder aDecoder: NSCoder) { // fatalError("init(coder:) has not been implemented") // } // // func setupSubviews() { // layer.addSublayer(shortSymbol) // layer.addSublayer(middleSymbol) // layer.addSublayer(longSymbol) // backgroundColor = UIColor.white // } // // func drawRuler() { // layer.sublayers?.forEach { (sublayer) in // if sublayer.isKind(of: CATextLayer.self) { // sublayer.removeFromSuperlayer() // } // } // // let longPathRef = CGMutablePath() // let middlePathRef = CGMutablePath() // let shortPathRef = CGMutablePath() // // for idx in 0 ... rulerCount { // let i = CGFloat(idx) // // let rule = CATextLayer() // rule.foregroundColor = UIColor.lightGray.cgColor // rule.font = ruleFont // rule.fontSize = ruleFont.pointSize // rule.contentsScale = UIScreen.main.scale // rule.string = String(format: "%.0f", (i + minValue) * rulerAverage) // // let textSize = (rule.string as! NSString).size(withAttributes: [NSAttributedString.Key.font: ruleFont]) // rule.bounds = CGRect(origin: CGPoint.zero, size: textSize) // // let xPos = DISTANCELEFTANDRIGHT + DISTANCEVALUE * i // // if idx % Int(binary) == 0 { // longPathRef.move(to: CGPoint(x: xPos, y: DISTANCETOPANDBOTTOM + textSize.height + 5)) // longPathRef.addLine(to: CGPoint(x: xPos, y: bounds.height - DISTANCETOPANDBOTTOM)) // rule.position = CGPoint(x: xPos, y: 5 + textSize.height / 2) // layer.addSublayer(rule) // // } else if idx % Int(binary / 2) == 0 { // middlePathRef.move(to: CGPoint(x: xPos, y: DISTANCETOPANDBOTTOM + textSize.height + 10)) // middlePathRef.addLine(to: CGPoint(x: xPos, y: bounds.height - DISTANCETOPANDBOTTOM)) // // } else if isShowShortSymbol { // shortPathRef.move(to: CGPoint(x: xPos, y: DISTANCETOPANDBOTTOM + textSize.height + 15)) // shortPathRef.addLine(to: CGPoint(x: xPos, y: bounds.height - DISTANCETOPANDBOTTOM)) // } // } // // longSymbol.path = longPathRef // // let longSymbolFrame = longSymbol.path?.boundingBoxOfPath ?? .zero // let longSymbolCenterY = longSymbolFrame.midY // // middleSymbol.path = middlePathRef // shortSymbol.path = shortPathRef // // middleSymbol.position.y += (longSymbolCenterY - (middlePathRef.boundingBoxOfPath.midY)) // shortSymbol.position.y += (longSymbolCenterY - (shortPathRef.boundingBoxOfPath.midY)) // // if isSmallModel { // contentInset = UIEdgeInsets(top: 0, left: bounds.width / 2 - DISTANCELEFTANDRIGHT, bottom: 0, right: bounds.width / 2 - DISTANCELEFTANDRIGHT) // contentOffset = CGPoint(x: DISTANCEVALUE * ((currentRulerValue - minValue) / rulerAverage) - bounds.width + (bounds.width / 2 + DISTANCELEFTANDRIGHT), y: 0) // } else { // contentOffset = CGPoint(x: DISTANCEVALUE * ((currentRulerValue - minValue) / rulerAverage) - bounds.width / 2.0 + DISTANCELEFTANDRIGHT, y: 0) // } // // contentSize = CGSize(width: CGFloat(rulerCount) * DISTANCEVALUE + DISTANCELEFTANDRIGHT * 2, height: bounds.height) // } // // // Computed property to get the current ruler value based on scroll position // var currentRulerValue: CGFloat { // let offsetX = contentOffset.x + bounds.size.width / 2 - DISTANCELEFTANDRIGHT // return (offsetX / DISTANCEVALUE) * rulerAverage + minValue // } //} // //protocol weightViewDelegate: AnyObject { // func sliderRulerView(ruler: UIView, rulervalue: CGFloat) // //} // //class weightRulerView: UIView { // // weak var delegate: weightViewDelegate? // // var valueLabelFont = UIFont.boldSystemFont(ofSize: 14) { // didSet { // valueLabel.font = valueLabelFont // } // } // // var rulerHeight: CGFloat = 50.0 { // didSet { // rulerScrollView.frame = CGRect(x: 0, y: frame.size.height - rulerHeight, width: frame.size.width, height: rulerHeight) // rulerScrollView.drawRuler() // } // } // // public var rulerScrollView = weightViewScrollView() // public let markLine = CALayer() // public let valueLabel = UILabel() // public let valueImageV = UIImageView() // public let TriangleimagV = UIImageView() // public let TriangtopleimagV = UIImageView() // //// var rulerValue: CGFloat { //// return rulerScrollView.rulerValue //// } // // override init(frame: CGRect) { // super.init(frame: frame) // rulerScrollView.frame = CGRect(x: 0, y: frame.size.height - rulerHeight, width: frame.size.width, height: rulerHeight) // rulerScrollView.showsHorizontalScrollIndicator = false // rulerScrollView.delegate = self // addSubview(rulerScrollView) // // // valueImageV.image = UIImage(named: "bgkg") // valueImageV.frame = CGRect(x: center.x - 119.5, y: rulerScrollView.frame.minY - 55, width: 239, height: 46) // addSubview(valueImageV) // // // TriangleimagV.image = UIImage(named: "buttonTriangle") // TriangleimagV.frame = CGRect(x: center.x - 11, y: rulerScrollView.frame.minY + 55, width: 22, height: 12) // addSubview(TriangleimagV) // // TriangtopleimagV.image = UIImage(named: "topTriangle") // TriangtopleimagV.frame = CGRect(x: center.x - 11, y: rulerScrollView.frame.maxY - 55, width: 22, height: 12) // addSubview(TriangtopleimagV) // // valueLabel.font = UIFont.boldSystemFont(ofSize: 24) // valueLabel.textAlignment = .center // valueLabel.textColor = UIColor.hexSting(color: "#62BFFF", alpha: 1) // valueLabel.frame = CGRect(x: 0, y: rulerScrollView.frame.minY - 44, width: bounds.width, height: 25) // valueLabel.text = "160 kg" // addSubview(valueLabel) // // } // // required init?(coder aDecoder: NSCoder) { // fatalError("init(coder:) has not been implemented") // } // // override func layoutSubviews() { // super.layoutSubviews() // rulerScrollView.drawRuler() // } // // func animationRebound() { // // Method intentionally left empty to remove snapping effect // } //} // //extension weightRulerView: UIScrollViewDelegate { // // func scrollViewDidScroll(_ scrollView: UIScrollView) { // // let offSetX = scrollView.contentOffset.x + bounds.size.width / 2 - DISTANCELEFTANDRIGHT // let ruleValue = (offSetX / DISTANCEVALUE) * rulerScrollView.rulerAverage // let valuetext = "\(round(ruleValue) + rulerScrollView.minValue) kg" // if valuetext != valueLabel.text { // valueLabel.text = valuetext // // } // } // // // func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { // // animationRebound() removed to prevent snapping // } // // func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { // // animationRebound() removed to prevent snapping // } //} import UIKit class weightViewScrollView: UIScrollView { // var onweightSelected: ((Int) -> Void)? var maxValue: CGFloat = 500 var minValue: CGFloat = 0 var rulerAverage: CGFloat = 1 var rulerCount: Int { return Int(maxValue - minValue) } var isShowShortSymbol = true var isSmallModel: Bool = true var binary: Int = 10 var ruleFont = UIFont.systemFont(ofSize: 12) var longSymbolColor = UIColor.hexSting(color: "#B6BCC7", alpha: 1) { didSet { longSymbol.strokeColor = longSymbolColor.cgColor } } var middleSymbolColor = UIColor.hexSting(color: "#B6BCC7", alpha: 1) { didSet { middleSymbol.strokeColor = middleSymbolColor.cgColor } } var shortSymbolColor = UIColor.hexSting(color: "#B6BCC7", alpha: 1) { didSet { shortSymbol.strokeColor = shortSymbolColor.cgColor } } fileprivate lazy var longSymbol: CAShapeLayer = { let shapeLayer = CAShapeLayer() shapeLayer.strokeColor = longSymbolColor.cgColor shapeLayer.fillColor = UIColor.clear.cgColor shapeLayer.lineWidth = 3 shapeLayer.lineCap = .round return shapeLayer }() fileprivate lazy var middleSymbol: CAShapeLayer = { let shapeLayer = CAShapeLayer() shapeLayer.strokeColor = middleSymbolColor.cgColor shapeLayer.fillColor = UIColor.clear.cgColor shapeLayer.lineWidth = 3 shapeLayer.lineCap = .round return shapeLayer }() fileprivate lazy var shortSymbol: CAShapeLayer = { let shapeLayer = CAShapeLayer() shapeLayer.strokeColor = shortSymbolColor.cgColor shapeLayer.fillColor = UIColor.clear.cgColor shapeLayer.lineWidth = 3 shapeLayer.lineCap = .round return shapeLayer }() override init(frame: CGRect) { super.init(frame: frame) setupSubviews() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func setupSubviews() { layer.addSublayer(shortSymbol) layer.addSublayer(middleSymbol) layer.addSublayer(longSymbol) backgroundColor = UIColor.white } func drawRuler() { layer.sublayers?.forEach { (sublayer) in if sublayer.isKind(of: CATextLayer.self) { sublayer.removeFromSuperlayer() } } let longPathRef = CGMutablePath() let middlePathRef = CGMutablePath() let shortPathRef = CGMutablePath() for idx in 0 ... rulerCount { let i = CGFloat(idx) let rule = CATextLayer() rule.foregroundColor = UIColor.lightGray.cgColor rule.font = ruleFont rule.fontSize = ruleFont.pointSize rule.contentsScale = UIScreen.main.scale rule.string = String(format: "%.0f", (i + minValue) * rulerAverage) let textSize = (rule.string as! NSString).size(withAttributes: [NSAttributedString.Key.font: ruleFont]) rule.bounds = CGRect(origin: CGPoint.zero, size: textSize) let xPos = DISTANCELEFTANDRIGHT + DISTANCEVALUE * i if idx % Int(binary) == 0 { longPathRef.move(to: CGPoint(x: xPos, y: DISTANCETOPANDBOTTOM + textSize.height + 5)) longPathRef.addLine(to: CGPoint(x: xPos, y: bounds.height - DISTANCETOPANDBOTTOM)) rule.position = CGPoint(x: xPos, y: 5 + textSize.height / 2) layer.addSublayer(rule) } else if idx % Int(binary / 2) == 0 { middlePathRef.move(to: CGPoint(x: xPos, y: DISTANCETOPANDBOTTOM + textSize.height + 10)) middlePathRef.addLine(to: CGPoint(x: xPos, y: bounds.height - DISTANCETOPANDBOTTOM)) } else if isShowShortSymbol { shortPathRef.move(to: CGPoint(x: xPos, y: DISTANCETOPANDBOTTOM + textSize.height + 15)) shortPathRef.addLine(to: CGPoint(x: xPos, y: bounds.height - DISTANCETOPANDBOTTOM)) } } longSymbol.path = longPathRef let longSymbolFrame = longSymbol.path?.boundingBoxOfPath ?? .zero let longSymbolCenterY = longSymbolFrame.midY middleSymbol.path = middlePathRef shortSymbol.path = shortPathRef middleSymbol.position.y += (longSymbolCenterY - (middlePathRef.boundingBoxOfPath.midY)) shortSymbol.position.y += (longSymbolCenterY - (shortPathRef.boundingBoxOfPath.midY)) if isSmallModel { contentInset = UIEdgeInsets(top: 0, left: bounds.width / 2 - DISTANCELEFTANDRIGHT, bottom: 0, right: bounds.width / 2 - DISTANCELEFTANDRIGHT) contentOffset = CGPoint(x: DISTANCEVALUE * ((currentRulerValue - minValue) / rulerAverage) - bounds.width + (bounds.width / 2 + DISTANCELEFTANDRIGHT), y: 0) } else { contentOffset = CGPoint(x: DISTANCEVALUE * ((currentRulerValue - minValue) / rulerAverage) - bounds.width / 2.0 + DISTANCELEFTANDRIGHT, y: 0) } contentSize = CGSize(width: CGFloat(rulerCount) * DISTANCEVALUE + DISTANCELEFTANDRIGHT * 2, height: bounds.height) } var currentRulerValue: CGFloat { let offsetX = contentOffset.x + bounds.size.width / 2 - DISTANCELEFTANDRIGHT // onweightSelected?(Int((offsetX / DISTANCEVALUE) * rulerAverage + minValue)) return (offsetX / DISTANCEVALUE) * rulerAverage + minValue } } protocol weightViewDelegate: AnyObject { func sliderRulerView(ruler: weightRulerView, rulervalue: CGFloat) } class weightRulerView: UIView { // var onweightSelected: ((Int) -> Void)? weak var delegate: weightViewDelegate? var valueLabelFont = UIFont.boldSystemFont(ofSize: 14) { didSet { valueLabel.font = valueLabelFont } } var rulerHeight: CGFloat = 50.0 { didSet { rulerScrollView.frame = CGRect(x: 0, y: frame.size.height - rulerHeight, width: frame.size.width, height: rulerHeight) rulerScrollView.drawRuler() } } public var rulerScrollView = weightViewScrollView() public let markLine = CALayer() public let valueLabel = UILabel() public let valueImageV = UIImageView() public let TriangleimagV = UIImageView() public let TriangtopleimagV = UIImageView() override init(frame: CGRect) { super.init(frame: frame) rulerScrollView.frame = CGRect(x: 0, y: frame.size.height - rulerHeight, width: frame.size.width, height: rulerHeight) rulerScrollView.showsHorizontalScrollIndicator = false rulerScrollView.delegate = self addSubview(rulerScrollView) valueImageV.image = UIImage(named: "bgkg") valueImageV.frame = CGRect(x: center.x - 119.5, y: rulerScrollView.frame.minY - 55, width: 239, height: 46) addSubview(valueImageV) TriangleimagV.image = UIImage(named: "buttonTriangle") TriangleimagV.frame = CGRect(x: center.x - 11, y: rulerScrollView.frame.minY + 55, width: 22, height: 12) addSubview(TriangleimagV) TriangtopleimagV.image = UIImage(named: "topTriangle") TriangtopleimagV.frame = CGRect(x: center.x - 11, y: rulerScrollView.frame.maxY - 55, width: 22, height: 12) addSubview(TriangtopleimagV) valueLabel.font = UIFont.boldSystemFont(ofSize: 24) valueLabel.textAlignment = .center valueLabel.textColor = UIColor.hexSting(color: "#62BFFF", alpha: 1) valueLabel.frame = CGRect(x: 0, y: rulerScrollView.frame.minY - 44, width: bounds.width, height: 25) valueLabel.text = "160 kg" addSubview(valueLabel) let defaults = UserDefaults.standard let weightint = Int(valueLabel.text!) defaults.set(weightint, forKey: "weight") } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func layoutSubviews() { super.layoutSubviews() rulerScrollView.drawRuler() } func animationRebound() { // Method intentionally left empty to remove snapping effect } } extension weightRulerView: UIScrollViewDelegate { func scrollViewDidScroll(_ scrollView: UIScrollView) { print("ScrollView did scroll") let offSetX = scrollView.contentOffset.x + bounds.size.width / 2 - DISTANCELEFTANDRIGHT let ruleValue = (offSetX / DISTANCEVALUE) * rulerScrollView.rulerAverage let valueText = "\(round(ruleValue) + rulerScrollView.minValue) kg" if valueText != valueLabel.text { valueLabel.text = valueText delegate?.sliderRulerView(ruler: self, rulervalue: ruleValue + rulerScrollView.minValue) } // onweightSelected?(Int(valueText) ?? 0) let defaults = UserDefaults.standard let currentRulerValue = rulerScrollView.currentRulerValue print("----\(currentRulerValue)") let weightint = Int(currentRulerValue) defaults.set(weightint, forKey: "weight") } func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { // animationRebound() removed to prevent snapping } func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { // animationRebound() removed to prevent snapping } }