UIPickerView: evento generato quando la riga è evidenziata
-
06-07-2019 - |
Domanda
Quello che vorrei fare è questo:
Viene mostrato un UIPickerView. Se l'utente tocca la riga selezionata, la riga viene bloccata (è un selettore multicomponente) e gli altri componenti sono liberi di girare. Se la riga è già stata bloccata e l'utente tocca la riga bloccata, la riga viene quindi sbloccata e libera di girare. Ho già codificato la parte di blocco usando un pulsante. Vorrei rimuovere il pulsante e sostituirlo con l'opzione di selezione evidenziata.
Ho provato:
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
}
Apparentemente questo si attiva solo se la riga non è già stata selezionata, quindi quando tocco una riga che si trova nella regione evidenziata, questo evento non si attiva.
Ho quindi provato
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"touchesBegan");
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"touchesMoved");
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"touchesEnded");
}
Nessuno di questi eventi si attiva quando viene toccato il selettore.
Qualche idea su come rilevare quando una riga evidenziata / selezionata in un selettore viene toccata dall'utente?
Soluzione
Bene - c'è una semplice soluzione che ha fatto esattamente quello che volevo realizzare. Fondamentalmente volevo che l'utente toccasse la barra di selezione in una vista di selezione multicomponente e che quel componente fosse bloccato mentre gli altri sono liberi di girare.
Ecco cosa ho fatto:
Primo: disattivare l'opzione per mostrare la barra di selezione.
Secondo: crea tre etichette - una per ciascun componente - le etichette hanno la stessa altezza e posizione della barra di selezione, ma ce n'è una per ciascun componente. Si sembrano l'un l'altro una barra solida.
Terzo: crea un metodo per cambiare il colore dell'etichetta per indicare che è bloccato per l'utente. Sto anche usando un flag booleano per informare i processi del programma quando un componente è bloccato.
- (IBAction) lockButtonPress:(id)sender {
// determine which button was pressed....
int btnPressed = 0;
if (leftSelectionBar.touchInside) btnPressed = 1;
if (centerSelectionBar.touchInside) btnPressed = 2;
if (rightSelectionBar.touchInside) btnPressed = 3;
// we are not going to make this difficult -- images for different states..... default in viewWillShow
switch (btnPressed) {
case 1:
if (lockSelected0) {
lockSelected0 = FALSE;
[leftSelectionBar setBackgroundColor:[UIColor blueColor]];
[leftSelectionBar setAlpha:0.25];
} else {
lockSelected0 = TRUE;
[leftSelectionBar setBackgroundColor:[UIColor redColor]];
[leftSelectionBar setAlpha:0.45];
}
break;
case 2:
if (lockSelected1) {
lockSelected1 = FALSE;
[centerSelectionBar setBackgroundColor:[UIColor blueColor]];
[centerSelectionBar setAlpha:0.25];
} else {
lockSelected1 = TRUE;
[centerSelectionBar setBackgroundColor:[UIColor redColor]];
[centerSelectionBar setAlpha:0.45];
}
break;
case 3:
if (lockSelected2) {
lockSelected2 = FALSE;
[rightSelectionBar setBackgroundColor:[UIColor blueColor]];
[rightSelectionBar setAlpha:0.25];
} else {
lockSelected2 = TRUE;
[rightSelectionBar setBackgroundColor:[UIColor redColor]];
[rightSelectionBar setAlpha:0.45];
}
break;
default:
break;
}
}
Ed è tutto .... semplice;)
Altri suggerimenti
(void) pickerView: (UIPickerView *) thePickerView didSelectRow: (NSInteger) row inComponent: (NSInteger) componente { // Codice personalizzato qui
// Ad esempio, se si dispone di un NSArray o NSMutableArray chiamato come " list " i cui valori sono mostrati su UIPickerView - [list objectAtIndex: row] in cui la riga è indice restituito dall'evento UIPickerView restituirà l'oggetto stesso.
}
Il seguente frammento di codice intercetterà i gesti dei tocchi su un UIPickerView
e determinerà se il tocco era all'interno dell'indicatore di selezione di UIPickerView
:
Per prima cosa, aggiungeremo un UITapGestureRecognizer
per intercettare i gesti dei tocchi. Nota che non vogliamo cancellare i tocchi perché UIPickerView
dovrebbe ancora fare la cosa facendo girare la ruota e tutto il resto.
- (void)viewDidLoad
{
[super viewDidLoad];
UITapGestureRecognizer* gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pickerViewTapGestureRecognized:)];
gestureRecognizer.cancelsTouchesInView = NO;
[self.pickerView addGestureRecognizer:gestureRecognizer];
}
In secondo luogo, controlleremo se il tocco si trovava all'interno dell'indicatore di selezione del UIPickerView
(supponendo che l'indicatore di selezione utilizzi circa il 15% dell'altezza del UIPickerView
- potrebbe essere necessario modificare questo valore):
- (void)pickerViewTapGestureRecognized:(UITapGestureRecognizer*)gestureRecognizer
{
CGPoint touchPoint = [gestureRecognizer locationInView:gestureRecognizer.view.superview];
CGRect frame = self.pickerView.frame;
CGRect selectorFrame = CGRectInset( frame, 0.0, self.pickerView.bounds.size.height * 0.85 / 2.0 );
if( CGRectContainsPoint( selectorFrame, touchPoint) )
{
NSLog( @"Selected Row: %i", [self.currentArticles objectAtIndex:[self.pickerView selectedRowInComponent:0]] );
}
}
Dovresti NON implementare
- (void)pickerView:(UIPickerView*)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
poiché stiamo rilevando la selezione per conto nostro ora.