Home > Software engineering >  Use forEach for creating UIActions
Use forEach for creating UIActions

Time:02-15

I wanted to use UIMenuto create a filter like menu that will be open from a UIBarButtonItem

  private func createFilteringMenu() -> UIMenu {
        
        let fivePhotos = UIAction( title: "5", image: UIImage(systemName: "photo")) { [weak self] _ in
            guard let this = self else { return }
            this.fetchImages(limit: 5)
        }


        let tenPhotos = UIAction( title: "10", image: UIImage(systemName: "photo")) { [weak self] _ in
            guard let this = self else { return }
            this.fetchImages(limit: 10)
        }

        let twentyPhotos = UIAction( title: "20", image: UIImage(systemName: "photo")) { [weak self] _ in
            guard let this = self else { return }
            this.fetchImages(limit: 20)
        }

        let thirtyPhotos = UIAction( title: "30", image: UIImage(systemName: "photo")) { [weak self] _ in
            guard let this = self else { return }
            this.fetchImages(limit: 30)
        }
        
    
        
        let menuActions = [fivePhotos, tenPhotos, twentyPhotos, thirtyPhotos]
        let addNewMenu = UIMenu( title: "Select number of photos", children: menuActions)
        
        return addNewMenu
    }

Which is super bad in my opinion (too many repeated code). I wanted to do it by using forEach:

    private func createFilteringMenu() -> UIMenu {
        
        let numberOfItems = [5, 10, 15, 20, 25, 30]
        var menuActions: [UIAction] = []
        
        numberOfItems.forEach{ index in
            if index < numberOfItems.count {
                let item = UIAction( title: "\(numberOfItems[index])", image: UIImage(systemName: "photo")) { [weak self] _ in
                    guard let this = self else { return }
                    this.fetchImages(limit: numberOfItems[index])
                }
                menuActions.append(item)
            }
        }

        
        let addNewMenu = UIMenu( title: "Select number of photos", children: menuActions)
        
        return addNewMenu
    }

But of course it just added the last item (30), could anyone help me to add all the item with for each (or something similar).

Thank you so much

CodePudding user response:

The for-each gives you the value not the index.

So the if condition is not required because it is actually checking the values against the array length in each iteration

is 5 < 6 -> true
is 10 < 6 -> false
is 15 < 6 -> false
is 20 < 6 -> false
is 25 < 6 -> false
is 30 < 6 -> false

That is why there is only one item showing up in your menu

Try this and see if it fixes your issue.

private func createFilteringMenu() -> UIMenu {
    
    var menuActions: [UIAction] = []
    
    numberOfItems.forEach{ value in
        
        let item = UIAction( title: "\(value)",
                             image: UIImage(systemName: "photo"))
        { [weak self] _ in
            guard let this = self else { return }
            this.fetchImages(limit: value)
        }
    
        menuActions.append(item)
    }
    
    return UIMenu(title: "Select number of photos",
                  children: menuActions)
}
  • Related