简体   繁体   English

在 Swift / UIKit 中,你如何将 UIView 的“基础”class 推广到其他视图类型,因为你不能在各种 UIView 类型中组合太多

[英]In Swift / UIKit, how do you generalize a "base" class of UIView to other view types, given that you can't compose much in the various UIView types

Say I have说我有

class Plastic: UIView, SomeProto {
  override something {
    blah
  }
  override func layoutSubviews() {
    blah
  }
}

I then have various custom views GreenPlastic: Plastic , YellowPlastic: Plastic etc.然后我有各种自定义视图GreenPlastic: PlasticYellowPlastic: Plastic等。

I want to do exactly the same thing for stack views.我想对堆栈视图做同样的事情。

Currently I use copy-paste engineering:目前我使用复制粘贴工程:

class PlasticForStackViews: UIStackView, SomeProto {
  //.. copy and paste in the identical code.
  //.. if I edit something in one, edit in both
}

Note that you can't compose (unless I drastically misunderstand something, tell me if I'm wrong) any of the good stuff in the UIView classes, layoutSubviews etc.请注意,您不能编写(除非我完全误解了什么,如果我错了请告诉我)UIView 类、布局子视图等中的任何好东西。

(Obviously if the issue at hand is just "adding corners" or such you can usually trivially use an extension). (显然,如果手头的问题只是“添加角”之类的,您通常可以简单地使用扩展名)。

(Note that this does assume the various issues addressed in the "base class" do apply to both UIView and the other view types, stack view in the example. Obviously you couldn't generalize something specific to, say, an image view, across a "similar base class" for the other view types.) (请注意,这确实假设“基类”中解决的各种问题确实适用于 UIView 和其他视图类型,示例中的堆栈视图。显然,您不能概括某些特定于图像视图的内容其他视图类型的“类似基类”。)

Is there a solution to this problem?这个问题有解决办法吗?

The problem at hand is completely different from a protocol solution, because, in fact, you can't compose (unless I drastically misunderstand something, tell me if I'm wrong) any of the good stuff in the UIView classes... layoutSubviews etc.手头的问题与协议解决方案完全不同,因为实际上,您无法编写(除非我严重误解某些东西,如果我错了请告诉我)UIView 类中的任何好东西... layoutSubviews ETC。

You say你说

It's completely different from a protocol它与协议完全不同

but this is a description of protocol extensions:但这是对协议扩展的描述:

many of the features of the various view classes are identical and can be handled identically各种视图类的许多功能是相同的,可以相同地处理

If you need "overrides" of default implementations, put the declarations in the protocol definition.如果您需要“覆盖”默认实现,请将声明放在协议定义中。 Otherwise, don't bother.否则,不要打扰。

protocol PlasticProtocol: UIView {
  func something() -> String
}

// MARK: - internal
extension PlasticProtocol {
  func etc() {
    // …
  }

  func something() -> String {
    "default"
  }

  func variousBringupStuff() {
    // …
  }
}
// MARK: - PlasticProtocol
extension Plastic: PlasticProtocol {
  func something() -> String {
    "override"
  }
}
let plastic = Plastic()
plastic.something() // override
let plasticProtocol: some PlasticProtocol = plastic
plasticProtocol.something() // default

Naming is going to be terrible, when you need to override superclass members.当您需要覆盖超类成员时,命名将变得很糟糕。 And you'll still need to define the overrides and call super .而且您仍然需要定义覆盖并调用super But that's better than copypasta.但这比 copypasta 好。

// MARK: - UIView
extension Plastic {
  override func layoutSubviews() {
    plastic_layoutSubviews()
    super.layoutSubviews()
  }
}
// MARK: - UIView
extension PlasticProtocol {
  func plastic_layoutSubviews() {
    // …
  }
}
class PlasticView: UIView, SomeProtocol {
    /// Apply all identical code here
}

class GreenPlasticView: PlasticView {
    /// Automatically inherits code from PlasticView
}

class YellowPlasticView: PlasticView {
    /// Automatically inherits code from PlasticView
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM