it-swarm.com.de

Parameter an addTarget übergeben: action: forControlEvents

Ich benutze addTarget: action: forControlEvents wie folgt:

[newsButton addTarget:self
action:@selector(switchToNewsDetails)
forControlEvents:UIControlEventTouchUpInside];

und ich möchte Parameter an meinen Selektor "switchToNewsDetails" übergeben. Das einzige, was mir gelingt, ist, den Absender (id) zu übergeben, indem ich schreibe:

action:@selector(switchToNewsDetails:)

Aber ich versuche Variablen wie Integer-Werte zu übergeben. So zu schreiben funktioniert nicht:

int i = 0;
[newsButton addTarget:self
action:@selector(switchToNewsDetails:i)
forControlEvents:UIControlEventTouchUpInside];

So zu schreiben funktioniert auch nicht:

int i = 0;
[newsButton addTarget:self
action:@selector(switchToNewsDetails:i:)
forControlEvents:UIControlEventTouchUpInside];

Jede Hilfe wäre dankbar :)

118
Pierre Espenan
action:@selector(switchToNewsDetails:)

Sie übergeben hier keine Parameter an die switchToNewsDetails:-Methode. Sie erstellen einfach eine Auswahltaste, mit der die Schaltfläche aufgerufen werden kann, wenn eine bestimmte Aktion ausgeführt wird (in Ihrem Fall aufrüsten). Steuerelemente können drei Arten von Selektoren verwenden, um auf Aktionen zu reagieren. Alle haben eine vordefinierte Bedeutung ihrer Parameter:

  1. ohne Parameter

    action:@selector(switchToNewsDetails)
    
  2. mit 1 Parameter, der die Steuerung angibt, die die Nachricht sendet

    action:@selector(switchToNewsDetails:)
    
  3. Mit 2 Parametern, die die Steuerung angeben, die die Nachricht sendet, und das Ereignis, das die Nachricht ausgelöst hat: 

    action:@selector(switchToNewsDetails:event:)
    

Es ist nicht klar, was genau Sie zu tun versuchen. Wenn Sie jedoch möchten, dass Sie jeder Schaltfläche einen bestimmten Detailindex zuweisen möchten, können Sie Folgendes tun:

  1. legen Sie für jede Schaltfläche eine Tag-Eigenschaft fest, die dem erforderlichen Index entspricht
  2. in der switchToNewsDetails:-Methode können Sie diesen Index abrufen und entsprechende Deatails öffnen:

    - (void)switchToNewsDetails:(UIButton*)sender{
        [self openDetails:sender.tag];
        // Or place opening logic right here
    }
    
170
Vladimir

Um benutzerdefinierte Parameter mit dem Klicken der Schaltfläche zu übergeben, müssen Sie nur SUBCLASS UIButton .

(ASR ist aktiviert, daher gibt es keine Freigaben im Code.)

Das ist myButton.h

#import <UIKit/UIKit.h>

@interface myButton : UIButton {
    id userData;
}

@property (nonatomic, readwrite, retain) id userData;

@end

Dies ist myButton.m

#import "myButton.h"
@implementation myButton
@synthesize userData;
@end

Verwendungszweck:

myButton *bt = [myButton buttonWithType:UIButtonTypeCustom];
[bt setFrame:CGRectMake(0,0, 100, 100)];
[bt setExclusiveTouch:NO];
[bt setUserData:**(insert user data here)**];

[bt addTarget:self action:@selector(touchUpHandler:) forControlEvents:UIControlEventTouchUpInside];

[view addSubview:bt];

Empfangsfunktion:

- (void) touchUpHandler:(myButton *)sender {
    id userData = sender.userData;
}

Wenn Sie möchten, dass ich mich an irgendeinem Teil des oben genannten Codes genauer verhalte, fragen Sie in Kommentaren nach.

63

Target-Action erlaubt drei verschiedene Formen der Aktionsauswahl:

- (void)action
- (void)action:(id)sender
- (void)action:(id)sender forEvent:(UIEvent *)event
19
Benoît

Benötigen Sie mehr als nur ein (int) via .tag? Verwenden Sie KVC!

Sie können beliebige Daten über das Schaltflächenobjekt selbst übergeben (indem Sie auf CALayers keyValue dict zugreifen). 


Setzen Sie Ihr Ziel so (mit dem ":")

[myButton addTarget:self action:@selector(buttonTap:) forControlEvents:UIControlEventTouchUpInside];

Fügen Sie Ihre Daten zu der Schaltfläche selbst hinzu (auch den .layer der Schaltfläche, der sich befindet):

NSString *dataIWantToPass = @"this is my data";//can be anything, doesn't have to be NSString
[myButton.layer setValue:dataIWantToPass forKey:@"anyKey"];//you can set as many of these as you'd like too!

Wenn Sie dann auf die Schaltfläche tippen, können Sie sie wie folgt überprüfen:

-(void)buttonTap:(UIButton*)sender{

    NSString *dataThatWasPassed = (NSString *)[sender.layer valueForKey:@"anyKey"];
    NSLog(@"My passed-thru data was: %@", dataThatWasPassed);

}
12
Albert Renshaw

Ich habe eine Lösung basierend auf den obigen Informationen gemacht. Ich setze einfach den Titlelabel.text auf die Zeichenfolge, die ich übergeben möchte, und setze die Titlelabel.hidden = YES

So was :

UIButton *imageclick = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
imageclick.frame = photoframe;
imageclick.titleLabel.text = [NSString stringWithFormat:@"%@.%@", ti.mediaImage, ti.mediaExtension];
imageclick.titleLabel.hidden = YES;

Auf diese Weise ist keine Vererbung oder Kategorie erforderlich und es gibt keinen Speicherverlust

7

