gpt4 book ai didi

swift - MKAnnotationView 子类在 Swift 中应该有哪些初始值设定项?

转载 作者:IT王子 更新时间:2023-10-29 05:36:27 26 4
gpt4 key购买 nike

我正在我的项目中创建 MKAnnotationView 的子类。它需要有两个属性来存储 subview ,我需要在开始的某个地方对其进行初始化。

MKAnnotationView 在其文档中列出了一个初始化程序,initWithAnnotation:reuseIdentifier:,所以我想我可以简单地覆盖它:

class PulsatingDotMarker: MKAnnotationView {

let innerCircle: UIView
let outerCircle: UIView

override init!(annotation: MKAnnotation!, reuseIdentifier: String!) {
innerCircle = ...
outerCircle = ...

super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
}

...
}

但这会导致运行时异常:

fatal error: use of unimplemented initializer 'init(frame:)' for class 'PulsatingDotMarker'

好吧,我想 initWithAnnotation:reuseIdentifier: 在内部调用了 initWithFrame:,所以我应该改写它。让我们试试看:

class PulsatingDotMarker: MKAnnotationView {

let innerCircle: UIView
let outerCircle: UIView

override init(frame: CGRect) {
innerCircle = ...
outerCircle = ...

super.init(frame: frame)
}

...
}

然而,这会在创建注释 View 对象时导致编译错误:

Extra argument 'reuseIdentifier' in call

嗯,所以如果我实现(必需的)初始化器 initWithFrame:,它现在会丢失默认初始化器 initWithAnnotation:reuseIdentifier:?

也许如果我添加一个仅调用 superinitWithAnnotation:reuseIdentifier: 重写,它将再次可用,这会起作用吗?

class PulsatingDotMarker: MKAnnotationView {

let innerCircle: UIView
let outerCircle: UIView

init!(annotation: MKAnnotation!, reuseIdentifier: String!) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
}

override init(frame: CGRect) {
innerCircle = ...
outerCircle = ...

super.init(frame: frame)
}

...
}

不,仍然不好 - 编译错误:

Property 'self.innerCircle' not initialized at super.init call

好吧,如果我有一个 initWithFrame:,但是在 initWithAnnotation:reuseIdentifier: 中初始化了 subview 呢? (但是如果有人直接调用 initWithFrame: 会怎样?...)

class PulsatingDotMarker: MKAnnotationView {

let innerCircle: UIView
let outerCircle: UIView

init!(annotation: MKAnnotation!, reuseIdentifier: String!) {
innerCircle = ...
outerCircle = ...

super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
}

override init(frame: CGRect) {
super.init(frame: frame)
}

...
}

不足为奇,Swift 告诉我:

Property 'self.innerCircle' not initialized at super.init call

(这次在 initWithFrame: 中)。

那我该怎么办?我不能在这里和那里都创建 subview ,对吗?

class PulsatingDotMarker: MKAnnotationView {

let innerCircle: UIView
let outerCircle: UIView

init!(annotation: MKAnnotation!, reuseIdentifier: String!) {
innerCircle = ...
outerCircle = ...

super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
}

override init(frame: CGRect) {
innerCircle = ...
outerCircle = ...

super.init(frame: frame)
}

...
}

又错了,这实际上有效 - 即使我在同一个对象中两次分配常量属性(!)。

这应该如何正确完成?

(注意:该类还包含一个必需的 initWithCoder: 初始化程序,它仅调用第一个示例中的 fatalError,但该对象从未从 Storyboard 中创建。)

最佳答案

不幸的是,MKAnnotationView 强制您实现 init(frame: CGRect),这意味着您还必须在该方法中初始化所有实例变量。

This article再解释一下

对于只能用传入值初始化的变量,您必须将这些变量设为可选,并在 init(frame: CGRect) 中将它们设置为 nil。

原因是我怀疑 MKAnnotationView 在它的 objective-C init 方法中调用了 self.initWithFrame: rect。这样一来,如果一个子类覆盖了 initWithFrame:(CGRect) rect,它将被调用。但是,这会导致 swift 出现问题,因为如果您声明自定义指定的初始化程序,您不会继承父类(super class)的初始化程序。因此你必须在你的子类中实现 init(frame: CGRect)

我在使用 UITableViewController 时遇到了同样的问题。它的标题看起来遵循相同的模式。即两个易出错的指定初始化程序。

这让我很伤心。但你能做什么呢。

关于swift - MKAnnotationView 子类在 Swift 中应该有哪些初始值设定项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29550936/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com