我试图把一些3D触摸到应用程序中,我已经在运行到一个奇怪的问题forceTouchCapability
检查返回nil
上viewDidLoad
而不是在viewWillAppear/viewDidAppear
.
我知道这只适用于iOS 9+,因此我添加了检查以验证traitCollection
视图控制器上的属性是否响应,forceTouchCapability
如下所示:
- (void)loadView { self.view = [[MyView alloc] init]; } - (void)viewDidLoad { [super viewDidLoad]; // Checking the force touch availability here if ([self.traitCollection respondsToSelector:@selector(forceTouchCapability)] && self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) { // This won't get called because forceTouchCapability is returning nil // which corresponds to UIForceTouchCapabilityUnknown [self registerForPreviewingWithDelegate:self sourceView:self.view]; } }
在LLDB中,在if
语句中有一个断点,输入对应的po [self.traitCollection forceTouchCapability]
返回值.但是,本身并非如此.nil
UIForceTouchCapabilityUnknown
traitCollection
nil
根据UIForceTouchCapabilityUnknown的文档:
UIForceTouchCapabilityUnknown: The availability of 3D Touch is unknown. For example, if you create a view but have not yet added it to your app’s view hierarchy, the view’s trait collection has this value.
此时是否未将视图添加到层次结构中?
我很好奇是否有人遇到过这个问题以及如何解决这个问题?我想避免添加这个,viewDidAppear
因为这可以被调用相当多.
如果它有帮助,我在iOS 9.1上用Xcode 7.2在6S上运行它
视图尚未添加到视图层次结构中.您可以通过在调试控制台中检查superview来轻松查看
(lldb) po self.view.superview nil
如果这就是您所看到的,那么该视图尚未添加到层次结构中:所以您必须将检查放在其他位置.
这有点令人困惑,因为在Apple的ViewControllerPreview示例应用程序中它位于viewDidLoad中.但它确实应该在traitCollectionDidChange:中,因为那时你确定该视图已被添加到应用程序的层次结构中.
这是我使用的代码(适用于iOS 8,如果你不需要支持那么随意移动外部条件).
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { [super traitCollectionDidChange:previousTraitCollection]; if ([self.traitCollection respondsToSelector:@selector(forceTouchCapability)]) { if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) { // retain the context to avoid registering more than once if (!self.previewingContext) { self.previewingContext = [self registerForPreviewingWithDelegate:self sourceView:self.view]; } } else { [self unregisterForPreviewingWithContext:self.previewingContext]; self.previewingContext = nil; } } }
这样做的另一个好处是,如果用户在应用程序运行时更改其3D Touch设置,您的视图将被注册/取消注册.