【问题标题】:Subclassing a variable within a class在类中子类化变量
【发布时间】:2016-12-28 01:02:43
【问题描述】:

我正在尝试更改类中变量的行为。

更准确地说,我有一个具有“scrollview”属性的“UIWebView”。

我需要覆盖此滚动视图的“setContentInset”,但我不确定如何执行此操作。

文档告诉我 UIWebView 有这个:

var scrollView: UIScrollView { get }

所以我不能简单地创建自己的并将其设置在那里。

我的问题是,如何覆盖 UIWebView 的滚动视图中的“setContentInset”?

编辑:

2 澄清。

我知道 UIWebView 不应该是子类,根据文档的subclassing notes

我的目标是修复this answer 之后我已经在我的应用的其他滚动视图上实现的“下拉刷新”跳跃行为。

【问题讨论】:

  • 我不知道你是否能实现你想要的,但作为一种解决方法,可以考虑扩展UIScrollViewDelegate 协议以添加委托方法scrollViewDidSetContentInset(UIScrollView),然后扩展UIScrollView 以随时调用它contentInset 已设置。

标签: ios swift


【解决方案1】:

当一个内置接口类“拥有”另一个内置接口类时,您不能子类化内部类或覆盖它的任何内容。

因此,虽然你可以继承 UIWebView,但你不能以某种方式继承 UIWebView 的滚动视图。

另一个熟悉的例子是 UIButton。大家都知道UIButton包含一个UILabel和一个UIImageView。你可以继承 UIButton 但你不能继承它的 UILabel 或 UIImageView。

【讨论】:

  • 覆盖titleLabelimageViewUIButton 会很棘手,但这是因为按钮状态不同。我已经成功地覆盖了UITableViewCell 的子类中的textLabelimageView。覆盖 scrollView 时会出现什么问题?
【解决方案2】:

我会从一个直截了当的方法开始,看看是否有任何微妙的问题。

class MyScrollView: UIScrollView {
    private lazy var my_contentInset: UIEdgeInsets = UIEdgeInsets()
    override var contentInset: UIEdgeInsets {
        get { return my_contentInset }
        set {
            // Your willSet code
            my_contentInset = newValue
            // Your didSet code
        }
    }
}

class MyWebView: UIWebView {
    private lazy var my_scrollView: MyScrollView = MyScrollView()
    override var scrollView: UIScrollView {
        get { return my_scrollView }
    }
}

这有点简单,因此您可能会遇到问题,具体取决于运行时设置scrollView 的方式。如果运行时需要 scrollView 的设置器,那么您需要更深入。

在这里,我为我的滚动视图创建了一个初始化器,它克隆了一个 UIScrollView 并在 MyWebViewscrollView 的设置器中使用它。

extension MyScrollView {
    convenience init(scrollView: UIScrollView) {
        let data = NSKeyedArchiver.archivedData(withRootObject: scrollView)
        let coder = NSKeyedUnarchiver(forReadingWith: data)
        self.init(coder: coder)! // Intentionally failing hard on decode failure.

        // Additional configuration not captured in the encode/decode
        // process might be needed.
    }
}

class MyWebView: UIWebView {
    private lazy var my_scrollView: MyScrollView = MyScrollView()
    override var scrollView: UIScrollView {
        get { return my_scrollView }
        set { my_scrollView = MyScrollView(scrollView: newValue) }
    }
}

即使这样可能还不够。在处理内部对象时,运行时可以以多种方式作弊。应该足以让您入门。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-21
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多