0
    func createRowOfButtons(buttonTitles: [NSString]) -> UIView {
    var buttons = [UIButton]()
    let keyboardRowView = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 50))
    var dict = [UIButton:String]()
    for buttonTitle in buttonTitles 
    {
       let button = createButtonWithTitle(title: buttonTitle as String)
        buttons.append(button)
        keyboardRowView.addSubview(button)
        dict.updateValue("\(buttonTitle)", forKey: button)
    }
    allButtons = NSMutableDictionary(dictionary: dict)
    //error:[UIButton copyWithZone:]: unrecognized selector sent to instance 0x7e011bc0
    addIndividualButtonConstraints(buttons: buttons, mainView:keyboardRowView)
    return keyboardRowView
}

I am new to iOS, I want to create a NSMutableDictionary of UIButton but it give the following error:

Cannot cast 'UIButton' to 'NSCopying'.

I don't understand why this error occurs.

Thanks in advance.

Abhinandan Pratap
  • 2,142
  • 1
  • 18
  • 39

2 Answers2

1

UIButton does not conform to the NSCopying protocol and so you cannot use it as a key in NSDictionary

From Apple docs:

The key is copied (using copyWithZone:; keys must conform to the NSCopying protocol).

Reference: pheelicks answer of This Question

Abhinandan Pratap
  • 2,142
  • 1
  • 18
  • 39
0

It is really not certain why you would have to resort to using NSString or NSMutableArray, especially taking into account that you bridge NSString to String, which hints that NSString is actually useless.

Local buttons and dict arrays also seem to be unnecessary since after your loop finishes you simply assign those buttons to allButtons. It means that you can address that storage directly (with proper Swift [String: UIButton] type instead of NSMutableDictionary):

var allButtons: [String: UIButton]!

func createRowOfButtons(buttonTitles: [String]) -> UIView {

    let keyboardRowView = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 50))

    // Initialize / reset dictionary
    // Do it here or on declaration
    allButtons = [String: UIButton]()

    // Populate dictionary
    buttonTitles.forEach { title in
        let button = UIButton()// createButtonWithTitle(title: title)
        keyboardRowView.addSubview(button)
        allButtons[title] = button
    }

    addIndividualButtonConstraints(buttons: Array(allButtons.values),
                                   mainView: keyboardRowView)
    return keyboardRowView
}

You also access buttons by their titles, not vice versa.

Hexfire
  • 5,945
  • 8
  • 32
  • 42