Я пытаюсь преобразовать некоторые из моих классов Obj-C в Swift. И некоторые другие классы Obj-C все еще используют enum в этом преобразованном классе. Я искал в предварительной документации и не нашел, а может, пропустил. Есть ли способ использовать Swift enum в классе Obj-C? Или ссылку на документ этого вопроса?
Вот как я объявил свое перечисление в моем старом коде Obj-C и новом коде Swift.
мой старый код Obj-C:
typedef NS_ENUM(NSInteger, SomeEnum)
{
SomeEnumA,
SomeEnumB,
SomeEnumC
};
@interface SomeClass : NSObject
...
@end
мой новый код Swift:
enum SomeEnum: NSInteger
{
case A
case B
case C
};
class SomeClass: NSObject
{
...
}
Обновление: Из ответов. Это невозможно сделать в Swift более ранней версии, чем 1.2. Но согласно этому официальному блогу Swift . В Swift 1.2, выпущенном вместе с XCode 6.3, вы можете использовать Swift Enum в Objective-C, добавив @objc
передenum
objective-c
enums
swift
myLifeasdog
источник
источник
Ответы:
Начиная со Swift версии 1.2 (Xcode 6.3) вы можете. Просто добавьте к объявлению перечисления префикс
@objc
@objc enum Bear: Int { case Black, Grizzly, Polar }
Бесстыдно взято из блога Swift
В Objective-C это будет выглядеть как
Bear type = BearBlack; switch (type) { case BearBlack: case BearGrizzly: case BearPolar: [self runLikeHell]; }
источник
BearBlack
,BearGrizzly
иBearPolar
!Чтобы развернуть выбранный ответ ...
Можно совместно использовать перечисления стиля Swift между Swift и Objective-C, используя
NS_ENUM()
.Их просто нужно определить в контексте Objective-C, используя,
NS_ENUM()
и они доступны с использованием точечной нотации Swift.От использования Swift с какао и Objective-C
Цель-C
typedef NS_ENUM(NSInteger, UITableViewCellStyle) { UITableViewCellStyleDefault, UITableViewCellStyleValue1, UITableViewCellStyleValue2, UITableViewCellStyleSubtitle };
Swift
let cellStyle: UITableViewCellStyle = .Default
источник
if let a = MyEnum(rawValue: 12345)
где 12345 не является частью этого перечисления, результат не является необязательным, а является неким недопустимым перечислением.Из руководства Использование Swift с Какао и Objective-C :
Итак, нет, вы не можете использовать перечисление Swift в классе Objective-C.
источник
@objc
как @DanielGalasko указал в своем ответе ниже !!!@obj enum MyEnum: Int
оно будет нормально работать с файлами Objective-C, как упоминалось ранее. Если ваше перечисление объявлено с другим типом необработанного значения, например@obj enum MyOtherEnum: String
, вы не сможете использовать его в файлах Objective-CSwift 4.1, Xcode 9.4.1:
1) Swift enum должен иметь префикс
@objc
и иметьInt
тип:// in .swift file: @objc enum CalendarPermission: Int { case authorized case denied case restricted case undetermined }
2) Имя Objective-C - это имя перечисления + имя случая, например
CalendarPermissionAuthorized
:// in .m file: // point to something that returns the enum type (`CalendarPermission` here) CalendarPermission calPermission = ...; // use the enum values with their adjusted names switch (calPermission) { case CalendarPermissionAuthorized: { // code here break; } case CalendarPermissionDenied: case CalendarPermissionRestricted: { // code here break; } case CalendarPermissionUndetermined: { // code here break; } }
И, конечно же, не забудьте импортировать заголовок моста Swift в качестве последнего элемента в списке импорта файла Objective-C:
#import "MyAppViewController.h" #import "MyApp-Swift.h"
источник
Если вы предпочитаете сохранять коды ObjC как есть, вы можете добавить в свой проект вспомогательный файл заголовка:
Swift2Objc_Helper.h
в файле заголовка добавьте этот тип перечисления:
typedef NS_ENUM(NSInteger, SomeEnum4ObjC) { SomeEnumA, SomeEnumB };
В вашем .m файле может быть другое место для внесения изменений: для включения скрытого файла заголовка:
#import "[YourProjectName]-Swift.h"
замените [YourProjectName] названием вашего проекта. Этот файл заголовка предоставляет все классы @objc, определенные Swift, перечисляемые в ObjC.
Вы можете получить предупреждающее сообщение о неявном преобразовании из типа перечисления ... Это нормально.
Кстати, вы можете использовать этот вспомогательный файл заголовка для хранения некоторых кодов ObjC, таких как константы #define.
источник
Если вы (как и я) действительно хотите использовать перечисления String, вы можете создать специализированный интерфейс для objective-c. Например:
enum Icon: String { case HelpIcon case StarIcon ... } // Make use of string enum when available: public func addIcon(icon: Icon) { ... } // Fall back on strings when string enum not available (objective-c): public func addIcon(iconName:String) { addIcon(Icon(rawValue: iconName)) }
Конечно, это не даст вам удобства автозаполнения (если вы не определите дополнительные константы в среде objective-c).
источник
это может помочь немного больше
Постановка задачи : - У меня есть перечисление в быстром классе, к которому я обращаюсь из других быстрых классов, и теперь мне нужно получить доступ к нему из моего одного из объективных классов C.
Перед доступом к нему из класса objective-c: -
enum NTCType { case RETRYNOW case RETRYAFTER } var viewType: NTCType?
Изменения для доступа к нему из объектного класса c
@objc enum NTCType :Int { case RETRYNOW case RETRYAFTER }
и добавьте функцию, чтобы передать ей значение
@objc func setNtc(view:NTCType) { self.viewType = view; // assign value to the variable }
источник
Изучив это, я продолжал находить только частичные ответы, поэтому я создал полный пример приложения Swift, связанного с Objective C, которое имеет перечисления Swift, используемые кодом Objective C, и перечисления Objective C, используемые кодом Swift. Это простой проект Xcode, который можно запускать и экспериментировать. Он был написан с использованием Xcode 10.3 со Swift 5.0
Пример проекта
источник
enum SwAnimal
отсутствует ведущий@obj
Если вы пытаетесь наблюдать перечисление, которое выглядит так:
enum EnumName: String { case one = "One" case two = "Two" }
этот обходной путь мне помог.
Наблюдаемый класс:
@objc dynamic var observable: String?
создайте свой экземпляр перечисления следующим образом:
private var _enumName: EnumName? { didSet { observable = _enumName!.rawValue } }
Класс наблюдателя:
private var _enumName: EnumName?
private let _instance = ObservableClass()
Создайте
private var _enumObserver: NSKeyValueObservation = _instance.observe(\.observable, options: .new, changeHandler: { [weak self] (_, value) in guard let newValue = value.newValue else { return } self?._enumName = EnumName(rawValue: period)! })
Тогда это. Теперь каждый раз, когда вы меняете
_enumName
в наблюдаемом классе, соответствующий экземпляр в классе наблюдателя также будет немедленно обновляться.Это, конечно, упрощенная реализация, но она должна дать вам представление о том, как наблюдать несовместимые с KVO свойства.
источник