我试图将我的一些Obj-C类转换为Swift。还有一些其他的Obj-C类仍在转换类中使用枚举。我在Pre-Release Docs中搜索过但无法找到它或者我错过了它。有没有办法在Obj-C类中使用Swift枚举?或者链接到这个问题的文档?
这就是我在旧的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 Blog。在与XCode 6.3一起发布的Swift 1.2中,您可以在Objective-C中使用Swift Enum,在@objc
前面添加enum
答案 0 :(得分:194)
从Swift 1.2版(Xcode 6.3)开始,你可以。只需在枚举声明前添加@objc
@objc enum Bear: Int {
case Black, Grizzly, Polar
}
无耻地取走
在Objective-C中,这看起来像
Bear type = BearBlack;
switch (type) {
case BearBlack:
case BearGrizzly:
case BearPolar:
[self runLikeHell];
}
答案 1 :(得分:31)
来自Using Swift with Cocoa and Objective-C指南:
必须使用@objc属性标记Swift类或协议 可在Objective-C中访问和使用。 [...]
您可以访问类或协议中的任何内容 标有@objc属性,只要它兼容 Objective-C的。这不包括仅限Swift的功能,例如列出的功能 这里:
泛型元组/ 在Swift中定义的枚举 /中定义的结构 在Swift / Global变量中定义的Swift / Top-level函数 在Swift / Swift风格的可变参数/嵌套类型中定义的Swift / Typealiases / 咖喱功能
所以,不,你不能在Objective-C类中使用Swift枚举。
答案 2 :(得分:29)
扩展所选答案......
可以使用NS_ENUM()
在Swift和Objective-C之间共享Swift样式枚举。
它们只需要使用NS_ENUM()
在Objective-C上下文中定义,并使用Swift点表示法提供它们。
来自 Using Swift with Cocoa and Objective-C
Swift导入作为Swift枚举的任何标有
NS_ENUM
宏的C样式枚举。这意味着枚举值名称的前缀在导入Swift时会被截断,无论它们是在系统框架中定义还是在自定义代码中定义。
目标-C
typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle
};
夫特
let cellStyle: UITableViewCellStyle = .Default
答案 3 :(得分:2)
如果您希望将ObjC代码保留为原样,则可以在项目中添加帮助程序头文件:
Swift2Objc_Helper.h
头文件中的添加此枚举类型:
typedef NS_ENUM(NSInteger, SomeEnum4ObjC)
{
SomeEnumA,
SomeEnumB
};
.m文件中可能还有其他地方可以进行更改:包含隐藏的头文件:
#import "[YourProjectName]-Swift.h"
用您的项目名称替换[YourProjectName]。这个头文件公开了所有Swift定义的@objc类,枚举到ObjC。
您可能会收到有关从枚举类型隐式转换的警告消息......没关系。
顺便说一句,您可以使用此头文件助手文件来保留一些ObjC代码,例如#define常量。
答案 4 :(得分:0)
如果你(像我一样)真的想要使用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环境中定义其他常量)。
答案 5 :(得分:0)
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"
答案 6 :(得分:0)
这可能会帮助更多
问题陈述:-我在swift类中有枚举,我正在从其他swift类访问它,现在我需要从我的目标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
}
答案 7 :(得分:0)
研究此问题后,我一直只找到部分答案,因此我创建了一个完整的示例,该示例连接到Objective C,其中包含Objective C代码使用的Swift枚举和Swift代码使用的Objective C枚举。这是一个可以运行和试验的简单Xcode项目。它是使用Xcode 10.3和Swift 5.0编写的
答案 8 :(得分:0)
如果您尝试观察的枚举看起来像这样:
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不兼容的属性。