在类中子类化变量

Posted

技术标签:

【中文标题】在类中子类化变量【英文标题】: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 已设置。 【参考方案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) 
    

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

【讨论】:

以上是关于在类中子类化变量的主要内容,如果未能解决你的问题,请参考以下文章

6-23

面向对象

5-7

Python面向对象---类的基本使用

面向对象基础

简述在类的继承关系中,子类可以继承父类的都有哪些成员