Domanda

Ho un UIPickerView che viene sfumata al 20% alpha quando non in uso. Voglio che l'utente sia in grado di toccare il selettore e farlo svanire di nuovo in.

posso farlo funzionare se metto un metodo touchesBegan sulla principale vista, ma questo funziona solo quando l'utente tocca il View. Ho provato sub-classing UIPickerView e avere un touchesBegan in là, ma non ha funzionato.

Sto indovinando che è qualcosa a che fare con la catena Responder, ma non riesco a lavorare fuori.

È stato utile?

Soluzione

Sono stato alla ricerca di una soluzione a questo problema per più di una settimana. Ti sto rispondendo anche se sei domanda è più di un anno nella speranza che questo aiuta gli altri.

Scusate se la mia lingua non è molto tecnico, ma io sono abbastanza nuovo per Objective-C e lo sviluppo iPhone.

Subclassing UIPickerView è il modo giusto per farlo. Ma hai per l'override del metodo - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event. Questo è il metodo chiamato ogni volta che si tocca lo schermo e restituisce la vista che reagisce al tocco. In altre parole, la vista cui metodo touchesBegan:withEvent: verrà chiamato.

L'UIPickerView ha 9 subviews! Nella implementazione della classe - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event UIPickerView non tornerà self (questo significa che il touchesBegan:withEvent: si scrive nella sottoclasse, non sarà chiamato), ma restituirà una visualizzazione secondaria, esattamente la vista di indice 4 (una sottoclasse non documentato chiamato UIPickerTable).

Il trucco è quello di rendere il metodo - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event per tornare self in modo da avere il controllo sui metodi touchesBegan:withEvent:, touchesMoved:withEvent: e touchesEnded:withEvent:.

In questi metodi, al fine di mantenere le funzionalità standard della UIPickerView, si deve ricordare di chiamare di nuovo, ma sulla visualizzazione secondaria UIPickerTable.

Spero che questo ha un senso. Non posso scrivere codice ora, non appena sono a casa mi permetterà di modificare questa risposta e aggiungere un po 'di codice.

Altri suggerimenti

Ecco un codice che fa quello che si vuole:

@interface TouchDetectionView : UIPickerView {

}
- (UIView *)getNextResponderView:(NSSet *)touches withEvent:(UIEvent *)event;
@end
@implementation TouchDetectionView

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UIView * hitTestView = [self getNextResponderView:touches withEvent:event];
    [hitTestView touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UIView * hitTestView = [self getNextResponderView:touches withEvent:event];
    [hitTestView touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UIView * hitTestView = [self getNextResponderView:touches withEvent:event];
    [hitTestView touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    UIView * hitTestView = [self getNextResponderView:touches withEvent:event];
    [hitTestView touchesCancelled:touches withEvent:event];
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    return self;
}

- (UIView *)getNextResponderView:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch * touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];
    UIView * hitTestView = [super hitTest:point withEvent:event];

    return ( hitTestView == self ) ? nil : hitTestView;
}

Entrambe le risposte di cui sopra erano molto disponibile, ma ho un UIPickerView nidificato all'interno di un UIScrollView. Sto anche facendo il rendering continua altrove sullo schermo, mentre l'interfaccia grafica è presente. Il problema è che l'UIPickerView non aggiorna completamente quando: una riga selezionata non è sfruttato, il selettore viene spostato in modo che due file a cavallo della zona di selezione, o una riga viene trascinato ma le dito scivola fuori del UIPickerView. Allora non è fino a quando l'UIScrollView che viene spostato il selettore aggiorna istantaneamente. Questo risultato è brutto.

la causa del problema: la mia rappresentazione continua teneva animazione del UIPickerView di ottenere i cicli di CPU di cui aveva bisogno per finire, da qui per mostrare la corretta selezione corrente. La mia soluzione --che giochi idraulici è stato questo: nel touchesEnded:withEvent: del UIPickerView, eseguire qualcosa per mettere in pausa il mio rendering per un breve periodo. Ecco il codice:

#import "SubUIPickerView.h"

@implementation SubUIPickerView

- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
    [pickerTable touchesBegan:touches withEvent:event];
}

- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
    [pickerTable touchesMoved:touches withEvent:event];
}

- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
    [singleton set_secondsPauseRendering:0.5f];  // <-- my code to pause rendering

    [pickerTable touchesEnded:touches withEvent:event];
}

- (void) touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event
{
    [pickerTable touchesCancelled:touches withEvent:event];
}

- (UIView*) hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
    if (CGRectContainsPoint(self.bounds, point))
    {
        if (pickerTable == nil)
        {
            int nSubviews = self.subviews.count;
            for (int i = 0; i < nSubviews; ++i)
            {
                UIView* view = (UIView*) [self.subviews objectAtIndex:i];
                if ([view isKindOfClass:NSClassFromString(@"UIPickerTable")])
                {
                    pickerTable = (UIPickerTable*) view;
                    break;
                }
            }
        }
        return self;    // i.e., *WE* will respond to the hit and pass it to UIPickerTable, above.
    }
    return [super hitTest:point withEvent:event];
}

@end

e poi l'intestazione, SubUIPickerView.h:

@class UIPickerTable;

@interface SubUIPickerView : UIPickerView
{
    UIPickerTable*  pickerTable;
}

@end

Come ho detto, questo funziona. Rendering pause per un ulteriore 1/2 secondo (fa una pausa già quando si fa scorrere l'UIScrollView) che consente l'animazione UIPickerView per terminare. Utilizzando NSClassFromString () significa che non si sta usando le API non documentate. Messing con la catena risponditore non era necessario. Grazie alla checcco e Tylerc230 per avermi aiutato a venire con la mia soluzione!

Set canCancelContentTouches e delaysContentTouches di vista padre a NO, che ha lavorato per me

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top