UIDatePicker select Month and Year

前端 未结 11 1740
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-27 04:00

I need a UIDatePicker for selecting Month and Year only. I checked the class reference documents. Looks like UIDatePicker is a UIView.

相关标签:
11条回答
  • 2020-11-27 04:15

    I rewrote Igor's answer in Swift:

    class CLIVEDatePickerView: UIPickerView  {
    
        enum Component: Int {
            case Month = 0
            case Year = 1
        }
    
        let LABEL_TAG = 43
        let bigRowCount = 1000
        let numberOfComponentsRequired = 2
    
        let months = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"]
        var years: [String] {
            get {
                var years: [String] = [String]()
    
                for i in minYear...maxYear {
                    years.append("\(i)")
                }
    
                return years;
            }
        }
    
        var bigRowMonthsCount: Int {
            get {
                return bigRowCount * months.count
            }
        }
    
        var bigRowYearsCount: Int {
            get {
                return bigRowCount * years.count
            }
        }
    
        var monthSelectedTextColor: UIColor?
        var monthTextColor: UIColor?
        var yearSelectedTextColor: UIColor?
        var yearTextColor: UIColor?
        var monthSelectedFont: UIFont?
        var monthFont: UIFont?
        var yearSelectedFont: UIFont?
        var yearFont: UIFont?
    
        let rowHeight: NSInteger = 44
    
        /**
         Will be returned in user's current TimeZone settings
        **/
        var date: NSDate {
            get {
                let month = self.months[selectedRowInComponent(Component.Month.rawValue) % months.count]
                let year = self.years[selectedRowInComponent(Component.Year.rawValue) % years.count]
                let formatter = NSDateFormatter()
                formatter.dateFormat = "MM yyyy"
                return formatter.dateFromString("\(month) \(year)")!
            }
        }
    
        var minYear: Int!
        var maxYear: Int!
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            loadDefaultParameters()
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            loadDefaultParameters()
        }
        override func awakeFromNib() {
            super.awakeFromNib()
            loadDefaultParameters()
        }
    
        func loadDefaultParameters() {
            minYear = NSCalendar.currentCalendar().components(NSCalendarUnit.Year, fromDate: NSDate()).year
            maxYear = minYear! + 10
    
            self.delegate = self
            self.dataSource = self
    
            monthSelectedTextColor = UIColor.blueColor()
            monthTextColor = UIColor.blackColor()
    
            yearSelectedTextColor = UIColor.blueColor()
            yearTextColor = UIColor.blackColor()
    
            monthSelectedFont = UIFont.boldSystemFontOfSize(17)
            monthFont = UIFont.boldSystemFontOfSize(17)
    
            yearSelectedFont = UIFont.boldSystemFontOfSize(17)
            yearFont = UIFont.boldSystemFontOfSize(17)
        }
    
    
        func setup(minYear: NSInteger, andMaxYear maxYear: NSInteger) {
            self.minYear = minYear
    
            if maxYear > minYear {
                self.maxYear = maxYear
            } else {
                self.maxYear = minYear + 10
            }
        }
    
        func selectToday() {
            selectRow(todayIndexPath.row, inComponent: Component.Month.rawValue, animated: false)
            selectRow(todayIndexPath.section, inComponent: Component.Year.rawValue, animated: false)
        }
    
    
        var todayIndexPath: NSIndexPath {
            get {
                var row = 0.0
                var section = 0.0
    
                for cellMonth in months {
                    if cellMonth == currentMonthName {
                        row = Double(months.indexOf(cellMonth)!)
                        row = row + Double(bigRowMonthsCount / 2)
                        break
                    }
                }
    
                for cellYear in years {
                    if cellYear == currentYearName {
                        section = Double(years.indexOf(cellYear)!)
                        section = section + Double(bigRowYearsCount / 2)
                        break
                    }
                }
    
                return NSIndexPath(forRow: Int(row), inSection: Int(section))
            }
        }
    
        var currentMonthName: String {
            get {
                let formatter = NSDateFormatter()
                let locale = NSLocale(localeIdentifier: "en_US")
                formatter.locale = locale
                formatter.dateFormat = "MM"
                return formatter.stringFromDate(NSDate())
            }
        }
    
        var currentYearName: String {
            get {
                let formatter = NSDateFormatter()
                formatter.dateFormat = "yyyy"
                return formatter.stringFromDate(NSDate())
            }
        }
    
    
        func selectedColorForComponent(component: NSInteger) -> UIColor {
            if component == Component.Month.rawValue {
                return monthSelectedTextColor!
            }
            return yearSelectedTextColor!
        }
    
        func colorForComponent(component: NSInteger) -> UIColor {
            if component == Component.Month.rawValue {
                return monthTextColor!
            }
            return yearTextColor!
        }
    
    
        func selectedFontForComponent(component: NSInteger) -> UIFont {
            if component == Component.Month.rawValue {
                return monthSelectedFont!
            }
            return yearSelectedFont!
        }
    
        func fontForComponent(component: NSInteger) -> UIFont {
            if component == Component.Month.rawValue {
                return monthFont!
            }
            return yearFont!
        }
    
    
    
        func titleForRow(row: Int, forComponent component: Int) -> String? {
            if component == Component.Month.rawValue {
                return self.months[row % self.months.count]
            }
            return self.years[row % self.years.count]
        }
    
    
        func labelForComponent(component: NSInteger) -> UILabel {
            let frame = CGRect(x: 0.0, y: 0.0, width: bounds.size.width, height: CGFloat(rowHeight))
            let label = UILabel(frame: frame)
            label.textAlignment = NSTextAlignment.Center
            label.backgroundColor = UIColor.clearColor()
            label.userInteractionEnabled = false
            label.tag = LABEL_TAG
            return label
        }
    }
    
    extension CLIVEDatePickerView: UIPickerViewDelegate, UIPickerViewDataSource {
    
        func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
            return numberOfComponentsRequired
        }
    
        func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            if(component == Component.Month.rawValue) {
                return bigRowMonthsCount
            } else {
                return bigRowYearsCount
            }
        }
    
    
    
        func pickerView(pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
            return self.bounds.size.width / CGFloat(numberOfComponentsRequired)
        }
    
        func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
            var selected = false
    
            if component == Component.Month.rawValue {
                let monthName = self.months[(row % self.months.count)]
                if monthName == currentMonthName {
                    selected = true
                }
            } else {
                let yearName = self.years[(row % self.years.count)]
                if yearName == currentYearName {
                    selected = true
                }
            }
    
            var returnView: UILabel
            if view?.tag == LABEL_TAG {
                returnView = view as! UILabel
            } else {
                returnView = labelForComponent(component)
            }
    
            returnView.font = selected ? selectedFontForComponent(component) : fontForComponent(component)
            returnView.textColor = selected ? selectedColorForComponent(component) : colorForComponent(component)
    
            returnView.text = titleForRow(row, forComponent: component)
    
            return returnView
        }
    
    
        func pickerView(pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
            return CGFloat(rowHeight)
        }
    
    }
    
    0 讨论(0)
  • 2020-11-27 04:21

    You can use UICustomDatePicker to show only the month and year option

    https://github.com/Anandsan/UICustomDatePicker

    @interface ViewController ()
    
    @property (nonatomic, weak) IBOutlet UICustomDatePicker *customDatePicker;
    
    @end
    
    -(void) viewDidLoad {
    
     [super viewDidLoad];
    
     self.customDatePicker.option = NSCustomDatePickerOptionLongMonth | NSCustomDatePickerOptionYear;
    
     self.customDatePicker.order = NSCustomDatePickerOrderMonthDayAndYear;
    
    }
    
     -(IBAction)didCustomDatePickerValueChanged:(id)sender {
    
        NSLog(@"%@",[(UICustomDatePicker *)sender currentDate]);
    
    }
    

    Refer the Screen

    0 讨论(0)
  • 2020-11-27 04:22

    I have a lazy workaround-- I made a 10x10 black png. I then used that as a mask with a scaletofill imageview sized to cover the dates column perfectly. I put the alpha at 0.75 to barely show that column. It is clear to the user and looks decent.

    0 讨论(0)
  • 2020-11-27 04:23

    I'm using a simple UIPickerView with 2 components (months and years).

    And calling the UIPickerViewDelegate with every row selection:

    - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
    {
        //Today year and month
        NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
        [dateFormat setDateFormat:@"yyyy"];
        int year = [[dateFormat stringFromDate:[NSDate date]] intValue];
        [dateFormat setDateFormat:@"MM"];
        int month = [[dateFormat stringFromDate:[NSDate date]] intValue] - 1;
    
        //picker year and month
        int selectedYear = [[self.yearsArray objectAtIndex:[pickerView selectedRowInComponent:1]] intValue];
        int selectedMonth = [pickerView selectedRowInComponent:0];
    
        // if month in the past, change the month
        if (year == selectedYear && selectedMonth < month)
        {
            [pickerView selectRow:month inComponent:0 animated:YES];
        }
    }
    
    0 讨论(0)
  • 2020-11-27 04:27

    You can use the open source library named

    AKMonthYearPickerView

    import AKMonthYearPickerView
    
    AKMonthYearPickerView.sharedInstance.show(vc: viewController, doneHandler: doneHandler, completetionalHandler: completetionalHandler)
    

    https://github.com/ali-cs/AKMonthYearPickerView

    to install it using pods,

    pod 'AKMonthYearPickerView' 
    

    to customize previous years limit and bar color

    AKMonthYearPickerView.sharedInstance.barTintColor =   UIColor.blue
    
    AKMonthYearPickerView.sharedInstance.previousYear = 4
    

    0 讨论(0)
提交回复
热议问题