DatePicker for tvOS! inspired by https://github.com/jruhym/datePicker
This has seen a long road of being a POC from the code listed above, to written completely in obj-c, to being re-written in Swift! There are now two versions that parallel in functionality one in Objective-C and one in Swift (the swift target is a framework you can embed too!) Will updated README with swift sample code and info later, however, the Swift sample app now uses the new Swift framework.
all 4 date picker modes are supported:
Objective-C:
KBDatePickerModeTime
KBDatePickerModeDate
KBDatePickerModeDateAndTime
KBDatePickerModeCountDownTimer
Swift:
DatePickerMode.Time
DatePickerMode.Date
DatePickerMode.DateAndTime
DatePickerMode.CountDownTimer
4 of the most important properties are supported
- (NSDate *)date
- (NSDate *)minimumDate *
- (NSDate *)maximumDate *
- (NSTimeInterval)countDownDuration *
minimum(maximum)Date aren't supported in KBDatePickerModeDateAndTime/DatePickerMode.DateAndTime mode yet
In the near future I will try to make this work w/ CocoaPods and Carthage, for now just grab the KBDatePicker/KBDatePicker folder (with KBDatePickerView.h/m and Macros.h in it) and add that to your project.
Adding the control & listening for control events is the same as any other UIControl (same as UIPicker iOS counterparts)
Objective-C:
#import "KBDatePickerView.h"
- (void)addDatePicker {
KBDatePickerView *datePickerView = [KBDatePickerView new];
datePickerView.translatesAutoresizingMaskIntoConstraints = false;
[self.view addSubview:datePickerView];
//would center the view obviously optional!
[datePickerView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor].active = true;
[datePickerView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = true;
//listen for changes
[datePickerView addTarget:self action:@selector(datePickerChanged:) forControlEvents:UIControlEventValueChanged];
//use a countdown timer instead
[datePickerView setDatePickerMode:KBDatePickerModeCountDownTimer];
[datePickerView setCountDownDuration:4205];
}
- (void)datePickerChanged:(KBDatePickerView *)dpv {
NSLog(@"[KBDatePicker] changed: %@", dpv.date);
if (dpv.datePickerMode == KBDatePickerModeCountDownTimer){
NSString *time = [NSString stringWithFormat:@"countdown duration: %.0f seconds", dpv.countDownDuration];
self.datePickerLabel.text = time;
} else {
NSDateFormatter *dateFormatter = [KBDatePickerView sharedDateFormatter];
NSString *strDate = [dateFormatter stringFromDate:dpv.date];
NSLog(@"strDate: %@", strDate); // Result: strDate: 2014/05/19 10:51:50
self.datePickerLabel.text = strDate;
}
}
Swift:
import UIKit
import TVDatePickerSwift
class ViewController: UIViewController {
let datePickerView = DatePickerView(withHybrdidLayout: false)
let toggleButton = UIButton(type: .system)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
datePickerView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(datePickerView)
datePickerView.showDateLabel = true
datePickerView.addTarget(self, action: #selector(actionOccured(sender:)), for: .valueChanged)
datePickerView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
datePickerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
toggleButton.setTitle("Toggle", for: .normal)
toggleButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(toggleButton)
toggleButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
toggleButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 50).isActive = true
toggleButton.addTarget(self, action: #selector(toggleMode), for: .primaryActionTriggered)
datePickerView.datePickerMode = .CountDownTimer
//datePickerView.countDownDuration = 4100
datePickerView.minuteInterval = 6
}
override var preferredFocusEnvironments: [UIFocusEnvironment] {
return [toggleButton]
}
@objc func toggleMode() -> Void {
if datePickerView.datePickerMode == .CountDownTimer {
self.datePickerView.datePickerMode = .Time
} else {
self.datePickerView.datePickerMode = DatePickerMode(rawValue: self.datePickerView.datePickerMode.rawValue+1)!
}
}
@objc func actionOccured(sender: DatePickerView) -> Void {
//print
print("date selected: \(sender.date)")
}
}
There are both Objective-C and Swift sample apps included in this project. Please refer to them if this sample code isnt sufficient!
Sometimes you may have trouble directing the focus engine on and off of KBDatePicker, if this happens, i recommend creating focus guides similar to the ones created in the sample project. This sample below is assuming theres a toggle button like the one in the sample app and isnt code that will run on its own without substituting in the view you want the focus engine to redirect to.
UIFocusGuide *focusGuideLeft = [[UIFocusGuide alloc] init];
[self.view addLayoutGuide:focusGuideLeft];
[focusGuideLeft.topAnchor constraintEqualToAnchor:self.datePickerView.topAnchor].active = true;
[focusGuideLeft.bottomAnchor constraintEqualToAnchor:self.datePickerView.bottomAnchor].active = true;
[focusGuideLeft.widthAnchor constraintEqualToConstant:40].active = true;
[focusGuideLeft.rightAnchor constraintEqualToAnchor:self.datePickerView.leftAnchor].active = true;
focusGuideLeft.preferredFocusEnvironments = @[self.toggleTypeButton];
UIFocusGuide *focusGuideRight = [[UIFocusGuide alloc] init];
[self.view addLayoutGuide:focusGuideRight];
[focusGuideRight.topAnchor constraintEqualToAnchor:self.datePickerView.topAnchor].active = true;
[focusGuideRight.bottomAnchor constraintEqualToAnchor:self.datePickerView.bottomAnchor].active = true;
[focusGuideRight.leftAnchor constraintEqualToAnchor:self.datePickerView.rightAnchor].active = true;
[focusGuideRight.widthAnchor constraintEqualToConstant:40].active = true;
focusGuideRight.preferredFocusEnvironments = @[self.toggleTypeButton];
- Plan on adding localization support at some point for the text labels that are created for some of the view modes
- Create a CocoaPod & Cartfile (or whatever carthage uses)
- Support min/max date in KBDatePickerModeDateAndTime
Feel free to request features if you think i've overlooked anything!