Search code examples
iosswiftclosurespushviewcontroller

Call function pushing UIViewController inside closure as though it were outside


I have a closure (handleMentionTap) inside two other closure (entireDescView.customize (2nd closure) and description (1st closure)). Now I would like to call the function pushProfileController(of: String) which is located in the same class (in order to push another view controller (newController). The functions need to be called inside the closure since calling them outside it causes memory leaks for a reason I currently don't know (I am using a library called ActiveLabel, didn't write it myself). However, the newController is not pushed (even though I use DispatchQueue.main.async as suggested in some answers on stackoverflow concerning similar problems). Nevertheless newController appears to be created and its data set (I am printing the data using var passedData: String? { didSet { print(passedData) } } ). How can I push the controller as though it were outside the closure (e.g. with self.pushProfileController(of: username)? I would really appreciate your help!

swift (everyhting in the same class):

var pushingViewController = false

//...

func pushProfileController(of: String) {
    if self.pushingViewController == false {
        self.pushingViewController = true
        DispatchQueue.main.async {
            let newController = NewController()
            newController.passedData = of //passedData is a string
            self.navigationController?.pushViewController(newController, animated: true)
        }

        self.pushingViewController = false
    }
}

let description: ActiveLabel = {

    let entireDescView = ActiveLabel()

    //set properties of controls container view

    //recognize (@hotel_x) and be able to push controller of 'hotel_x'
    entireDescView.customize({ (entireDescView) in
        entireDescView.enabledTypes = [.mention]
        entireDescView.mentionColor = UIColor(red: 25/255, green: 153/255, blue: 1, alpha: 1)
        entireDescView.handleMentionTap { username in
            self.pushProfileController(of: username) //also tried ThisClass().pushProfileController(of: username) which didn't push the controller either
        }
    })

    return entireDescView

}()

Solution

  • Have you checked navigationController? exists?

    Try adding the following before attempting to push the viewController:

    func pushProfileController(of: String) {
        if self.pushingViewController == false {
            self.pushingViewController = true
            DispatchQueue.main.async {
                guard let navController = self.navigationController else { return print("navigationController was nil") }
                let newController = NewController()
                newController.passedData = of //passedData is a string
                navController.pushViewController(newController, animated: true)
            }
    
            self.pushingViewController = false
        }
    }