21

私はこの質問をよく調べましたが、それが可能かどうかはまだ不明です。基本的に私がやりたいことは、UIPickerViewそれを永遠に回転させることができ、最後に到達することはないという意味で連続的な を作成することです (最後の値の後に最初の値が続くため)。

私はオンラインで見回しており、望ましい効果を達成するためのさまざまなハックがあるようです. UIPickerViewただし、これらのソリューションの多くは、 が連続しているとユーザーに思わせるために、 の行数を増やしているようですUIPickerView(ただし、実際には、スクロールし続けると最終的には最後に到達します)。

私が求めているのは、何日、何週間、何ヶ月、何年もスクロールし続けても最後まで到達しないという意味で、真に無限の UIPickerView を作成する方法です。解決策がハックであっても、Apple がまだ効果を達成する方法を提供していないことを理解しているので、私はあまり気にしません。

誰かがこれを行う方法についてアドバイスできますか(または、少なくとも正しい方向に向けてください)?

4

10 に答える 10

4

ネイティブ UIPickerView で実行できる唯一のハックは、次のとおりです。

UIPickerView コンポーネントをラップアラウンドするにはどうすればよいですか?

実際にループ ピッカーを作成するもう 1 つの方法は、自分で実装することです。

OpenGL ベースの cocos2d で実装されたピッカーを見ました。本当に必要な場合は、UIKit を使用して実行できると思います。

または、それを忘れて、反復可能なコンテンツを含む NSIntegerMax 行でピッカーを作成します。誰も最後まで回さないと思います。

于 2012-06-02T10:39:39.723 に答える
3

UIPickerViewここで非常にうまく機能し、実装が非常に簡単な カスタムクラスを見つけてください

于 2012-10-04T09:56:53.643 に答える
2

それが可能だ。これを行う方法は次のとおりです。まずタイマーをセットします。int maxNumberは、任意の値に設定されたインスタンス変数であると仮定しましょう。

- ( void) viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
   [self.timer invalidate];
   self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self    selector:@selector(timerFireMethod:) userInfo:nil repeats:YES];

}

- (void) viewWillDisappear:(BOOL)animated{
   [self.timer invalidate];
   [super viewWillDisappear:animated];
}

- (void)viewDidLoad
{
 [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
 [self.infinitePickerView selectRow:(int)maxNumber*5 inComponent:0 animated:YES];
}

タイマー起動メソッドで、uipickerview の「エッジ」ビューが表示されているかどうかを確認します。

- (void)timerFireMethod:(NSTimer*)theTimer{
int rowSelected = [self.infinitePickerView selectedRowInComponent:0];    
for (int i=0; i<= 20; i++) {
    UIView * viewBelow = [self.infinitePickerView viewForRow:i forComponent:0];
    UIView * viewAbove = [self.infinitePickerView viewForRow:maxNumber*10-20+i forComponent:0];
    if(viewBelow!=nil || viewAbove!=nil){
        int middlePosition = maxNumber * 5 + (rowSelected % maxNumber);
        [self.infinitePickerView selectRow:middlePosition inComponent:0 animated:NO];
        break;
    }
}
}

[self.infinitePickerView viewForRow:i forComponent:0];表示されている場合にのみ UIView を返すため、これが機能することに注意してください。

もちろん、あなたのUIPickerViewDelegate使用は次のようなものでなければなりません

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
   return  maxNumber * 10; //returning a large number
}

 //You cannot use this method
/*
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row  forComponent:(NSInteger)component{}
 You have to use the method below in lieu of it
*/

 - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{

 UILabel * label;

 if (!view) {
    label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0,  self.infinitePickerView.bounds.size.width, 30)];
}else {
    label = (UILabel *) view;     
}
[label setText:[NSString stringWithFormat:@" %d", row % maxNumber]];
return label;
}

これがうまくいくことを願っています!! :) 幸運を!

于 2012-06-06T17:55:23.553 に答える
2

ラップするネイティブ ピッカーはありません (とにかく iOS7.1 の時点ではありません)。次の行に沿ってこれを偽造できます。

NSArray *picks = @[ @"zero", @"one", @"two", @"three" ]; // 4 entries

// ...

- (NSInteger)pickerView:(UIPickerView *)pickerView 
numberOfRowsInComponent:(NSInteger)component
{
    return (3 * [picks count]); // we're very tricky, displaying only
                                // ...the SECOND set of entries, to
                                // ... give the impression of wrap-around
}

// ...

- (NSString *)pickerView:(UIPickerView *)pickerView 
             titleForRow:(NSInteger)row 
            forComponent:(NSInteger)component
{
    // All "3" sets of entries have the same values;
    // this is what gives the appearance of wrap-around.
    int titleRow = row % [picks count];
    return [picks objectAtIndex: titleRow];
}

// ...

- (void)pickerView:(UIPickerView *)pickerView 
      didSelectRow:(NSInteger)row 
       inComponent:(NSInteger)component
{
    // If the wheel turns to outside our 2nd-set range,
    // ...set it to the matching item in the 2nd set.
    // In this way, we always display what looks like a wrap-around.
    int count = [picks count];
    if ((row <  count)
    ||  (row > (count * 2) )
    {
        [pickerView selectRow: (row % count) inComponent: component animated: NO];
    }
}

もちろん、ニーズに合わせて調整する必要がありますが、これが基本的な要点です。

幸運を!

于 2014-05-15T02:08:23.877 に答える
0

pickerView に大量のデータを詰め込む必要があるソリューションは無駄に思えます。次のソリューションでは、メモリの代わりにスマートを使用します。

移入が必要な行は、ビューに表示されている行と、最初の行の直前の行と最後の行の直後の行だけです。ユーザーがコンポーネントをスクロールすると、スクロールする行ごとに pickerView:titleForRow:forComponent: が呼び出されます。

したがって、解決策は pickerView:titleForRow:forComponent: のデータを更新してから、適切なメソッドを呼び出してデータを再読み込みし、pickerview がもう 1 回目盛りをスクロールしたときにデータがそこにあるようにすることです。

于 2013-01-13T01:45:30.753 に答える
0

私はそれが古い質問であることを知っていますが、私は自分のプロジェクトでそれを実装しているときにそれを見つけました.

コンテンツが繰り返される多数のアイテムのモリオンの方法を使用するだけで、スクロールが停止するたびに行がリセットされます。あなたがだまされたことを誰かが理解する唯一の方法は、didSelectRow 関数を決して呼び出さずに、止まるまで途切れることなく継続的にスクロールすることです。それにはいくらかの献身が必要です!

どのようにやっても、少しハッキーに感じるように思えます。これが最も簡単なハックに違いありません...

于 2015-11-02T15:42:40.613 に答える
0

うーん..私は周りを見回してきましたが、いくつかの可能性へのリンクがいくつかあります.センターセット。ユーザーが上部または下部のセットのいずれかの中央にスクロールするたびに、行の値を中央のセットの中央に戻します! 無限の錯覚を生み出す非常に長いリストを作成するよりも、より本物のようです。この解決策は、無限のピッカービューの問題を解決するのに最も効果的で簡単かもしれません! これが役に立ったことを願っています!

于 2012-06-06T14:51:04.570 に答える