Skip to the content.

对于 Mac Catalyst 不支持的控件的解决方案

Table of Contents

问题

最近在做 iOS 通用程序时, 遇到了一个错误, 是使用 UIDatePicker 引起的, 在 Inline 模式下点击左上角的日期, 将会切换至滚动选择器, 也就是 UIPickerView 来展示功能, 然而就是它 UIPickerView 却在 MacCatalyst 中不支持.🥲

以下是报错堆栈信息:

[General] _UIDatePickerView is not supported when running Catalyst apps in the Mac idiom.
[General] (
	0   CoreFoundation     0x00007fff204a883b __exceptionPreprocess + 242
	1   libobjc.A.dylib    0x00007fff201e0d92 objc_exception_throw + 48
	2   UIKitCore          0x00007fff45382e32 -[UIView(UICatalystMacIdiomUnsupported_Internal) _throwForUnsupportedNonMacIdiomBehaviorWithReason:] + 0
	3   UIKitCore          0x00007fff4508e1c4 -[UIPickerView _didMoveFromWindow:toWindow:] + 191    

我们先上解决方法, 后续值得探究一番.

解决方法

针对我的问题, 查看报错的堆栈, 可以看到是 UIPickerView 在被移动到前端显示时报的这个错误, 那么我们针对 UIPickerView, 让其遇到不支持的方法时, 不 throw exception. 当然大家可以看到堆栈中其实是 UIView 的分类方法丢出的, 我们也可以直接对 UIView 操作. 我这里仅针对 UIPickerView 提前调用如下方法:

// 注意这里初始化 Selector 方法时, 套了 2 层括号是因为 Xcode 默认会扫描不到这个 Objective-C 方法(当然了, 这是私有 API, 能搜到才有鬼了.👻), 多加一层静默掉那个警告罢了.
UIPickerView.perform(Selector(("_setAllowsUnsupportedMacIdiomBehavior:")), with: 1)

探究

问题从何而来

参考文章:

Forbidden Controls in Catalyst: Optimize Interface for Mac