swift - How to make an iOS volume slider-like design element? - Stack Overflow

This is what I need to create:I need this element's value to be able to change with the user'

This is what I need to create:

I need this element's value to be able to change with the user's swipes.

I thought it was UISlider but it’s impossible to configure it the way I need:

 lazy var timeSlider : UISlider = {
        let slider = UISlider()
        slider.minimumValue = 1
        slider.maximumValue = 10
        slider.value = 1
        slider.layer.cornerRadius = 10
        slider.tintColor = UIColor(hexColor: "#F9F5EF")
        slider.addTarget(self, action: #selector(sliderValueChanged), for: .valueChanged)
        addSectionMarkers(for: slider)
        return slider
    }()

This is what I need to create:

I need this element's value to be able to change with the user's swipes.

I thought it was UISlider but it’s impossible to configure it the way I need:

 lazy var timeSlider : UISlider = {
        let slider = UISlider()
        slider.minimumValue = 1
        slider.maximumValue = 10
        slider.value = 1
        slider.layer.cornerRadius = 10
        slider.tintColor = UIColor(hexColor: "#F9F5EF")
        slider.addTarget(self, action: #selector(sliderValueChanged), for: .valueChanged)
        addSectionMarkers(for: slider)
        return slider
    }()
Share edited Mar 5 at 3:47 President James K. Polk 42.1k30 gold badges109 silver badges145 bronze badges asked Mar 4 at 12:27 GagenGagen 233 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

I think it would be easier to make your own using a UIStackView and UIPanGestureRecognizer instead of trying to inherit a UISlider.

Here's what I came up with:

CustomSliderView.swift:

import UIKit

final class CustomSliderView: UIView {
    
    // MARK: - Properties
    
    var progress: Int = 0 {
        didSet {
            progress = max(0, min(progress, sectionCount))
            updateProgress()
        }
    }
    
    private let sectionCount = 10
    private var sectionHeight: CGFloat = 0
    
    private var startProgress: Int = 0
    private var startTouchY: CGFloat = 0
    
    // MARK: - Views
    
    private let stackView = UIStackView()
    private let filledView = UIView()
    
    // MARK: - Init
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        commonInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        
        commonInit()
    }
    
    private func commonInit() {
        setupView()
        setupStackView()
        setupFilledView()
        addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:))))
    }
    
    // MARK: - Layout
    
    override func layoutSubviews() {
        super.layoutSubviews()
        sectionHeight = bounds.height / CGFloat(sectionCount)
        updateProgress()
    }
    
    private func setupView() {
        backgroundColor = .clear
        layer.cornerRadius = 10
        layer.masksToBounds = true
    }
    
    private func setupStackView() {
        stackView.axis = .vertical
        stackView.distribution = .fillEqually
        stackView.spacing = 1
        stackView.layer.cornerRadius = 10
        stackView.clipsToBounds = true
        
        addSubview(stackView)
        
        stackView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
            stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
            stackView.topAnchor.constraint(equalTo: topAnchor),
            stackView.bottomAnchor.constraint(equalTo: bottomAnchor)
        ])
        
        for _ in 0..<sectionCount {
            let view = UIView()
            view.backgroundColor = UIColor(white: 0.95, alpha: 1)
            stackView.addArrangedSubview(view)
        }
    }
    
    private func setupFilledView() {
        filledView.backgroundColor = UIColor.brown.withAlphaComponent(0.6)
        addSubview(filledView)
    }
    
    // MARK: - Actions
    
    private func updateProgress() {
        let sectionHeight = bounds.height / CGFloat(sectionCount)
        let height = CGFloat(progress) * sectionHeight
        filledView.frame = CGRect(
            x: 0,
            y: bounds.height - height,
            width: bounds.width,
            height: height
        )
    }
    
    @objc
    private func handlePan(_ gesture: UIPanGestureRecognizer) {
        let location = gesture.location(in: self)
        
        switch gesture.state {
        case .began:
            startTouchY = location.y
            startProgress = progress
            
        case .changed:
            let delta = startTouchY - location.y
            let newProgress = startProgress + Int(delta / sectionHeight)
            progress = newProgress
        default:
            break
        }
    }
}

Usage:

view.addSubview(customSlider)
customSlider.translatesAutoresizingMaskIntoConstraints = false
        
NSLayoutConstraint.activate([
    customSlider.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    customSlider.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    customSlider.widthAnchor.constraint(equalToConstant: 60),
    customSlider.heightAnchor.constraint(equalToConstant: 200)
])

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745043338a4607943.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信