Passing specific values from Dictionary to another

Programatically arranging buttons I want to cut down on the NSLayoutConstraint code and would like to pass through a dictionary of select keys for a single constraint anchor to work on. I would like to copy specific key values (UIButton) pairs from one dictionary into a new one:

var cookerButtons : [String: UIButton] = ["1": UIButton(), "2": UIButton(), "3": UIButton(), "4": UIButton()]

//creates UIButtons from the dictionary's keys, assigning the same name all in one pass
for key in cookerButtons.keys {
cookerButtons[key]?.setTitle(key, for: .normal)
view.addSubview(cookerButtons[key]!)
}

I would like to extract e.g. just three key value pairs into another dictionary and have them all processed at once, if possible:

let test1 = cookerButtons["2", "3", "4"]!

test1.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),

You could do something like this:

class Titled { // Did this on a Mac so substituited this class for UIButton.
    var title: String! = nil
}

extension Dictionary { // Add required capability to Dictionaries.
    subscript(_ keys: Key...) -> [Value] { // Extract the values for the given keys into an array.
        var result = [Value]()
        for key in keys {
            let value = self[key]
            if let v = value {
                result.append(v)
            }
        }
        return result
    }
}

var cookerButtons : [String: Titled] = ["1": Titled(), "2": Titled(), "3": Titled(), "4": Titled()]

//creates UIButtons from the dictionary's keys, assigning the same name all in one pass
for key in cookerButtons.keys {
    cookerButtons[key]?.title = key
}

let test1 = cookerButtons["2", "3", "4"] // Extract the `Titled` for the given `Strings` into an array.

for titled in test1 {
    titled.title // "2", "3", "4"
}
1 Like

Thank you very much for your help, I have yet to explore Extensions, but they are on my todo list.

I get the following error when attempting to use the "test1" constant as an array of constraints:

"Value of type '[UIButton]' has no member 'heightAnchor'"

I'm unsure if an array can be used to pass through several constraints at once with NSLayoutConstraints?

I don't know what heightAnchor is, it isn't in UIButton?

It's an NSLayoutDimension that every view has but yes, the issue is that it's an array of buttons and not just a button.

@powing If you want to use all of the anchors of an array of views, you'd have to apply what ever anchor function you want to use to every value in the array, either using a loop or forEach.

1 Like

Thanks for catching my mistake :smile:.

Hi guys, thank you for your help, I'm learning all of the time.

I managed to get it working, but I was trying to be too clever and increased my code by x3.5!

In the end I used the following:

    let fromBottomR1 = cookerButtons["🥑", "🥒", "🍒"]
    let toBottomR1 = cookerButtons["C", "C", "C"]

    
    for (_, buttonFrom) in fromBottomR1.enumerated() {
        for (_, buttonTo) in toBottomR1.enumerated() {
            NSLayoutConstraint.activate([
                buttonFrom.bottomAnchor.constraint(equalTo: buttonTo.bottomAnchor),
                ])
        }
    }

To replace:

calculatriceButtons["🥑"]!.bottomAnchor.constraint(equalTo: cookerButtons["C"]!.bottomAnchor),
calculatriceButtons["🥒"]!.bottomAnchor.constraint(equalTo: cookerButtons["C"]!.bottomAnchor),
calculatriceButtons["🍒"]!.bottomAnchor.constraint(equalTo: cookerButtons["C"]!.bottomAnchor)

But, the theory still worked.

The best I got was:

                        i.widthAnchor.constraint(equalTo: cookerButtons["C"]!.widthAnchor),
                        i.heightAnchor.constraint(equalTo: cookerButtons["C"]!.heightAnchor)

Which looped over a total of 5 chunks of code, but that was it, and that only needed a simple For Loop.

I wish there were a way to stitch the buttons together, from trailing to leading in some kind of repeat order that only a few lines of code would carry out. But in all of this I found readability really suffered, and that was compared to 100 lines of NSLayoutConstraints!

Thanks anyway!