ios - Swift 设置内容压缩阻力

标签 ios swift autolayout

再次使用 Swift,我是否遗漏了什么?

我有这一行:

self.itemDescription?.setContentCompressionResistancePriority(UILayoutPriorityRequired, forAxis: UILayoutConstraintAxis.Vertical);

但是 Xcode 给我一个错误:

Undefined symbols for architecture i386: "_UILayoutPriorityRequired"

Swift 的另一个怪癖?

最佳答案

解决方案:将UILayoutPriorityRequired替换为1000

self.itemDescription?.setContentCompressionResistancePriority(1000, forAxis: UILayoutConstraintAxis.Vertical);

这不是错误。这是对如何将 Objective-C 库导入 Swift 的误解。应该了解 Swift 如何将代码(甚至来自 Apple UIKIt 库)从 Objective-C 导入 Swift。

UILayoutPriority 是一个 float 。在 Objective-C 中,已经为我们预定义了几个值。预定义值似乎是一个枚举。我们可能希望在 Swift 中可以使用相同的枚举。

文档似乎暗示了一个枚举:

SWIFT(文档)

typealias UILayoutPriority = Float

objective-c (文档)

enum {
   UILayoutPriorityRequired = 1000,
   UILayoutPriorityDefaultHigh = 750,
   UILayoutPriorityDefaultLow = 250,
   UILayoutPriorityFittingSizeLevel = 50,
};
typedef float UILayoutPriority;

但是在 Xcode 中,如果您要求查看其中一个枚举值的定义(例如 UILayoutPriorityRequired),您会看到它们实际上在头文件中定义为常量 float 。

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.

因此,尽管我们可能喜欢将预定义的布局优先级视为枚举值(如文档所示),但布局优先级并未真正定义为枚举;它们被定义为常量 float 。

对于任何了解 C 编程语言的人来说,存在不匹配的提示是 C 枚举可能仅包含 int 值。以下是合法的并将编译:

enum myEnum {
    JGCEnum_one = 1, // this is O.K.
    JGCEnum_two,
    JGCEnum_three
} JGCEnum;

但是我们不能将 float 定义为 C 枚举的值。以下将不会编译:

enum myEnum {
    JGCEnum_one = 1.5, // compile error
    JGCEnum_two,
    JGCEnum_three
} JGCEnum;

Objective-C 枚举与 C 枚举相同(Swift 枚举不同)。重要的是要知道我们是在处理实际的整数还是 float 。因为可以使用 NS_ENUM 宏定义整数,然后可以将其作为 Swift 枚举导入到 Swift 中。

iBook 说

Swift imports as a Swift enumeration any C-style enumeration marked with the NS_ENUM macro. This means that the prefixes to enumeration value names are truncated when they are imported into Swift, whether they’re defined in system frameworks or in custom code.

摘自:Apple Inc. “Using Swift with Cocoa and Objective-C.” iBooks

这意味着如果使用 NS_ENUM 宏将 UILayoutPriority 定义为整数,它将作为 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 中是否可用:

  1. 检查文档
  2. 检查 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);

引用资料

关于ios - Swift 设置内容压缩阻力,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27210527/

相关文章:

ios - 'NSInternalInconsistencyException',原因 : 'Only run on the main thread!' error

swift - AVAudioFile 中的 URL 为 nil

iOS 8 AutoLayout 改变 View 的位置

swift - 快速根据屏幕尺寸自动调整应用程序大小

ios - 使用 Storyboard 屏蔽 UIView 并赋予圆角?

html - 如何在 Swift 中匿名从 URL 获取 HTML 源代码?

ios - 无法在重构的 Storyboard上设置标签栏角标(Badge)值

ios - UITableViewCell用nib文件滑动更改内容

swift - 类型不能符合具有相同名称但可选的成员的协议(protocol)

iOS 'NSInternalInconsistencyException',原因 : 'UICollectionViewFlowLayout internal error