Search code examples
iosswiftuislider

how to use range slider with Dates instead of numbers in Swift?


I am looking at this implementation of range slider: https://github.com/warchimede/RangeSlider and I see that it has a lowerValue and upperValue set by default to 0.2 and 0.8:

@IBInspectable var lowerValue: Double = 0.2 {
    didSet {
        if lowerValue < minimumValue {
            lowerValue = minimumValue
        }
        updateLayerFrames()
    }
}

@IBInspectable var upperValue: Double = 0.8 {
    didSet {
        if upperValue > maximumValue {
            upperValue = maximumValue
        }
        updateLayerFrames()
    }
}

It also has minimumValue and maximumValue set to 0 and 1:

@IBInspectable var minimumValue: Double = 0.0 {
    willSet(newValue) {
        assert(newValue < maximumValue, "RangeSlider: minimumValue should be lower than maximumValue")
    }
    didSet {
        updateLayerFrames()
    }
}

@IBInspectable var maximumValue: Double = 1.0 {
    willSet(newValue) {
        assert(newValue > minimumValue, "RangeSlider: maximumValue should be greater than minimumValue")
    }
    didSet {
        updateLayerFrames()
    }
}

I would like to change the behavior of this slider so that it becomes range date picker - the maximumValue should be the current date and minimumValue some date in the past, e.g. 6 months before. Could you help me with that and give some hints whether it's possible to do so with this range slider?


Solution

  • This should do it.

    class ViewController: UIViewController {
    
        var slider:UISlider?
        // These number values represent each slider position
        let daysInPast = [14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] //Add your values here - this sets from two past weeks to current day
        let secondsPerDay = 86400
        var oldIndex = 0
    
        override func viewDidLoad() {
            super.viewDidLoad()
            slider = UISlider(frame: self.view.bounds)
            self.view.addSubview(slider!)
    
            // slider values go from 0 to the number of values in your numbers array
            var numberOfSteps = Float(numbers.count - 1)
            slider!.maximumValue = numberOfSteps;
            slider!.minimumValue = 0;
    
            // As the slider moves it will continously call the -valueChanged:
            slider!.continuous = true; // false makes it call only once you let go
            slider!.addTarget(self, action: "valueChanged:", forControlEvents: .ValueChanged)
        }
    
        func valueChanged(sender: UISlider) {
            // round the slider position to the nearest index of the numbers array
            var index = (Int)(slider!.value + 0.5);
            slider?.setValue(Float(index), animated: false)
            var dayInPast = daysInPast[index]; // <-- This numeric value you want
    
            if oldIndex != index {
    
                let today = NSDate() //today
                //every day value in the slider will be multiplied by number of seconds in day
                let pickedDate = today.dateByAddingTimeInterval(-secondsPerDay * dayInPast)
                let calendar = NSCalendar.currentCalendar()
                let components = calendar.components([.Month, .Year, .Day], fromDate: pickedDate)
                let month = components.month
                let year = components.year
                let day = components.day
    
                print("Date picked with slider is \(month)/\(day), \(year)")
    
                oldIndex = index
            }
        }
    }