D051P0 D051P0 - 6 months ago 65
Swift Question

iOS popToRootViewControllerAnimated not working on delegate method

I've implemented a custom delegate method which should pop the root view controller if some data arrives from server.
By clicking the back button in child controller 1st method

back()
checks if any changes were made in text fields and shows an UIActionSheet in case there are some changes.

1.

func back() {
if modified {
let actionSheet = UIActionSheet(title: NSLocalizedString("SAVESETTINGS", comment: "Settings were changed. Do you want to save them?"), delegate: self, cancelButtonTitle: "No", destructiveButtonTitle: "Yes")
actionSheet.actionSheetStyle = .Default
actionSheet.showInView(self.view)
}
else {
self.navigationController?.popToRootViewControllerAnimated(true)
}
}


The ActionSheet delegate method sends the data and the controller is waiting for the answer

2.

func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {
if buttonIndex == 0 {
self.socket.send(someData, tag: someTag)
}
else {
self.modified = false
self.navigationController?.popToRootViewControllerAnimated(true)
}
}


The delegate method checks if the right answer is here and should pop the root view controller.

3.

func ackReceived(tag: Int32) {
if tag == someTag {
self.navigationController?.popToRootViewControllerAnimated(true)
}
}


The root view controller pops in 1st and 2nd method if there are no changes or if the 2nd button is pressed in UIActionSheet, but it is not working in 3d method.

All methods are called. I end up by

self.navigationController?.popToRootViewControllerAnimated(true)


I also checked the debugger, the navigation controller is not
nil
.

I hope you can help me with this problem.
Many thanks in advance.

Answer

Thank the hint from Wain, I've found the issue. func ackReceived(tag: Int32) {} wasn't called in the main queue. UI as UIKit methods are not thread safe and should be called in the main queue.

func ackReceived(tag: Int32) {
    if tag == someTag {
        dispatch_async(dispatch_get_main_queue(), {
                self.navigationController?.popToRootViewControllerAnimated(true)
                return
            })
    }
}

is the right way to call UI methods.

Thank you very much for your help.

Comments