是否可以根据iOS的版本继承类?
我有代码:
let cell1 = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier1", for: indexPath) as! MyCell1
// ....
let cell2 = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier2", for: indexPath) as! MyCell2
对我来说,对于iOS版本<11.0使用带有第三方框架的类,但在iOS版本中> = 11.0是使用标准解决方案。
class MyCell1: BaseTableViewCell {
// Different code
}
class MyCell2: BaseTableViewCell {
// Different code
}
// Available for iOS >= 11.0
class BaseTableViewCell: UITableViewCell {
}
// Available for all other versions
class BaseTableViewCell: SwipeTableViewCell {
}
在第三方框架中,我有这个类:
class SwipeTableViewCell: UITableViewCell {
// Different code
}
实质上,我想为 iOS <11.0 添加一个层间类
是否可以根据iOS的版本继承类?
基类是在编译代码时建立的,而不是在运行时建立的,因此无法根据运行代码的操作系统版本切换基类。
对我来说,对于iOS版本<11.0使用带有第三方框架的类,但在iOS版本中> = 11.0是使用标准解决方案。
执行此操作的方法是使用包含而不是继承,以便您可以在代码运行时使用所需的行为配置对象。可以把它想象成委托,其中有一个帮助程序对象,它允许您在不创建子类的情况下专用化类。
例如,假设您已经根据UITableViewCell
定义了BaseTableViewCell
类,如您所所示:
// Available for iOS >= 11.0
class BaseTableViewCell: UITableViewCell {
}
但是,也许 11.0 之前的 iOS 版本没有您想要的与滑动相关的一些功能,因此您首先创建一个协议来声明提供您需要添加的行为的函数:
protocol SwipingProtocol {
func swipe()
}
。并创建实现该协议中的函数的类
class OldSwiper : SwipingProtocol {
func swipe() { // put your < 11.0 swiping code here }
}
class NewSwiper : SwipingProtocol {
func swipe() { // put your >= 11.0 swiping code here }
}
。最后将对此的支持添加到基类中:
class BaseTableViewCell: UITableViewCell {
var swiper : SwipingProtocol
init() {
if systemVersion < 11.0 {
swiper = OldSwiper()
}
else {
swiper = NewSwiper()
}
}
func swipe() {
swiper.swipe()
}
}
所以现在你有两个(或更多)包含在OldSwiper
和NewSwiper
中的滑动行为实现,你的基类根据它运行的环境决定使用哪一个。
当然,您可以跳过整个协议的事情,将新旧行为构建到BaseTableViewCell
中,在具有依赖于操作系统的自定义的每个方法中使用if
语句在它们之间切换。不过,使用协议和帮助程序类更好,因为它将所有特定于版本的内容保存在单独的类中。它还使您的代码变得灵活 - 如果您想在未来为iOS 14.0及更高版本做一些不同的事情,那么进行更改只需创建新的SwipingProtocol
实现即可。
这应该有你需要的东西: 在 Swift 中检查操作系统版本?
var cell: BaseTableViewCell? = nil
if #available(iOS 11.0, *) {
cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier1", for: indexPath)
} else {
cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier2", for: indexPath)
}