2017-01-06 90 views
12

Podsunięto podklasę Swift 3 a UIButton, która jest napisana w Objective-C.Argument "# selector" nie odnosi się do metody @objc, właściwości lub inicjalizatora

Gdy próbuję dodać cel, nie jest on z kodem błędu:

class ActionButton: JTImageButton { 

    func action() { 

    } 

    func configure()) { 
     // ... 
     self.addTarget(self, action: #selector(self.action()), for: .touchUpInside) 
     // error: 
     // Argument of '#selector' does not refer to an '@objc' method, property, or initializer 

    } 
} 
+2

Twoja metoda 'action konflikty z' działania (dla :, forKey:) '' UIView' metoda, porównaj http://stackoverflow.com/questions/35658334/how-do-i-resolve -znaczny-użycie-kompilacji-z-swift-selektor-składnia. –

Odpowiedz

13

Wszystko co musisz zrobić, to zaznaczyć func jako @objc i nie ma potrzeby odniesienia self lub nawiasie

class ActionButton: JTImageButton { 

    @objc func btnAction() { 

    } 

    func configure() { 
     // ... 
     self.addTarget(self, action: #selector(btnAction), for: .touchUpInside) 
     // error: 
     // Argument of '#selector' does not refer to an '@objc' method, property, or initializer 

    } 
} 

Można nawet zrobić to private jeśli chcesz

+0

Dzięki, ale mówi: "Niejednoznaczne użycie" działania ", gdy zaimplementowałem twoje podejście? Edycja: zmiana nazwy 'action()' na 'action2()' pomogło. – MJQZ1347

+0

Dziwne. Zmieniłem nazwę metody na "btnAction" i nie daje mi tego błędu. Może coś wspólnego z nazwą funkcji, 'action'? Zaktualizowałem swoją odpowiedź, aby pokazać, co mam na myśli. – cjrieck

+1

Nie potrzebujesz '@ objc', ponieważ klasa już dziedziczy z NSObject. –

1

Zamiast mówić self.action() użyć ActionButton.action().

2

Dodana z komentarzy do innej odpowiedzi: Funkcja func() to nie tylko kiepski wybór dla nazwy i działania funkcji, ale nie kompilacji. (Można go użyć jako parametru funkcji wejściowej, co robię dla jasności podczas przekazywania w celu/akcji do init(), który ustawia te rzeczy.) Zamieniam to na MyAction() dla jasności.


Spróbuj tego:

self.addTarget(self, action: #selector(MyAction), for: .touchUpInside) 

Wspomniany o wiele lepiej konstrukcja jest przeniesienie funkcji MyAction() do przycisku SuperView, jak to sprawia, że ​​rzeczy bardziej związane z podstawowego projektu MVC:

Superview:

let myButton = ActionButton() 
// include other button setup here 
myButton.addTarget(self, action: #selector(MyAction), for: .touchUpInside 

func action(_ sender: ActionButton) { 
    // code against button tap here 
} 

Alternatywne kodowanie do tego, utrzymując "działanie()" meto d w kontrolerze widoku, ale porusza tylko z „addTarget” do przycisku:

self.addTarget(superview?, action(superview?.MyAction), for: .touchUpInside) 

Dlaczego prośbą rozważyć przesunięcie „MyAction()” metoda do SuperView? Dwukrotnie:

  • Kontroluje on nie tylko przycisk, ale wszystkie inne widoki w jego widoku i zwykle współdziałają ze sobą za pomocą kontrolera widoku.
  • Powoduje, że przycisk jest bardziej przydatny do wielokrotnego użytku w innych sytuacjach.
13

problemu jest to, że w #selector(self.action()), self.action() jest to wywołanie metody . Nie chcesz, aby zadzwonił pod numer; chcesz nazwa metody. Zamiast tego powiedz: #selector(action): utracisz nawiasy, a także nie ma potrzeby stosowania self.

+1

Ponadto, jest on sprzeczny z metodą 'action (for :, forKey:)' z 'UIView'. '#selector (akcja)' daje "niejednoznaczny użytek", a twoje pytania i odpowiedzi http://stackoverflow.com/questions/35658334/how-do-i-resolve-ambiguous-use-of-compile-error-with-swift -selector-składnia dotyczy. –

+1

@MartinR Cool! Tak, "akcja" była bardzo kiepskim wyborem nazwy ... – matt

+0

tak 'func action() { }' musi być repalced z inną nazwą jak @matt powiedział inaczej zakończysz z 'Niejednoznacznym użyciem akcji () 'błąd. –

2

Dodanie @objc słowa kluczowego na początku metody, która jest idealna, ale nadal mam ten błąd. Wreszcie, dowiedziałem się, że rozwiązanie jest następujące: enter image description here

Za metodą jest parę zbędnych nawiasów, jak pokazano powyżej. Powinienem to usunąć i wszystko działało dobrze.

+0

To nie odpowiada na potrzeby pytania. Nie odpowiadaj również na odpowiedzi. – paper1111

+0

Oto odpowiedź, z którą się zetknąłem i ktoś może się z nią spotkać. I rozwiązałem go, usuwając nawias. Dlaczego ponosiłeś moją odpowiedź? To jest PRAWDZIWA odpowiedź! @ paper1111 –

0

Jeśli nie masz nic przeciwko dodaniu dodatkowej funkcji, możesz zagnieździć tę funkcję.

self.addTarget(self, action: myAction, for: UIControlledEvent) 

myAction(){ 
    @obj.methodYouWantToCall(//parameters//) 
}