Ich habe mehrere Tasten für jede Telefonnummer in einem Array erstellt, sodass für jede Taste eine andere Telefonnummer zum Anrufen erforderlich war. Ich habe die setTag-Funktion verwendet, als ich mehrere Schaltflächen innerhalb einer for-Schleife erstellte:

for (NSInteger i = 0; i < _phoneNumbers.count; i++) {

    UIButton *phoneButton = [[UIButton alloc] initWithFrame:someFrame];
    [phoneButton setTitle:_phoneNumbers[i] forState:UIControlStateNormal];

    [phoneButton setTag:i];

    [phoneButton addTarget:self
                    action:@selector(call:)
          forControlEvents:UIControlEventTouchUpInside];
}

Dann habe ich in meiner Aufrufmethode dieselbe for-Schleife und eine if-Anweisung verwendet, um die richtige Telefonnummer auszuwählen:

- (void)call:(UIButton *)sender
{
    for (NSInteger i = 0; i < _phoneNumbers.count; i++) {
        if (sender.tag == i) {
            NSString *callString = [NSString stringWithFormat:@"telprompt://%@", _phoneNumbers[i]];
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:callString]];
        }
    }
}
5
rjdunwoody91

Es gibt noch eine andere Möglichkeit, indexPath der Zelle zu erhalten, in der die Schaltfläche gedrückt wurde:

mit dem üblichen Aktionswähler wie:

 UIButton *btn = ....;
    [btn addTarget:self action:@selector(yourFunction:) forControlEvents:UIControlEventTouchUpInside];

und dann in deineFunktion:

   - (void) yourFunction:(id)sender {

    UIButton *button = sender;
    CGPoint center = button.center;
    CGPoint rootViewPoint = [button.superview convertPoint:center toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:rootViewPoint];
    //the rest of your code goes here
    ..
}

da Sie einen Indexpfad erhalten, wird dieser viel einfacher.

2
Anton Lisitsyn

Da hier für die Lösung viele Möglichkeiten genannt werden, gilt die Ausnahme-Kategorie.

Verwenden Sie das category-Feature, um definierte (integrierte) Elemente in Ihrem .__ zu erweitern. anpassbares Element.

Zum Beispiel (ex):

@interface UIButton (myData)

@property (strong, nonatomic) id btnData;

@end

in Ihrer Ansicht Controller.m

 #import "UIButton+myAppLists.h"

UIButton *myButton = // btn intialisation....
 [myButton set btnData:@"my own Data"];
[myButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];

Eventhandler:

-(void)buttonClicked : (UIButton*)sender{
    NSLog(@"my Data %@", sender. btnData);
}
2
Kumar KL

Dies behebte mein Problem, aber es stürzte ab, wenn ich mich nicht geändert hatte 

action:@selector(switchToNewsDetails:event:)                 

zu

action:@selector(switchToNewsDetails: forEvent:)              
1
iphaaw

Siehe meinen Kommentar oben und ich glaube, Sie müssen NSInvocation verwenden, wenn es mehr als einen Parameter gibt

weitere Informationen zu NSInvocation hier

http://cocoawithlove.com/2008/03/construct-nsinvocation-for-any-message.html

1
Aaron Saunders

Sie können target-action durch einen Abschluss (Block in Objective-C) ersetzen, indem Sie einen Helper-Closure-Wrapper (ClosureSleeve) hinzufügen und ihn als zugehöriges Objekt zum Steuerelement hinzufügen, damit er erhalten bleibt. Auf diese Weise können Sie beliebige Parameter übergeben.

Swift 3

class ClosureSleeve {
    let closure: () -> ()

    init(attachTo: AnyObject, closure: @escaping () -> ()) {
        self.closure = closure
        objc_setAssociatedObject(attachTo, "[\(arc4random())]", self, .OBJC_ASSOCIATION_RETAIN)
    }

    @objc func invoke() {
        closure()
    }
}

extension UIControl {
    func addAction(for controlEvents: UIControlEvents, action: @escaping () -> ()) {
        let sleeve = ClosureSleeve(attachTo: self, closure: action)
        addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents)
    }
}

Verwendungszweck:

button.addAction(for: .touchUpInside) {
    self.switchToNewsDetails(parameter: i)
}
1
Marián Černý

Wenn Sie nur den Text für das leftBarButtonItem ändern möchten, das vom Navigationscontroller zusammen mit der neuen Ansicht angezeigt wird, können Sie den Titel der aktuellen Ansicht vor dem Aufruf von pushViewController auf den gewünschten Text ändern und ihn im viewHasDisappered-Rückruf für zukünftige Vorführungen von wiederherstellen die aktuelle Ansicht.

Dieser Ansatz behält die Funktionalität (popViewController) und das Erscheinungsbild des angezeigten Pfeils bei.

Es funktioniert für uns zumindest mit iOS 12, gebaut mit Xcode 10.1 ...

0
Bubu

Ich habe UIButton in CustomButton subclassed und füge eine Eigenschaft hinzu, in der ich meine Daten speichere. Also rufe ich die Methode: (CustomButton *) sender auf und in der Methode lese ich nur meine Daten sender.myproperty.

Beispiel CustomButton:

@interface CustomButton : UIButton
@property(nonatomic, retain) NSString *textShare;
@end

Methodenaktion:

+ (void) share: (CustomButton*) sender
{
    NSString *text = sender.textShare;
    //your work…
}

Aktion zuweisen

    CustomButton *btn = [[CustomButton alloc] initWithFrame: CGRectMake(margin, margin, 60, 60)];
    // other setup…

    btnWa.textShare = @"my text";
    [btn addTarget: self action: @selector(shareWhatsapp:)  forControlEvents: UIControlEventTouchUpInside];
0
iNiko84