私はタイマーアプリを作成していて、ユーザーに時、分、秒を表示する必要がありました。 UIDatePicker
を使用してみましたが、選択肢として時間と分しか表示されません。秒ではありません。オンラインで少し調べたところ、UIDatePicker
で秒を取得する方法がないことがわかり、自分でUIPickerView
を最初から作成する必要がありました。
だから私の質問は、そのようなためのサンプルコードはありますか?つまり、誰かがCustomUIPickerView
を時間、分、秒で書いて、プロジェクトに組み込むことができますか? UIDatePicker
には、ユーザーがダイヤルを回している間も表示される時間と分テキストの素晴らしいオーバーレイがあります。誰かがカスタムピッカーにも追加したとしたら、それは素晴らしいことです。必要がない場合は、カスタムUIPickerView
を最初から作成しないことをお勧めします。ありがとうございました。
よろしくお願いします。これがUIPickerView
で時間/分/秒を取得するコードです。 3つのラベルを追加して、ピッカーに戦略的に配置できます。写真も添付しました。
あなたが答えが好きならそれを評価してください!優れた開発者は知識を共有し、一部の人々が提案したようにそれを隠さない。コーディングを楽しんでください!
あなたのヘッダ.hファイルにこれを入れてください
@interface v1AddTableViewController : UITableViewController
{
IBOutlet UIPickerView *pickerView;
NSMutableArray *hoursArray;
NSMutableArray *minsArray;
NSMutableArray *secsArray;
NSTimeInterval interval;
}
@property(retain, nonatomic) UIPickerView *pickerView;
@property(retain, nonatomic) NSMutableArray *hoursArray;
@property(retain, nonatomic) NSMutableArray *minsArray;
@property(retain, nonatomic) NSMutableArray *secsArray;
あなたの.mファイルにこれを入れてください
@synthesize pickerView;
@synthesize hoursArray;
@synthesize minsArray;
@synthesize secsArray;
@synthesize interval;
- (void)viewDidLoad
{
[super viewDidLoad];
//initialize arrays
hoursArray = [[NSMutableArray alloc] init];
minsArray = [[NSMutableArray alloc] init];
secsArray = [[NSMutableArray alloc] init];
NSString *strVal = [[NSString alloc] init];
for(int i=0; i<61; i++)
{
strVal = [NSString stringWithFormat:@"%d", i];
//NSLog(@"strVal: %@", strVal);
//Create array with 0-12 hours
if (i < 13)
{
[hoursArray addObject:strVal];
}
//create arrays with 0-60 secs/mins
[minsArray addObject:strVal];
[secsArray addObject:strVal];
}
NSLog(@"[hoursArray count]: %d", [hoursArray count]);
NSLog(@"[minsArray count]: %d", [minsArray count]);
NSLog(@"[secsArray count]: %d", [secsArray count]);
}
//Method to define how many columns/dials to show
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 3;
}
// Method to define the numberOfRows in a component using the array.
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent :(NSInteger)component
{
if (component==0)
{
return [hoursArray count];
}
else if (component==1)
{
return [minsArray count];
}
else
{
return [secsArray count];
}
}
// Method to show the title of row for a component.
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
switch (component)
{
case 0:
return [hoursArray objectAtIndex:row];
break;
case 1:
return [minsArray objectAtIndex:row];
break;
case 2:
return [secsArray objectAtIndex:row];
break;
}
return nil;
}
-(IBAction)calculateTimeFromPicker
{
NSString *hoursStr = [NSString stringWithFormat:@"%@",[hoursArray objectAtIndex:[pickerView selectedRowInComponent:0]]];
NSString *minsStr = [NSString stringWithFormat:@"%@",[minsArray objectAtIndex:[pickerView selectedRowInComponent:1]]];
NSString *secsStr = [NSString stringWithFormat:@"%@",[secsArray objectAtIndex:[pickerView selectedRowInComponent:2]]];
int hoursInt = [hoursStr intValue];
int minsInt = [minsStr intValue];
int secsInt = [secsStr intValue];
interval = secsInt + (minsInt*60) + (hoursInt*3600);
NSLog(@"hours: %d ... mins: %d .... sec: %d .... interval: %f", hoursInt, minsInt, secsInt, interval);
NSString *totalTimeStr = [NSString stringWithFormat:@"%f",interval];
}
上記の受け入れられたソリューションとは異なり、私は少しひどいものを思いつきました。間違いなく完璧ではありませんが、望ましい効果があります(私はiPhoneのiOS 7でのみテストしましたが、書かれているように縦長でのみ機能します)。より良くするための編集は大歓迎です。以下の関連表示コード:
// assumes you conform to UIPickerViewDelegate and UIPickerViewDataSource in your .h
- (void)viewDidLoad
{
[super viewDidLoad];
// assumes global UIPickerView declared. Move the frame to wherever you want it
picker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 200)];
picker.dataSource = self;
picker.delegate = self;
UILabel *hourLabel = [[UILabel alloc] initWithFrame:CGRectMake(42, picker.frame.size.height / 2 - 15, 75, 30)];
hourLabel.text = @"hour";
[picker addSubview:hourLabel];
UILabel *minsLabel = [[UILabel alloc] initWithFrame:CGRectMake(42 + (picker.frame.size.width / 3), picker.frame.size.height / 2 - 15, 75, 30)];
minsLabel.text = @"min";
[picker addSubview:minsLabel];
UILabel *secsLabel = [[UILabel alloc] initWithFrame:CGRectMake(42 + ((picker.frame.size.width / 3) * 2), picker.frame.size.height / 2 - 15, 75, 30)];
secsLabel.text = @"sec";
[picker addSubview:secsLabel];
[self.view addSubview:picker];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 3;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if(component == 0)
return 24;
return 60;
}
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component
{
return 30;
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
UILabel *columnView = [[UILabel alloc] initWithFrame:CGRectMake(35, 0, self.view.frame.size.width/3 - 35, 30)];
columnView.text = [NSString stringWithFormat:@"%lu", (long) row];
columnView.textAlignment = NSTextAlignmentLeft;
return columnView;
}
そしてその結果:
Swiftの実装
class TimePickerView: UIPickerView, UIPickerViewDataSource, UIPickerViewDelegate {
var hour:Int = 0
var minute:Int = 0
override init() {
super.init()
self.setup()
}
required internal init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.setup()
}
func setup(){
self.delegate = self
self.dataSource = self
/*let height = CGFloat(20)
let offsetX = self.frame.size.width / 3
let offsetY = self.frame.size.height/2 - height/2
let marginX = CGFloat(42)
let width = offsetX - marginX
let hourLabel = UILabel(frame: CGRectMake(marginX, offsetY, width, height))
hourLabel.text = "hour"
self.addSubview(hourLabel)
let minsLabel = UILabel(frame: CGRectMake(marginX + offsetX, offsetY, width, height))
minsLabel.text = "min"
self.addSubview(minsLabel)*/
}
func getDate() -> NSDate{
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH:mm"
let date = dateFormatter.dateFromString(String(format: "%02d", self.hour) + ":" + String(format: "%02d", self.minute))
return date!
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
switch component {
case 0:
self.hour = row
case 1:
self.minute = row
default:
println("No component with number \(component)")
}
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return 24
}
return 60
}
func pickerView(pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
return 30
}
func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView!) -> UIView {
if (view != nil) {
(view as UILabel).text = String(format:"%02lu", row)
return view
}
let columnView = UILabel(frame: CGRectMake(35, 0, self.frame.size.width/3 - 35, 30))
columnView.text = String(format:"%02lu", row)
columnView.textAlignment = NSTextAlignment.Center
return columnView
}
}
@ Stonz2のバージョンを少し改良しました。ラベルのy位置の計算にもエラーがありました。
ここで.hファイル
@interface CustomUIDatePicker : UIPickerView <UIPickerViewDataSource, UIPickerViewDelegate>
@property NSInteger hours;
@property NSInteger mins;
@property NSInteger secs;
-(NSInteger) getPickerTimeInMS;
-(void) initialize;
@end
そして、ここで改善された.mファイル
@implementation CustomUIDatePicker
-(instancetype)init {
self = [super init];
[self initialize];
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
[self initialize];
return self;
}
-(instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
[self initialize];
return self;
}
-(void) initialize {
self.delegate = self;
self.dataSource = self;
int height = 20;
int offsetX = self.frame.size.width / 3;
int offsetY = self.frame.size.height / 2 - height / 2;
int marginX = 42;
int width = offsetX - marginX;
UILabel *hourLabel = [[UILabel alloc] initWithFrame:CGRectMake(marginX, offsetY, width, height)];
hourLabel.text = @"hour";
[self addSubview:hourLabel];
UILabel *minsLabel = [[UILabel alloc] initWithFrame:CGRectMake(marginX + offsetX, offsetY, width, height)];
minsLabel.text = @"min";
[self addSubview:minsLabel];
UILabel *secsLabel = [[UILabel alloc] initWithFrame:CGRectMake(marginX + offsetX * 2, offsetY, width, height)];
secsLabel.text = @"sec";
[self addSubview:secsLabel];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (component == 0) {
self.hours = row;
} else if (component == 1) {
self.mins = row;
} else if (component == 2) {
self.secs = row;
}
}
-(NSInteger)getPickerTimeInMS {
return (self.hours * 60 * 60 + self.mins * 60 + self.secs) * 1000;
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 3;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if(component == 0)
return 24;
return 60;
}
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component
{
return 30;
}
-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
if (view != nil) {
((UILabel*)view).text = [NSString stringWithFormat:@"%lu", row];
return view;
}
UILabel *columnView = [[UILabel alloc] initWithFrame:CGRectMake(35, 0, self.frame.size.width/3 - 35, 30)];
columnView.text = [NSString stringWithFormat:@"%lu", row];
columnView.textAlignment = NSTextAlignmentLeft;
return columnView;
}
@end
私はここに簡単な解決策があります、あなたはUIPickerViewのUIPickerViewDataSourceの3つのメソッドを実装できます
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 5;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
switch (component) {
case 0:
return 24;
break;
case 1:
case 3:
return 1;
break;
case 2:
case 4:
return 60;
break;
default:
return 1;
break;
}
}
- (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
switch (component) {
case 1:
case 3:
return @":";
break;
case 0:
case 2:
case 4:
return [NSString stringWithFormat:@"%lu", (long) row];
break;
default:
return @"";
break;
}
}
1つのオプションはActionSheetPickerを使用することです
https://github.com/skywinder/ActionSheetPicker-3.
actionSheetMultipleStringPickerを利用します。 ActionSheetPickerドキュメントのサンプルコードをたどることができます。
「時間/分/秒」オーバーレイの別のソリューションを次に示します。ピッカービューのデリゲートからpickerView(UIPickerView, didSelectRow: Int, inComponent: Int)
メソッドを使用して、ビューのラベルを更新します。
これにより、画面の向きに関係なく機能します。 それはまだ最適ではありませんが、それは非常に簡単です。
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let label = UILabel()
label.text = String(row)
label.textAlignment = .center
return label
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if let label = pickerView.view(forRow: row, forComponent: component) as? UILabel {
if component == 0, row > 1 {
label.text = String(row) + " hours"
}
else if component == 0 {
label.text = String(row) + " hour"
}
else if component == 1 {
label.text = String(row) + " min"
}
else if component == 2 {
label.text = String(row) + " sec"
}
}
}
ピッカービューが表示されているときにオーバーレイを表示するには、行をプログラムで選択する必要があります...
func selectPickerViewRows() {
pickerView.selectRow(0, inComponent: 0, animated: false)
pickerView.selectRow(0, inComponent: 1, animated: false)
pickerView.selectRow(30, inComponent: 2, animated: false)
pickerView(pickerView, didSelectRow: 0, inComponent: 0)
pickerView(pickerView, didSelectRow: 0, inComponent: 1)
pickerView(pickerView, didSelectRow: 30, inComponent: 2)
}