2017-08-03 62 views
1

我是新來的Swift(我在一個月前瞭解它),我創建了一個自定義的UICollectionViewCell類,並且我還需要三種類型的UIButtons和其他對象,但我不想寫每一個,所以我正在創建一個函數。但是,由於我有三個按鈕,函數必須爲每個參數準確地使用三個數組。有人可以幫我解釋一下包含評論的代碼嗎?謝謝!如何檢查作爲UDF參數的數組中的值的數量?

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.") 


     } 
    } 
} 

回答

1

有很多怎麼回事。

if xOriginCgFloat != Array() { 

Array()聲明Array類型和檢查的新對象,如果xOriginCgFloat等於它:首先,如果你的參數數組就無法工作,你正在檢查的方式。相反,你要檢查xOriginCgFloat是Array類型,你可以這樣做的:

if xOriginCgFloat is Array { 

但是!你不需要這樣做。您的函數聲明指定xOriginCgFloat: [CGFloat],這意味着要運行該函數,傳遞的值爲xOriginCgFloat必須爲ArrayCGFloat s。無需檢查。

OK下一步:當你說

if AnyObject.self == UIButton.self { 

你可能認爲你檢查是否通過了ObjectTypeUIButton。但你不是。這實際上是檢查類AnyObject是否與UIButton類相同,但不是。所以這總是會返回錯誤。相反,你可以執行你在尋找這樣的檢查:

if objectType === UIButton.self { 

如果傳遞UIButton.selfobjectType當你調用該函數,我以爲是你的意圖,這將取得成功。

最後,您的實際問題:如果你想知道你xOriginCgFloat數組有多少個元素了,你可以使用xOriginCgFloat.count

if xOriginCgFloat.count == 2 { 

這是可行的,但它不是一個理想的方法,因爲它不」 t支持編譯時檢查;如果你的程序中的某個地方傳遞了一個數值錯誤的數組,編譯器就無法捕捉它。直到程序運行,你纔會發現,也許在一個非常糟糕的時間。相反,如果您知道要查找的值的數量,請使用元組。你可以聲明這樣的函數:

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

,並調用它是這樣的:

initializeStuff(xOriginCgFloat: (5.0, 6.7)) 

該公司預計正好用兩個CGFloats裏面一個元組,所以它會在IDE中顯示一個錯誤,如果你嘗試與其他任何東西打電話。當你的函數被調用時,你不需要檢查你所保證的值。

元組的缺點是你不能真正用for循環迭代它們(實際上you can,但它很混亂),所以你必須手動完成。因爲你的元組中只有兩個或三個元素,所以這可能不是一個壞的方法。例如:

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 
} 

您可以在Apple's documentation的元組中閱讀。

+0

當你說'if objectType == UIButton.self {'應該將等號運算符改爲身份運算符(===),因爲Xcode給我一個錯誤信息==。另外,因爲我想爲UIButton調用三個值,並且有兩個值UIView和UILabel,有沒有辦法讓一個元組具有不同數量的值? – ProgrammingEnthusiast

+0

如何在我的'for'循環中得到元組中三個值中的一個?我也發佈了另一個問題。 – ProgrammingEnthusiast

+0

@ProgrammingEnthusiast是:'AnyObject'不是'Equatable',所以我應該使用'==='比較身份而不是'=='。對於那個很抱歉。另外,使用for循環遍歷一個元組並不是真的支持。這是可能的,但很混亂。所以如果你想使用for循環方法,那麼元組可能不是一個很好的解決方案,你應該堅持使用數組。對不起,不好的建議。 – Robert

1

要寫如果檢查數組中的元素的量簡單地做:

if array.count == 3 

我不知道我這樣做是正確的,但你可以這樣做:

if buttonArray.count == 3{ 
    //do something 
} 

希望幫助

1

我不知道我用你的方法同意有FUNC建立所有的對象,但我絕對不會採用一系列必須是固定長度的參數。你可以嘗試這樣的事情:

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

struct ObjectDefinition { 
    let classType: UIView.Type 
    let frame: CGRect 
} 

func createAllTheStuff() { 
    let objectDefinitions: [ObjectDefinition] = [ 
     ObjectDefinition(classType: UIButton.self, frame: CGRect(x: 0, y: 0, width: 100, height: 200)), 
     ObjectDefinition(classType: UIButton.self, frame: CGRect(x: 10, y: 10, width: 10, height: 25)), 
     ObjectDefinition(classType: UIView.self, frame: CGRect(x: 0, y: 0, width: 50, height: 210)), 
     ObjectDefinition(classType: UILabel.self, frame: CGRect(x: 0, y: 0, width: 1200, height: 20)) 
    ] 

    for objectDefinition in objectDefinitions { 
     initializeStuff(objectType: objectDefinition.classType, frame: objectDefinition.frame) 
    } 
} 


func initializeStuff(objectType: UIView.self, frame: CGRect) { 
    switch objectType { 
    case UIButton.self: 
     let button = UIButton(frame: frame) 
     buttonArray.append(button) 
    case UILabel.self: 
     let label = UILabel(frame: frame) 
     labelArray.append(label) 
    case UIView.self: 
     let checkBox = UIView(frame: frame) 
     checkBoxArray.append(checkBox) 
    } 
} 

但是,我認爲,除非你是做了很多的樣板比你出什麼,你可以很容易地擺脫這一點。它實際上更短,因爲你不是什麼都不需要封裝。如果你是,你應該做一個工廠方法來預配置的UIButton,的UILabel,或UIView的

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] = [ 
} 
+0

你是什麼意思的「樣板?」這個函數是我較大的自定義UICollectionViewCell類的一部分。我將調用該函數三次(初始化我的所有UIButton,UIView,UILabel)。然後,我將只配置我的自定義類的確切佈局和約束條件。 – ProgrammingEnthusiast

+0

@ProgrammingEnthusiast - 我的意思是如果你在你的UIButton,UIView或UILabel實例上設置了大量的參數。例如,在設置插圖,字體,標籤文本等的按鈕上,然後您不希望爲每個按鈕調用所有這些方法,並且您希望使用工廠方法。 – dmorrow