MikeC MikeC - 1 year ago 64
Swift Question

Swift: Returning data from child ViewController via NSNotificationCenter

I have a table view controller with a Sort button that I'm using to allow the user to change the sort order of a tableview. I segue to the Sort view controller when the button is pressed, and pass in the current sort order, which a UIPickerView picks up and sets as the selected item.

If the user changes the selected item in the picker, I want to send that back to the parent view controller so it can re-sort the table.

So far I've seen 2 methods: setting up a delegate or using the NSNotificationCenter. I'd decided to try the latter.

In my SortViewController, I capture any changes pickerView:didSelectRow:InComponent and then post the new value as a named notification.

In the parent view controller, I added an addObserver call in the init for the view controller so that it's listening for that notification, but the notifications never get sent, apparently.

here's the code:


var sortOrder: String = "Name"

selector: "setSortOrder:",
name: "sortOrderChangedNotification",
object: sortOrder )

Receiver function:

func setSortOrder( notification: NSNotification ) {
// set the sort order
println("Received sortOrderChangedNotification")


func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int) {
println("Picker view selection changed!")
var selRow = sortPickerView.selectedRowInComponent(0)
NSNotificationCenter.defaultCenter().postNotificationName("sortOrderChangedNotification", object: sortMethods[selRow] )

I never get the println output from setSortOrder, which as far as I know can mean that a) the notification doesn't get pushed (even though the println in didSelectRow does print) b) it isn't being received by my observer or c) my observer is set up wrong.

Any input would be appreciated.

Answer Source

Your -addObserver: declaration has to be like this:

override func viewDidLoad() {

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "setSortOrder:", name: "sortOrderChangedNotification", object: nil)    

Your -postNotificationName declaration has to be like this:

NSNotificationCenter.defaultCenter().postNotificationName("sortOrderChangedNotification", object: nil, userInfo: ["row": sortMethods[selRow]]) //userInfo parameter has to be of type [NSObject : AnyObject]?

Then, you can complete your -setSortOrder: method with notification.userInfo:

func setSortOrder(notification: NSNotification) {
    //deal with notification.userInfo

    println("Received sortOrderChangedNotification")

To stop observing:

deinit {