2010-03-08 11 views
11

Próbuję użyć widoku UIPicker z zachowaniem, które różni się od tego, co zwykle widać w przykładach kodu iPhone'a.Umożliwienie użytkownikowi wybrania wiersza UIPickerView przez dotknięcie

Co chcę zrobić, to pozwolić użytkownikom na przewijanie zawartości selektora, ale nie na automatyczne wybieranie wiersza selektora (przy użyciu metody "didSelectRow" z delegata picker). Zamiast tego chcę pozwolić użytkownikowi dotknąć środkowego rzędu selektora, który zostanie podświetlony i stanie się wyborem.

Czy jest jakiś sposób, aby to osiągnąć?

Z góry dziękuję.

+0

Czy możesz wyjaśnić, dlaczego metoda didSelectRow tutaj nie pomaga? Czy próbowałeś go użyć i jeśli tak, jaki masz problem? – DyingCactus

+0

Problem polega na tym, że działa tak, jak zakłada. : -/Zasadniczo wyglądam jak pickerView, w którym selektor wybrał automatycznie jedną z wartości wiersza, ale wybiera tylko wartość, gdy użytkownik ją dotknie. Próbowałem zrobić to samo, ale nie mogłem. – camilo

Odpowiedz

0

Jest tylko 2 uczestników dla UIPickerView.

Tak, możemy użyć tylko 7 sposobów kontrolowania UIPickerView przez delegata.

- pickerView: rowHeightForComponent:
- pickerView: widthForComponent:
- pickerView: titleForRow: forComponent:
- pickerView: viewForRow: forComponent: reusingView:
- pickerView: didSelectRow: inComponent:
- numberOfComponentsInPickerView :
- pickerView: numberOfRealInComponent:

to wszystko.

W UITableViewDelegate case dostępnych jest więcej metod dla UITableView do zarządzania wyborami. takich jak - tableView: willSelectRowAtIndexPath:
- tableView: didSelectRowAtIndexPath:
- tableView: willDeselectRowAtIndexPath:
- tableView: didDeselectRowAtIndexPath:

Jednak ...

W przypadku UIPickerViewDelegate istnieje to tylko 1 metoda reagowania na wybór wiersza.

- pickerView: didSelectRow: inComponent:

+0

to właśnie myślałem. Widziałem aplikacje robiące, co chcę, ale przypuszczam, że robię to w inny sposób. Dzięki i tak. – camilo

5
  1. utworzyć nową UIControl

    • samej pozycji jak UIPickerView
    • [yourcontrol setBackGroundColor: [UIColor clearColor]];
  2. dokonać metodą

 
- (IBAction) pickerControlTapped 
{ 
    [yourpicker selectRow: rand()% yourpickersize 
       inComponent: 0 
       animated: YES]; 
} 

.3.nawiązania połączenia pomiędzy 1 a 2

 
[yourcontrol addTarget: self 
       action: @selector(pickerControlTapped) 
     forControlEvents: UIControlEventTouchUpInsied]; 
+0

Wielkie dzięki. Spróbuję teraz. – camilo

+0

Doskonały, proszę oznaczyć to jako odpowiedź. Uwaga: ustaw tę samą pozycję, co środkowy wiersz UIPickerView. –

+0

Myślę, że to jest proste i genialne. Ponieważ wybrana wysokość rzędów jest już znana, można ją precyzyjnie i prosto ustawić. Świetne rzeczy, dzięki. – Roddy

15

Dodaj rozpoznającym gest do UIPickerView który wywołuje metodę docelową w obiekcie:

myGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pickerTapped:)]; 
[myPicker addGestureRecognizer:myGR]; 

// target method 

-(void)pickerTapped:(id)sender 
{ 
// your code 
} 
+0

Martin, natknąłem się na twoje rozwiązanie i okazało się bardzo pomocne. Takie proste i działa. Jedyny problem, w mojej odpowiedzi na dotknięcie, jak mogę przekazać dotknięcie do selektora, aby uzyskać obiekt w linii, która jest dotknięta, a nie obiekt w środku? –

