Swift - Cast Int na enum: Int

134

Jestem bardzo nowy w Swift (zacząłem w tym tygodniu) i migruję moją aplikację z Objective-C. Mam w zasadzie następujący kod w Objective-C, który działa dobrze:

typedef enum : int {
    MyTimeFilter1Hour = 1,
    MyTimeFilter1Day = 2,
    MyTimeFilter7Day = 3,
    MyTimeFilter1Month = 4,
} MyTimeFilter;

...

- (void)selectFilter:(id)sender
{
    self.timeFilterSelected = (MyTimeFilter)((UIButton *)sender).tag;
    [self closeAnimated:YES];
}

Podczas tłumaczenia na Swift wykonałem następujące czynności:

enum MyTimeFilter : Int {
    case OneHour = 1
    case OneDay = 2
    case SevenDays = 3
    case OneMonth = 4
}

...

@IBAction func selectFilter(sender: AnyObject) {
    self.timeFilterSelected = (sender as UIButton).tag as MyTimeFilter
    self.close(true)
}

W ten sposób otrzymuję błąd:

„Int” nie można zamienić na „MyTimeFilter”

Nie wiem, czy moje podejście (użycie właściwości tag) jest najlepsze, ale i tak muszę wykonać tego rodzaju rzutowanie w różnych miejscach w mojej aplikacji. Czy ktoś ma pomysł jak pozbyć się tego błędu?

Dzięki!

Marcos Duarte
źródło
2
Zauważ również, że zamiast tego (sender as UIButton)możesz po prostu zmienić sygnaturę metody, aby przyjęła UIButtonzamiast AnyObject.
Ben Leggiero

Odpowiedzi:

240

Użyj rawValueinicjatora: jest to inicjator automatycznie generowany dla enums.

self.timeFilterSelected = MyTimeFilter(rawValue: (sender as UIButton).tag)!

patrz: Swift Programming Language § Enumerations


UWAGA: Ta odpowiedź uległa zmianie. Wcześniejsze wersje języka Swift używają metody klasy fromRaw()do konwersji wartości surowych na wartości wyliczone.

Jeffery Thomas
źródło
Należy również pamiętać, że jeśli znacznik nadawcy nie odpowiada wartości wyliczenia, spowoduje to awarię z powodu rozszerzenia !.
Ben Leggiero
2
Powiedziałbym, że awaria to najlepszy sposób na złapanie błędu w tym przypadku.
XY
0

Szybki 5

@IBAction func selectFilter(sender: AnyObject) {
    timeFilterSelected = MyTimeFilter(rawValue: sender.tag)
 }
Alok
źródło
W ogóle nie odpowiedziałeś na pytanie, zamiast skomentować, że nie wiesz, dlaczego ktoś przegłosował, sprawdź pytanie i jeszcze raz swoją odpowiedź, dlaczego ktoś przegłosował. Cóż, ja też muszę to złagodzić.
Renetik
0

rozwijając odpowiedź Jeffery'ego Thomasa. dla bezpieczeństwa umieść instrukcję guard, rozpakuj rzutowanie przed jej użyciem, pozwoli to uniknąć awarii

   @IBAction func selectFilter(sender: AnyObject) {
     guard let filter = MyTimeFilter(rawValue: (sender as UIButton).tag) else { 
        return
    }
        timeFilterSelected = filter
     }
Abraham Gonzalez
źródło