如何检查作为UDF参数的数组中的值的数量?

时间:2017-08-03 20:48:08

标签: arrays swift xcode user-defined-functions

我是Swift的新手(大约一个月前我学会了)并且我正在创建一个自定义的UICollectionViewCell类,我也需要三种类型的UIButtons和其他对象,但我不想写每一个out,所以我正在创建一个函数。但是,由于我有三个按钮,因此该函数必须为每个参数准确地使用三个数组。有人可以帮助我提供我已包含评论的代码吗?谢谢!

var buttonArray: [UIButton] = []
var checkBoxArray: [UIView] = []
var labelArray: [UILabel] = []

func initializeStuff(objectType: AnyObject, xOriginCgFloat: [CGFloat], yOriginCgFloat: [CGFloat], width: [CGFloat], height: [CGFloat])  {

    if xOriginCgFloat != Array() || yOriginCgFloat != Array() || width != Array() || height != Array() {
        fatalError("Each CgFloat parameter must be an array.")
    } else {
        if AnyObject.self == UIButton.self {
            if condition { //condition: each array must contain exactly three values
                for index in 0..<3 {
                    var button = UIButton(frame: CGRect.init(origin: CGPoint.init(x: xOriginCgFloat[index], y: yOriginCgFloat[index]), size: CGSize.init(width: width[index], height: height[index])))

                    buttonArray.append(button)
                }
            } else {
                fatalError("Each array for a button object must have exactly three values.")
            }

        } else if AnyObject.self == UIView.self {
            if condition2 { //condition2: each array must contain exactly two values
                for index in 0..<2 {
                    var checkBox = UIView(frame: CGRect.init(origin: CGPoint.init(x: xOriginCgFloat[index], y: yOriginCgFloat[index]), size: CGSize.init(width: width[index], height: height[index])))

                    checkBoxArray.append(checkBox)
                }
            } else {
                fatalError("Each array for a view object must have exactly two values.")
            }

        } else if AnyObject.self == UILabel.self {
            if condition3 { //condition3: each array must contain exactly two values
                for index in 0..<2 {
                    var label = UILabel(frame: CGRect.init(origin: CGPoint.init(x: xOriginCgFloat[index], y: yOriginCgFloat[index]), size: CGSize.init(width: width[index], height: height[index])))

                    labelArray.append(label)
                }
            } else {
                fatalError("Each array for a view object must have exactly two values.")
            }

        } else {
            fatalError("Incorrect type of object; AnyObject parameter must be a UIButton, UIView, or UILabel.")


        }
    }
}

3 个答案:

答案 0 :(得分:1)

要编写一个检查数组中元素数量的if,只需执行以下操作:

ssh git-amr-1 gerrit query --format=JSON  --commit-message --patch-sets commit:c895abd810d3880729dfdf4a58462aa81cee38a1

我不知道我是否做对了,但你可以这样做:

if array.count == 3

希望有所帮助

答案 1 :(得分:1)

我不确定我是否同意使用func来构建所有对象的方法,但我绝对不会采用必须是固定长度的一系列参数。你可以尝试这样的事情:

var buttonArray: [UIButton] = []
var checkBoxArray: [UIView] = []
var labelArray: [UILabel] = []


func createAllTheStuff() {
    let button1 = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 200))
    buttonArray.append(button1)
    let button2 = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 200))
    buttonArray.append(button2)
    ... etc ...
    let objectDefinitions: [ObjectDefinition] = [
}

但是,我认为,除非你做的事情比你所展示的要多得多,否则你可以轻松地逃脱这一点。它实际上更短,因为你真的没有其他任何需要封装的东西。如果是,您应该使用工厂方法来预配置UIButton,UILabel或UIView

{{1}}

答案 2 :(得分:1)

这里有很多事情要发生。首先,您检查参数是否为数组的方式不起作用:

if xOriginCgFloat != Array() {

Array()声明一个类型为Array的新对象,并检查xOriginCgFloat是否等于它。相反,您要检查xOriginCgFloat是否属于Array类型,您可以这样做:

if xOriginCgFloat is Array {

但是!你不需要这样做。您的函数声明指定xOriginCgFloat: [CGFloat],这意味着对于要运行的函数,为xOriginCgFloat 传递的值必须Array CGFloat个。无需检查。

接下来好了:当你说

if AnyObject.self == UIButton.self {

您可能认为您正在检查ObjectType传递的值是否为UIButton。但你不是。这实际上是在检查类AnyObject是否与类UIButton相同,而不是if objectType === UIButton.self { 。所以这总是会返回false。相反,您可以执行以下检查:

UIButton.self

如果您在调用函数时为objectType传递xOriginCgFloat,这将成功,我认为这是您的意图。

最后,您的实际问题是:如果您想知道xOriginCgFloat.count数组中有多少元素,可以使用if xOriginCgFloat.count == 2 {

func initializeStuff(xOriginCgFloat: (CGFloat, CGFloat)) {

这可行,但它不是一种理想的方法,因为它不支持编译时检查;如果程序中某处传递的数组值错误,则编译器无法捕获它。你不会在程序运行之前发现,也许是在非常糟糕的时候。

相反,如果您知道要查找的值的数量,请使用元组。你可以声明一个这样的函数:

initializeStuff(xOriginCgFloat: (5.0, 6.7))

并称之为:

CGFloats

它期望一个元组内部恰好有两个let xOriginCgFloat:(CGFloat, CGFloat) = (4, 6) var floats = [CGFloat]() floats.append(xOriginCgFloat.0) floats.append(xOriginCgFloat.1) for float in floats { // process xOriginCgFloat member here } ,所以如果你尝试用其他任何东西调用它会在IDE中显示错误。调用函数时,您无需检查,因为您可以确切地保证所需的值。

元组的缺点是你不能用for循环迭代它们(实际上是you can,但它很乱)所以你必须手动做事。由于你的元组中只有两个或三个项目,这可能不是一个糟糕的方法。例如:

currentPlaybackLabel.text = [NSString stringWithFormat:@"%.1f", (float)realCurrentPlayback / 60.0f];
durationLabel.text = [NSString stringWithFormat:@"%.1f", (float)totalDuration /60.0f];

您可以阅读Apple's documentation中的元组。