1

I'm trying to implement the delegation pattern on Swift. The process consists in a popover that is displayed from a UIMenuItem in a text selection on a textView. This popover is a TableViewController that contains some colors. When a cell (or color) is tapped, the selected text changes its color from black to the selected color. I have the following protocol in the sending class:

protocol SelectedColorDelegate {
func didSelectColorCell(color: UIColor)
}

Then in the sending class I created this property:

var colorCellDelegate: SelectedColorDelegate?

In the method didSelectRowAtIndexPath of the tableViewController (popover) that is the sending class, I assigned the required parameter:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let color = arrayOfColorValues[indexPath.row]
    self.colorCellDelegate?.didSelectColorCell(color: color)
}

In my receiving class that is a ViewController I set the protocol SelectedColorDelegate, and conformed to it with this method, aimed to change the textColor:

func didSelectColorCell(color: UIColor) {
    let textRange = noteTextView.selectedRange
    let string = NSMutableAttributedString(attributedString: noteTextView.attributedText)
    string.addAttribute(NSForegroundColorAttributeName, value: color, range: textRange)
    noteTextView.attributedText = string
    noteTextView.selectedRange = textRange
}

But the last method is never called, tapping the cell of the popover does nothing, what am I missing or doing wrong? Thanks!! :)

Marilyn García
  • 105
  • 1
  • 13

3 Answers3

7

First of all define your protocol as only for classes

protocol SelectedColorDelegate: class {
    func didSelectColorCell(color: UIColor)
}

Secondly we want our delegate to be weakly retained

weak var colorCellDelegate: SelectedColorDelegate?

Finally set delegate when you show other view or in viewDidLoad eg:

class YourViewController: SelectedColorDelegate {
    final override func viewDidLoad() {
        super.viewDidLoad()

        self.colorCellDelegate = self
    }
}

Tutorial - How To Make Weak Delegates In Swift

Adrian Bobrowski
  • 2,681
  • 1
  • 16
  • 26
  • I managed to find my mistake, but if I set the delegate as a weak reference the compiler complains, saying that "weak may only be applied to class and class-bound protocol types", not the simple protocol that I implemented, so my protocol has to be a class-only type. Thanks! – Marilyn García Dec 24 '16 at 04:48
  • @MarilynGarcía define your protocol as only for classes. Look for my edited answer – Adrian Bobrowski Dec 24 '16 at 06:42
1

In PopOverTableViewController, setup should look like -

class PopOverTableViewController: UITableViewController, SelectedColorDelegate {

    override func viewDidLoad() {
          super.viewDidLoad()
          self.colorCellDelegate = self
    }
}
BaSha
  • 2,356
  • 3
  • 21
  • 38
0

Did you do: xxTableViewController.colorCellDelegate = self in xxViewController?

And your delegate declaration should be weak:

weak var colorCellDelegate: SelectedColorDelegate?
Yun CHEN
  • 6,450
  • 3
  • 30
  • 33
  • Does the asisgnment of the ViewController to the colorCellDelegate go in the viewDidLoad()? – Marilyn García Dec 23 '16 at 06:38
  • @MarilynGarcía, where you create the xxTableViewController: let xxTableViewController = XXTableViewController(); xxTableViewController.colorCellDelegate = self – Yun CHEN Dec 23 '16 at 06:43