Calling a function which is placed in an Array

痴心易碎 提交于 2019-12-24 18:43:18

问题


I have an array where I have the Title of Button as Key and the Image as Value with position 0. I am calling this in CollectionView and the view looks like show in screenshot. At position 1 i have the name of the function that needs to be called with didSelectItemAt indexPath. How do I execute the function on click?

var mainBtnsArr = [
    ["Hotels" : ["homepage_hotel", ShowHotelSearch]],
    ["Flights" : ["homepage_flights", ShowFlightSearch]],
    ["Transfer" : ["homepage_transfer", ShowTransferSearch]],
    ["Activities" : ["homepage_sightseeing", ShowSightSeeingSearch]],
    ["Cruises" : ["homepage_cruise", ShowCruiseSearch]],
    ["CarRental" : ["homepage_carrental", ShowCarrentalSearch]],
    ["Packages" : ["homepage_packages", ShowPackageSearch]],
    ["Visa" : ["homepage_visa", ShowVisaSearch]],
    ["Groups" : ["homepage_groups", ShowGroupSearch]],
    ["Insurance" : ["homepage_insurance", ShowInsuranceSearch]],
    ["Meals" : ["homepage_meals", ShowMealsSearch]],
    ["ArrivalGuides" : ["homepage_arrivalguide", ShowArrivalGuidesSearch]]
]

My Collection View Code

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{
    let myCell:HomeCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeCollectionViewCell", for: indexPath) as! HomeCollectionViewCell
    myCell.backgroundColor = UIColor.clear
    myCell.layer.borderWidth = 1
    myCell.layer.borderColor = UIColor.clear.cgColor
    myCell.layer.cornerRadius = 10

    let title = "\((mainBtnsArr[indexPath.row] as NSDictionary).allKeys[0])"
    let img = "\(((mainBtnsArr[indexPath.row] as NSDictionary).allValues[0] as! NSArray)[0])"

    myCell.imgIcon.image = UIImage(named: img)
    myCell.imgIcon.contentMode = .center
    myCell.imgIcon.backgroundColor = UIColor.white
    myCell.imgIcon.layer.cornerRadius = 10
    myCell.imgIcon.layer.shadowColor = UIColor.colorFromCode(0xcccccc).cgColor
    myCell.imgIcon.layer.shadowOpacity = 0.5
    myCell.imgIcon.layer.shadowOffset = CGSize(width: 2.0, height: 2.0)
    myCell.imgIcon.layer.shadowRadius = 5

    myCell.lbl_Service.text = title
    myCell.lbl_Service.textColor = Constants.sharedInstance.MediumTextColour

    return myCell as HomeCollectionViewCell;
}


func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    print("User tapped on \(indexPath.row)")
    //let funcToCall: = ((mainBtnsArr[indexPath.row] as NSDictionary).allValues[0] as! NSArray)[1]
    let funcToCall:CGFunction = ((mainBtnsArr[indexPath.row] as NSDictionary).allValues[0] as! NSArray)[1] as! CGFunction

}

// CollectionView Clicks
func ShowHotelSearch() {
    presenter.showHotelSearchScreen()
}
func ShowFlightSearch() {
    MyCustomAlert.sharedInstance.ShowAlert(vc: self, myTitle: StringClass.sharedInstance.lcStr_comingsoon, myMessage: StringClass.sharedInstance.lcStr_comingsoonflightstext)
}

回答1:


Your problem is that you are using a Dictionary with a value which is an [Any] array to hold the button image name and function. Then you have to do some ugly casting to get to something you can use:

if let funcToCall = myBtnsArr[indexPath.row].first?.value.last as? (HomeViewController) -> () -> () {
    funcToCall(self)()
}

You'd be better served to put this into a struct using proper types:

struct ButtonInfo {
    let title: String
    let image: String
    let function: (HomeViewController) -> () -> ()
}

Note: The property function is defined here to hold an instance function of the HomeViewController class. When calling the function, the current instance of HomeViewController (i.e. self) will be passed like this: function(self)().

Then define your mainBtnsArr like this:

let mainBtnsArr = [
    ButtonInfo(title: "Hotels", image: "homepage_hotel", function: ShowHotelSearch),
    ButtonInfo(title: "Flights", image: "homepage_flights", function: ShowFlightSearch),
    ButtonInfo(title: "Transfer", image: "homepage_transfer", function: ShowTransferSearch),
    ...
]

Then it is much easier to use the data. (Note: Since the functions in the array are instance functions, you must pass self to the function when calling them):

let funcToCall = mainBtnsArr[indexPath.row].function
funcToCall(self)()

Likewise, title and img become:

let title = mainBtnsArr[indexPath.row].title
let img = mainBtnsArr[indexPath.row].image


来源:https://stackoverflow.com/questions/53652182/calling-a-function-which-is-placed-in-an-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!