如何接受 CGFloat 或 CGFloats 数组作为函数参数



我有一个自动布局便利功能,可以将视图堆叠在一起。对于我的间距参数,我想允许:

  • 视图之间的间距为零
  • 或单个CGFloat(所有视图均匀间隔(
  • CGFloat 数组(视图之间的不同空格(

但是,我不确定如何定义这个参数。

// Ambiguous
func myconstrainer(_ views : [UIView], spacing : CGFloat = 0){}
func myconstrainer(_ views : [UIView], spacing : [CGFloat]? = nil){}
// Messy
func myconstrainer(_ views : [UIView], spacingA : CGFloat = 0, spacingB: [CGFloat]? = nil){}

您还可以尝试可变数量的参数,如下所示:

func myconstrainer(_ views: [UIView], spacing: CGFloat...) {
    myconstrainer(views, spacing: spacing)
}

并提供一个简单的重载来处理数组

func myconstrainer(_ views: [UIView], spacing: [CGFloat]) {
    // Implementation...
}

因此,在使用偶数间距时,您无需将单个元素放在括号中。

呼叫站点:

myconstrainer([view1, view2, view3])
myconstrainer([view1, view2, view3], spacing: 123)
myconstrainer([view1, view2, view3], spacings: 1, 2, 3)
myconstrainer([view1, view2, view3], spacings: [1, 2, 3])

一些不明显的注意事项:

  • 使用零参数调用 CGFloat... 可以很好地涵盖默认情况;
  • 而且,由于这个参数实际上是一个数组,我们可以将其转发到另一个不带括号的方法。

如果不诉诸泛型,这将带来一个(我认为不必要的(复杂性的世界,你就不能做你想做的事情,因为需要定义参数的类型才能从 Swift 旨在提供的类型安全中受益。

为什么不简单地将间距定义为CGFloats数组(如第二个声明(,如果spaceing.count == 1,则默认为第一种情况?

func myconstrainer(_ views : [UIView], spacing : [CGFloat]?) {
    if spacing.count == 1 {
        // all views spaced evenly code
    }
    else {
        // different spaces between views code
    }
}

PS(不需要将可选参数设置为 nil(

以下是我的做法:

func myconstrainer(_ views: [UIView], spacing: CGFloat) {
    myconstrainer(views, spacings: repeatElement(spacing, count: views.count))
}
func myconstrainer<C: Collection>(_ views : [UIView], spacings: C)
    where C.Iterator.Element == CGFloat {
    // actual implementation...
}

呼叫站点:

myconstrainer([view1, view2, view3], spacing: 123.0)
myconstrainer([view1, view2, view3], spacings: [1, 2, 3])

最新更新