カスタマイズされたUIPickerviewがあり、日付ピッカーを使用したくありません。ユーザーが時間を上下にスクロールすると、AM/PMコンポーネントが時間のスクロール中に切り替わる機能を実装したいと思います。これは、pickerViewdidSelectRowが呼び出される前に切り替える必要があることを意味します。これを行う方法はありますか?
ありがとう
カスタマイズされたUIPickerviewがあり、日付ピッカーを使用したくありません。ユーザーが時間を上下にスクロールすると、AM/PMコンポーネントが時間のスクロール中に切り替わる機能を実装したいと思います。これは、pickerViewdidSelectRowが呼び出される前に切り替える必要があることを意味します。これを行う方法はありますか?
ありがとう
次の方法を使用します。
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
// put your logic here.
}
上記のメソッドはUIPickerViewDelegateからのものです。ユーザーがピッカービューを使用して要素を選択すると、このメソッドは自動的にトリガーされます。
お役に立てば幸いです。
編集:
検出には次の方法を使用する必要があると思います-ユーザーがスクロールしている方向はどれですか?
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
NSLog(@"scrolling to row is %@",[NSString stringWithFormat:@"index_%i",row]);
return [NSString stringWithFormat:@"index_%i",row];
}
ユーザーが上を上下にスクロールしているときはいつでも、メソッドは自動的にトリガーされます。これは。と同様UITableView
です。UIPickerView
プライベートを使用していることを忘れないでくださいUIPickerTableView
。そのため、希望どおりのスクロールを検出できません。
ピッカービューで方向を検出する方法を説明します。
例。表示される行はindex_4,index_5,index_6,index_7
です。これで、ユーザーが下にスクロールしている場合index_8
に呼び出されます。同様に、ユーザーが上にスクロールしている場合はindex_3
呼び出されます。
このトリックがあなたの問題を解決することを願っています。でも-これについてのフィードバックを教えてください。
これを検出するトリックはありますが、スクロールするかどうかを検出するデリゲートメソッド/プロパティはありません
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
または同等の方法に設定しますfunc pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
これがお役に立てば幸いです、ところでこれは上記のすべての回答で説明されていることです
イベントには、この2つのUIPickerViewデリゲートメソッドを使用する必要があります。
終了スクロール:
- (void)pickerView:(UIPickerView *)pV didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSLog(@"pickerView didSelectRow %zd",row);
// DID END SCROLL: CALL YOUR HEANDLER METHOD!!
}
スクロールを開始します:
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
// WILL START SCROLLING: CALL YOUR HEANDLER METHOD!!
UILabel* label = (UILabel*)view;
if (!label){
label = [UILabel new];
[label setFrame:frame];
[label setBackgroundColor:[UIColor clearColor]];
[label setFont:[UIFont fontWithName:FONT_QUICKSAND_BOLD size:12]];
[label setTextAlignment:NSTextAlignmentRight];
[label setLineBreakMode:NSLineBreakByTruncatingMiddle];
[label setTextColor:UIColorFromRGB(0X2692ff)];
}
//Update labeltext here
[label setText:[NSString stringWithFormat:@"row %zd",row]];
return label;
}
明らかに、UIPickerviewの構築を除いて(初めて!); したがって、パイカーの構築が完了したときに偽のdidendscrollイベントを実装するか、最初に無視すると、表示されているパイカー行のスクロールが開始されます。
残念ながら、上記の解決策(titleForRowなどのデータソースメソッドが呼び出されたときにフラグを設定し、didSelectRowが呼び出されたときにフラグをリセットする)は大雑把であり、多くの場合機能しません。データソースメソッドは、ビューレイアウトの変更につながるUIの変更など、ユーザーによるスクロールがない多くの場合に呼び出される可能性があり、didSelectRowの直後に呼び出される可能性もあります。これらのメソッドがいつ呼び出されるかを制御することはできません。
この特定の質問に関連して、これらのメソッドはスクロール時に常に呼び出されるため、これらのソリューションが機能する可能性があります。スクロール時だけではありません。ただし、これらの場合、ユーザーがスクロールしている必要があると想定しないように注意する必要があります。また、このフラグを使用してステートマシンを管理している場合(スクロール時に一部のボタンを無効にし、後で有効にするなど)、問題が発生します。
最後に、これではスクロールの検出のみが可能です(上記の注意事項があります)が、速度や現在の値はわかりません。そのため、AM/PMラベルをいつ切り替えるかを判断するのは困難です。
スクロールを確実に検出できた唯一の方法は、UIの変更が行われたときに設定したフラグの混乱や、その他の醜いハック(didSelectRowの100ミリ秒後にスクロールを再度検出する前に待機するなど)を使用することでした。 didSelectRowの直後のデータソース)。willScroll / didScrollメソッドをデリゲートに追加することは、Appleが追加を怠ったことは明らかなことのようです。
「pickerDidScroll」を実現する方法を見つけました。問題なく動作します。重要な点は、行ビューにKVOを追加することです。これが私のコードです:
//picker view delegate
- (UIView*)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
if (!view) {
view = [[RatchetScrollUnit alloc] initWithFrame:CGRectZero];
//
[((RatchetScrollUnit*)view) addRatchetObserver:self];
}
return view;
}
//KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if (self.ratchet) {
NSInteger row = [self.ratchet selectedRowInComponent:0];
if (row != _lastRow) {
_lastRow = row;
if (self.delegate && [self.delegate respondsToSelector:@selector(ratchetScrollerDidRatchetedToTooth:)]) {
[self.delegate ratchetScrollerDidRatchetedToTooth:row];
}
}
}
}
「RatchetScrollUnit」クラス:
@interface RatchetScrollUnit ()
@property (nonatomic,assign) BOOL observed;
@property (nonatomic,weak) NSObject *myObserver;
@end
@implementation RatchetScrollUnit
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_observed = NO;
self.backgroundColor = [UIColor clearColor];
}
return self;
}
- (void)dealloc {
if (self.observed) {
[self removeObserver:self.myObserver forKeyPath:@"frame" context:nil];
}
}
- (void)addRatchetObserver:(NSObject*)observer {
if (self.observed) {
return;
}
self.observed = YES;
self.myObserver = observer;
//
[self addObserver:observer
forKeyPath:@"frame"
options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew
context:nil];
}
試してみてください