Я пытаюсь преобразовать часть моего класса Obj-C в Swift. И некоторые другие классы Obj-C по-прежнему используют enum в этом преобразованном классе. Я искал в Документах перед выпуском и не мог найти его или, может быть, пропустил его. Есть ли способ использовать Swift enum в Obj-C Class? Или ссылка на документ этой проблемы?
Вот как я объявил свое перечисление в моем старом коде Obj-C и новом коде Swift.
мой старый код Obj-C:
typedef NS_ENUM(NSInteger, SomeEnum)
{
SomeEnumA,
SomeEnumB,
SomeEnumC
};
@interface SomeClass : NSObject
...
@end
мой новый Swift Code:
enum SomeEnum: NSInteger
{
case A
case B
case C
};
class SomeClass: NSObject
{
...
}
Обновление: Из ответов. Это не может быть сделано в более ранней версии Swift, чем 1.2. Но в соответствии с этим официальным Swift Blog. В Swift 1.2, выпущенном вместе с XCode 6.3, вы можете использовать Swift Enum в Objective-C, добавив @objc
перед enum
С Swift версии 1.2 (Xcode 6.3) вы можете. Просто префикс объявления enum с помощью @objc
@objc enum Bear: Int {
case Black, Grizzly, Polar
}
Бесстыдно взято из Swift Blog
В Objective-C это будет выглядеть как
Bear type = BearBlack;
switch (type) {
case BearBlack:
case BearGrizzly:
case BearPolar:
[self runLikeHell];
}
BearBlack
-c значениями перечисления будут называться BearBlack
, BearGrizzly
и BearPolar
!
Из Использование Swift с Cocoa и Objective-C:
Класс Swift или протокол должны быть отмечены атрибутом @objc для быть доступным и использоваться в Objective-C. [...]
У вас есть доступ к чему-либо в классе или протоколе, который отмеченный атрибутом @objc, если он совместим с Objective-C. Это исключает функции Swift, такие как перечисленные здесь:
Generics Tuples/ Перечисления, определенные в Swift/Структуры, определенные в Функции Swift/Top-level, определенные в переменных Swift/Global, определенных в Swift/Typealiases, определенные в вариациях Swift/Swift/Вложенные типы/ Выполненные функции
Итак, нет, вы не можете использовать переименование Swift в классе Objective-C.
Чтобы расширить выбранный ответ...
Можно разделить переменные стиля Swift между Swift и Objective-C с помощью NS_ENUM()
.
Их просто нужно определить в контексте Objective-C, используя NS_ENUM()
, и они становятся доступными с использованием нотации Swift.
Из Использование Swift с Cocoa и Objective-C
Быстрое импортирование в виде перечисления Swift перечисляет C-стиль, обозначенный макросом
NS_ENUM
. Это означает, что префиксы для имен значений перечисления усекаются, когда они импортируются в Swift, независимо от того, определены ли они в системных рамках или в пользовательском коде.
Objective-C
typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle
};
Свифта
let cellStyle: UITableViewCellStyle = .Default
Если вы предпочитаете сохранять коды ObjC как-они-есть, вы можете добавить в проект вспомогательный заголовочный файл:
Swift2Objc_Helper.h
в файле заголовка добавьте этот тип перечисления:
typedef NS_ENUM(NSInteger, SomeEnum4ObjC)
{
SomeEnumA,
SomeEnumB
};
В вашем файле .m может быть другое место, чтобы внести изменения: включить скрытый заголовочный файл:
#import "[YourProjectName]-Swift.h"
замените [YourProjectName] своим именем проекта. Этот файл заголовка предоставляет все Swift определенные классы @objc, перечисления для ObjC.
Вы можете получить предупреждающее сообщение о неявном преобразовании из типа перечисления... Это нормально.
Кстати, вы можете использовать этот вспомогательный файл заголовка для хранения некоторых кодов ObjC, таких как #define константы.
Swift 4.1, Xcode 9.4.1:
1) Swift перечисление должно иметь префикс @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"
Если вы (как и я) действительно хотите использовать перечисления 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).