Vraag Hoe doel-actie-mechanisme voor aangepaste controle te implementeren?


Ik ga mijn eigen aangepaste besturing schrijven die heel anders is dan UIButton. Het is zo veel anders dat ik besloot het helemaal opnieuw te schrijven. Dus alle ik subklasse is UIControl.

Wanneer mijn besturing van binnen is aangeraakt, dan wil ik een bericht activeren in de vorm van een doelactie. De gebruiker van die klasse kan het instantiëren en vervolgens een aantal doelen en acties toevoegen voor deze gebeurtenis.

dat wil zeggen stel je voor dat ik intern een methode zou bellen - fireTargetsForTouchUpEvent. Hoe kon ik dit target-action-mechanisme in mijn klas handhaven? Moet ik alle doelen en acties toevoegen aan mijn eigen array en vervolgens selectors (de acties) alleen aanroepen op de doelobjecten in een for-loop? Of is er een meer intelligente manier om het te doen?

Ik stel me voor om een ​​aantal methoden te bieden voor het toevoegen van doelen en acties voor sommige evenementen zoals die gebeurtenis bijwerken (ik raise dat handmatig door een interne methode aan te roepen wanneer dat gebeurt). Enig idee?


16
2017-08-17 16:22


oorsprong


antwoorden:


Aangezien u van plan bent UIControl te subclasseren, kunt u het gewoon gebruiken

- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;

Met behulp hiervan kan elke klasse zichzelf registreren als een doelwit voor alle evenementen die het wil op uw aangepaste controller.


5
2017-08-17 18:08



Ik wil alleen verduidelijken wat @Felixyz zei omdat het mij in het begin niet duidelijk was.

Als u subclassing bent UIControl, zelfs als u een aangepast evenement gaat houden, hoeft u uw eigen doelen / acties niet bij te houden. De functionaliteit is er al, het enige dat u hoeft te doen is de onderstaande code in uw subklasse aan te roepen om de gebeurtenis te activeren:

[self sendActionsForControlEvents:UIControlEventValueChanged];

Vervolgens in de weergave- of weergaveregelaar die uw gebruikmaakt UIControl, gewoon doen

[customControl addTarget:self action:@selector(whatever) forControlEvents:UIControlEventValueChanged]; 

Voor een aangepaste gebeurtenis, definieert u gewoon uw eigen opsommingsteken (bijvoorbeeld UIControlEventValueChanged is gelijk aan 1 << 12). Zorg ervoor dat het binnen het toegestane bereik valt dat is gedefinieerd door UIControlEventApplicationReserved


38
2017-09-25 02:33



Je hebt het juiste idee. Hier is hoe ik het zou doen:

@interface TargetActionPair : NSObject
{
    id target;
    SEL action;
}
@property (assign) id target;
@property (assign) SEL action;
+ (TargetActionPair *)pairWithTarget:(id)aTarget andAction:(SEL)selector;
- (void)fire;
@end

@implementation TargetActionPair
@synthesize target;
@synthesize action;

+ (TargetActionPair *)pairWithTarget:(id)aTarget andAction:(SEL)anAction
{
    TargetActionPair * newSelf = [[self alloc] init];
    [newSelf setTarget:aTarget];
    [newSelf setAction:anAction];
    return [newSelf autorelease];
}

- (void)fire
{
    [target performSelector:action];
}

@end

Met die klasse is het opslaan van je doel- / actieparen vrij eenvoudig:

MyCustomControl.h: 

#import "TargetActionPair.h"

@interface MyCustomControl : UIControl
{
    NSMutableArray * touchUpEventHandlers;
}

- (id)init;
- (void)dealloc;

- (void)addHandlerForTouchUp:(TargetActionPair *)handler;

@end

MyCustomControl.m: 

#import "TargetActionPair.h"

@implementation MyCustomControl

- (id)init
{
    if ((self = [super init]) == nil) { return nil; }
    touchUpEventHandlers = [[NSMutableArray alloc] initWithCapacity:0];
    return self;
}

- (void)dealloc
{
    [touchUpEventHandlers release];
}

- (void)addHandlerForTouchUp:(TargetActionPair *)handler
{
    [touchUpEventHandlers addObject:handler];
}

- (void) fireTargetsForTouchUpEvent
{
    [touchUpEventHandlers makeObjectsPerformSelector:@selector(fire)];
}

@end

Daarna zou het instellen van de besturing als volgt moeten gebeuren:

[instanceOfMyControl addHandlerForTouchUp:
         [TargetActionPair pairWithTarget:someController
                                andAction:@selector(touchUpEvent)];

14
2017-08-17 18:07