Вызов функции, которая помещается в массив - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть массив, в котором у меня есть заголовок кнопки в качестве ключа и изображение в качестве значения с позицией 0. Я вызываю это в CollectionView, и вид выглядит как шоу на скриншоте.В позиции 1 у меня есть имя функции, которую нужно вызвать с помощью didSelectItemAt indexPath.Как выполнить функцию при нажатии?

View Shown when I execute collection view code and getting data from below array

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]]
]

Моя коллекция Просмотр кода

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 Ответ

0 голосов
/ 06 декабря 2018

Ваша проблема в том, что вы используете Dictionary со значением, которое является массивом [Any], для хранения имени и функции изображения кнопки.Затем вам нужно выполнить какое-то уродливое приведение, чтобы получить что-то, что вы можете использовать:

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

Вам будет лучше поместить это в struct, используя надлежащие типы:

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

Примечание: Здесь определено свойство function для хранения функции экземпляра класса HomeViewController.При вызове функции текущий экземпляр HomeViewController (т.е. self) будет передан следующим образом: function(self)().

Затем определите ваш mainBtnsArr следующим образом:

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),
    ...
]

Тогда использовать данные будет намного проще.( Примечание: Поскольку функции в массиве являются функциями экземпляра, при вызове их необходимо передать self функции):

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

Аналогично, title и img стать:

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