2016-09-22 19 views
15

Xcode 8 przeciągnij i połączyć @IBAction nieprawidłowo dodaje „WithSender” na inspektora połączenie IBXcode 8 przeciągnij i połączyć @IBAction nieprawidłowo dodaje „WithSender” na inspektora połączenie IB

Dlatego muszę zmienić nazwę metody do czegoś podobnego

@IBAction func tappedConfirmButtonWithSender (nadawca: AnyObject) {}

nie powinno być ?:

@IBAction func tappedConfirmButton (nadawca: AnyObject) {}

Czy to moja wina, czy jest to błąd?

Odpowiedz

31

Właśnie trafiłem to. Wygląda na to, że jest to błąd związany ze starszym kodem Swift 2.3, z powodu wycieku Swift 3. Znalazłem kluczowe odpowiedzi: in the dev forums oraz kilka dodatkowych ustaleń przeze mnie i mojego współpracownika.

Obejście problemu: Zmień argument (sender: AnyObject) na (_ sender: AnyObject). Otrzymasz ostrzeżenie na zmodyfikowanej linii, którą możesz bezpiecznie zignorować.

[AKTUALIZACJA - kolejny obejście: Jabłko odpowiedzieliście na moje raportu o błędzie i zaproponował inne obejście: opisywanie sposobu @IBAction z @objc. Nie potwierdziłem jeszcze, że to działa.]

Co się dzieje: Wygląda na to, że jest błąd w planszach Xcode 8. Moja interpretacja jest taka, że ​​omyłkowo analizuję metody Swift 2 @IBAction tak, jakby były Swift 3, a następnie próbuję przekonwertować je z powrotem do Swift 2.

Zobaczmy! W Swift 3, w przeciwieństwie Swift 2, biorąc pod uwagę metody zadeklarowane jako:

@IBAction func foo(sender: AnyObject) 

etykieta sender argument jest faktycznie częścią nazwy metody i zostanie włączone połączeń do tej metody. W Swift 2 oczywiście pierwszy argument nie dostaje domyślnie etykiety. W Swift 2 możesz zadzwonić pod numer foo(myButton); w Swift 3 można nazwać foo(sender: myButton).

Xcode 8 omyłkowo czyta tę funkcję na sposób Swift 3. Wzorzec do wielkiej zmiany nazw interfejsów API polega na tym, że nazwy metody Swift 2 w postaci doSomethingWithParam(quuz) zostały przepisane dla Swift 3 jako doSomething(param: quuz). Xcode zakłada, że ​​tak właśnie się stało, więc w błędnej próbie wyprowadzenia oryginalnej nazwy Swift 2, dodaje ona WithSender z powrotem na końcu nazwy metody. Podejście obejścia polega na tym, że sygnatura metody Swift 3 jest identyczna z sygnaturą Swift 2. (Nie wiem, dlaczego @objc adnotacja rozwiązuje również problem, według Apple.)

[Edytowane wielokrotnie ze zmianami w obejściach.]

+4

Dzięki za szczegółową aktualizację! Pomyślałem, że coś takiego się dzieje. Moje bieżące ** obejście ** polega na ** podłączeniu @IBAction, a następnie spojrzeniu na faktyczny wylot (prawy klik na elemencie widoku) na Interface Builder **, który pokazuje literał ciągu dla selektora na ** czarnym pop-upu ** i dlatego muszę ** zaktualizować nazwę funkcji, aby to pasować. ** – moyoteg

+0

Dzięki za rozwiązanie tego problemu. Nie mogę uwierzyć w ilość błędów i problemów, które pojawiły się w Xcode 8 i Swift 3. Przed aktualizacją miałem gotowy projekt. Spędziłem nie mniej niż 8 godzin, naprawiając rzeczy, które sprawiają, że projekt działa po aktualizacji. Wszystko, od brakujących plików nagłówkowych, po zależność od podziale po problemy z układem IB Auto, a teraz od obsługi zdarzeń. SMH – itsben

+1

Dzięki za pracę i wyjaśnienia, jabłko zasugerowało, że "dodanie adnotacji @objc" nie działa dla mnie. więc myślę, że powinniśmy teraz trzymać się "_". –

1

I w końcu znaleźć temat z problemem mam. Zacząłem wątpić w siebie.

Zaproponuję jeszcze jedno obejście dla zainteresowanych.

Otwórz scenopis prawym przyciskiem myszy -> Otwórz jako -> Kod źródłowy.

Znajdź swoją metodę w pliku xml i usuń dodatek WithSender, aby dopasować nazwę swojej metody do swojej klasy.

W ten sposób możesz nadać nazwę swojej metody tak, jak chcesz.

To tyle ...

0

miałem ten sam problem podczas pracy z Xcode 8. It may be bug.

Screenshot 1

Poniżej obejścia tego problemu:

  1. Delete the outlet connection z pliku IB

  2. Utwórz new outlet, naciskając Ctrl i przeciągając. Spowoduje to otwarcie wyskakującego okienka, jak pokazano poniżej.

Screenshot 2

Wybierz Połączenie jako Action i wprowadź name of action. Następnie wybierz Type.

  1. Naciśnij przycisk Connect. Spowoduje to utworzenie nowej IBAction w pliku Swift. Mimo że okrąg dla IBAction może nie być wypełniony, ale jest podłączony.

Screenshot 4

0

Można spróbować ją zmienić w następujący sposób:

@IBAction func tappedConfirmButton(_ sender: AnyObject) 
{ 

} 

Powodzenia!