为 Swift 中的 IBOutlets 样式创建一个通用的 willSet 闭包

Create a generic willSet closure for styling IBOutlets in Swift

是否可以创建某种通用的 willSet 闭包来在视图控制器中设置 IBOutlets 的样式?

目前我使用这段代码来设置 UIImageView 的色调。 “.primary”是我通过 UIColor 扩展创建的 UIColor 上的静态变量:

@IBOutlet weak var someImageView:UIImageView! { 
  willSet { 
    newValue.tintColor = .primary 
  } 
}

现在我有一大堆插座,我想以相同的方式设置样式,对我来说,这似乎是很多重复的代码,特别是如果我开始应用更多的样式,而不仅仅是设置色调,所以我想要更通用的东西。我想到了:

let tintClosure: (_ newValue: UIView?) -> () = { [=12=]?.tintColor = .primary }
@IBOutlet weak var someImageView:UIImageView! { willSet{ tintClosure(newValue) } }

现在我只需编写一次实际着色的代码,就可以调用 willSet 中的闭包。但是,我想知道是否有一种更有效的方法,这样我什至不必自己用 (newValue) 调用闭包,而只需给它 tintClosure 即可。

就像一个函数需要一个完成处理程序并且您有一个适合其声明的函数,您只需传递函数的名称而不是调用函数的闭包。

非常喜欢的东西,例如:

@IBOutlet weak var someImageView:UIImageView! { superDuperClosure(willSet) }

@IBOutlet weak var someImageView:UIImageView! { willSet{ crazyImplementationOfTintClosre } }

@IBOutlet weak var someImageView:UIImageView! { willSet.howIsThisEvenPossible }

@IBOutlet weak var someImageView:UIImageView! { nowWeAreTalking }

好吧,也许我只是想多了,我已经找到了最简单的方法。可能是我对 willSet 的工作原理理解不够深入。亲爱的 Swift 大师们,请教我如何成为一名敏捷的开发人员。

更新

根据 Paulo Mattos 的第二个建议,我有了另一个想法。我创建了一个包含所有图像视图的出口集合。然后我用这段漂亮的小代码迭代所有的颜色:

@IBOutlet var imageViewsToTint: [UIImageView]! { willSet { newValue.forEach { [=17=].tintColor = .primary } } }

这种方法的美妙之处在于,您基本上可以为各种目的创建插座集合,例如一个用于着色,一个用于文本大小等,然后您可以将您想要设置样式的视图连接到适当的集合.

我觉得您的解决方案已经非常简约了 :) 抱歉,我想不出更短的解决方案。这个有点异国情调,Swift Evolution proposal 可以提供一些帮助,但至少暂时推迟了。

让我们快速探索 willSet 之外的一些替代方案(无论如何,可能会因此而被否决...):

UIView 子类。我有一个 UITextField,我在我的应用程序中经常使用它!因此,我实现了一个简单的子类并在其中进行了所有样式设置(而不是在它出现的每个视图控制器上)。当然,这在您的 所有 视图中可能不可行。

viewDidLoad。您可以将所有视图分组到一个数组中,然后在 viewDidLoad 方法中进行样式设置。可能比您当前的解决方案更 更容易出错 — 您可能会在这里和那里错过一个视图 — 但无需太多黑客攻击即可完成工作 ;)