【问题标题】:How can I swizzle UIView.init我怎样才能调配 UIView.init
【发布时间】:2021-05-25 17:09:25
【问题描述】:

我正在尝试调配 UIView 的 init 方法和任何它的子类。到目前为止,我的尝试只会导致崩溃或根本没有做任何明显的事情。

尝试实现的结果是能够覆盖视图边框颜色和宽度的值,以尝试在不需要附加调试器的情况下可视化视图框架。

【问题讨论】:

标签: ios objective-c swift swizzling swizzle


【解决方案1】:

我以前从未尝试过 swizzling,但我很想尝试一下 - 一个快速的谷歌找到了 this article,它解释了如何使用 extension 来做到这一点。

extension UIView {
    
    static let classInit: Void = {
        guard let originalMethod = class_getInstanceMethod(
            UIView.self,
            #selector(layoutSubviews)
        ), let swizzledMethod = class_getInstanceMethod(
            UIView.self,
            #selector(swizzled_layoutSubviews)
        ) else {
            return
        }
       method_exchangeImplementations(originalMethod, swizzledMethod)
    }()

    @objc func swizzled_layoutSubviews() {
        swizzled_layoutSubviews()
        self.layer.borderColor = UIColor.red.cgColor
        self.layer.borderWidth = 2
    }

}

然后,您只需要确保在 AppDelegate didFinishLaunchingWithOptions 方法中或在应用程序开始时的某个位置运行 swizzle

UIView.classInit

上面的代码适用于我在 iOS 13.7 模拟器上,但从我阅读的内容来看,你真的不应该尝试覆盖这样的方法,尤其是从这样一个核心对象,它会是如果可能,更安全地继承 UIView

【讨论】:

  • 我倾向于同意 swizzling 不是一个很好的方法,因为它在运行时存在不确定性,但是该功能只能在非生产版本中运行。我认为你可能会做一些事情,尽管只尝试 swizzle layoutSubviews 而不是 init。它使生活变得更加轻松。一旦我在电脑前,我会试一试并标记为已批准。干杯伙伴。
  • 可以确认此实现有效。关于在每个视图上恢复以前的边界状态,我需要解决一些事情,但这让我走出了困境,进入了主场。为了解决问题,这是 100% 正确的。
猜你喜欢
  • 1970-01-01
  • 2023-01-28
  • 1970-01-01
  • 2013-09-05
  • 2016-10-08
  • 1970-01-01
  • 2011-01-16
  • 2011-07-18
  • 1970-01-01
相关资源
最近更新 更多