解决方案:将UILayoutPriorityRequired替换为1000
self.itemDescription?.setContentCompressionResistancePriority(1000, forAxis: UILayoutConstraintAxis.Vertical);
这不是错误。这是对如何将 Objective-C 库导入 Swift 的误解。应该理解 Swift 是如何将代码(甚至来自 Apple UIKIt 库)从 Objective-C 导入到 Swift 中的。
UILayoutPriority 是一个浮点数。在 Objective-C 中,已经为我们预定义了几个值。预定义的值似乎是一个枚举。我们可能期望在 Swift 中也可以使用相同的枚举。
文档似乎暗示了一个枚举:
SWIFT(文档)
typealias UILayoutPriority = Float
OBJECTIVE-C(文档)
enum {
UILayoutPriorityRequired = 1000,
UILayoutPriorityDefaultHigh = 750,
UILayoutPriorityDefaultLow = 250,
UILayoutPriorityFittingSizeLevel = 50,
};
typedef float UILayoutPriority;
但在 Xcode 中,如果您要求查看这些枚举值之一的定义(例如 UILayoutPriorityRequired),您会看到它们实际上在头文件中定义为常量浮点数。
OBJECTIVE-C(头文件)
typedef float UILayoutPriority;
static const UILayoutPriority UILayoutPriorityRequired NS_AVAILABLE_IOS(6_0) = 1000; // A required constraint. Do not exceed this.
static const UILayoutPriority UILayoutPriorityDefaultHigh NS_AVAILABLE_IOS(6_0) = 750; // This is the priority level with which a button resists compressing its content.
static const UILayoutPriority UILayoutPriorityDefaultLow NS_AVAILABLE_IOS(6_0) = 250; // This is the priority level at which a button hugs its contents horizontally.
因此,尽管我们可能希望将预定义的布局优先级视为枚举值(如文档所示),但布局优先级并未真正定义为枚举;它们被定义为常量浮点数。
对于任何了解 C 编程语言的人来说,一个不匹配的提示是 C 枚举可能只包含 int 值。以下是合法的,将编译:
enum myEnum {
JGCEnum_one = 1, // this is O.K.
JGCEnum_two,
JGCEnum_three
} JGCEnum;
但我们不能将浮点数定义为 C 枚举的值。以下将无法编译:
enum myEnum {
JGCEnum_one = 1.5, // compile error
JGCEnum_two,
JGCEnum_three
} JGCEnum;
Objective-C 枚举与 C 枚举相同(Swift 枚举不同)。重要的是要知道我们是在处理实际的整数还是浮点数。因为整数可以使用 NS_ENUM 宏定义,然后可以作为 Swift 枚举导入 Swift。
iBook 说
Swift 将任何标有 NS_ENUM 宏的 C 样式枚举作为 Swift 枚举导入。这意味着枚举值名称的前缀在导入 Swift 时会被截断,无论它们是在系统框架中定义还是在自定义代码中定义。
摘自:Apple Inc. “Using Swift with Cocoa and Objective-C.” iBooks
这意味着如果 UILayoutPriority 被定义为使用 NS_ENUM 宏的整数,它会作为 Swift 枚举导入到 Swift 中。 UILayoutConstraintAxis 就是这种情况。
SWIFT(文档)
enum UILayoutConstraintAxis : Int {
case Horizontal
case Vertical
}
OBJECTIVE-C(文档)
enum {
UILayoutConstraintAxisHorizontal = 0,
UILayoutConstraintAxisVertical = 1
};
typedef NSInteger UILayoutConstraintAxis;
查看 Objective-C 头文件可以确认文档所说的内容。
OBJECTIVE-C(头文件)
//
// UIView Constraint-based Layout Support
//
typedef NS_ENUM(NSInteger, UILayoutConstraintAxis) {
UILayoutConstraintAxisHorizontal = 0,
UILayoutConstraintAxisVertical = 1
};
因此,至少有两种方法可以知道您习惯于在 Objective-C 中使用的预定义值是否在 Swift 中可用:
- 查看文档
- 检查 Objective-C 中的头文件(通过右键单击该值然后选择“跳转到定义”找到)
还有另一种方法可以查看您习惯使用的 typedef 是常量还是枚举。在代码中,测试看看常量的地址是否存在。常量有一个内存地址,而枚举没有。请参阅下面的代码。
// this line will compile and run just fine.
// UILayoutPriorityDefaultHigh is a constant and has a memory address
// the value will be true if the device is running iOS 6.0 or later
// and false otherwise
BOOL predefinedValueIsAvailable = (NULL != &UILayoutPriorityDefaultHigh);
// this line will not compile
// UILayoutConstraintAxisHorizontal is an enum (NOT a constant)
// and does not have a memory address
predefinedValueIsAvailable = (NULL != &UILayoutConstraintAxisHorizontal);
参考文献