+7

@DeanDavids Wygląda na to, że wskazana strona już nie istnieje. Czy mógłbyś podać inny lub wyjaśnić rozwiązanie? –

+0

Do każdego pracownika Google, który znajdzie tę odpowiedź, dostępne są inne odpowiedzi, które pozwalają przejść przez kliknięcie i wybrać element - https://stackoverflow.com/a/25719326/655822 – jp36

2

Opierając się na odpowiedź Martina Linklater do wspierania dotykając zbieraczy inne wiersze : Ma kilka magicznych liczb, ale działa dla mnie.

- (void) pickerTapped:(UITapGestureRecognizer*)gestureRecognizer 
{ 
    CGPoint location = [gestureRecognizer locationInView:self.pickerView]; 

    CGFloat halfViewHeight = self.pickerView.frame.size.height/2; 

    NSInteger row = -1; 
    if (location.y < halfViewHeight - 22 
     && location.y > halfViewHeight - 66) 
    { 
     row = [self.pickerView selectedRowInComponent:0] - 1; 
    } 
    else if (location.y < halfViewHeight + 22 
      && location.y > halfViewHeight - 22) 
    { 
     row = [self.pickerView selectedRowInComponent:0]; 
    } 
    else if (location.y < halfViewHeight + 66 
      && location.y > halfViewHeight + 22) 
    { 
     row = [self.pickerView selectedRowInComponent:0] + 1; 
    } 

    if (row >= 0 && row < [self.content count]) 
    { 
     id element = [self.content objectAtIndex:row]; 

     if (element) 
     { 
      [self.pickerView selectRow:row inComponent:0 animated:YES]; 

      // do more stuff 
     } 
    } 
} 
+0

Do każdego pracownika Google, który znajdzie tę odpowiedź, kolejna odpowiedź stackoverflow, która obsługuje przekazywanie kliknięć i wybieranie pozycji bez konieczności polegania na magicznych liczbach - https://stackoverflow.com/a/25719326/655822 – jp36

1

Mam stosunkowo proste rozwiązanie tego problemu, który działa dobrze dla mnie. Za pomocą ukrytego przycisku niestandardowego można uzyskać dostęp do funkcji dotknięcia bez rozpoznawania gestów. To rozwiązanie działa na zbieracz z jednym komponentem, ale jestem pewien, że można go przystosować do pracy z większą ilością.

Najpierw dodaj przycisk w programie Interface Builder lub programowo. Ustaw go tak, aby był ukryty i tak szeroki, jak selektor, a następnie umieść go tak, aby znajdował się dokładnie pośrodku stołu, a także przed nim w hierarchii widoku.

Używam IBAction w ten sposób, aby pokazać mój selektor. Jednak naprawdę zależy od Ciebie, w jaki sposób pokazujesz i ukrywasz próbnik.

- (IBAction)showPicker:(id)sender 
{ 
    _picker.hidden = NO; 
    _buttonPicker.hidden = NO; 
} 

Cała akcja wyboru wartości kompletacji dzieje w IBAction dla zdarzenia UIControlEventTouchUpInside, coś takiego.

- (IBAction)selectPicker:(id)sender 
{ 
    //Hide the button so that it doesn't get in the way 
    _buttonPicker.hidden = YES; 

    //Make sure we're within range 
    NSInteger max = _values.count; 
    NSInteger row = [_picker selectedRowInComponent:0]; 
    if(row >= 0 && row < max) { 
     NSString *value = [_values objectAtIndex:row]; 

     //Set the label value and hide the picker 
     _label.text = value; 
     _picker.hidden = YES; 
    } 
} 

Lekko zmodyfikowałem kod dla tej odpowiedzi z kodu roboczego, więc przepraszam, jeśli jest w ogóle uszkodzony.

Powiązane problemy