Привет, ребята, я новичок в разработке iOS и все еще учусь

У меня есть три контроллера просмотра: viewController, SViewController, TViewController

В SviewController у меня есть метод уведомления sender.post при нажатии кнопки

В методах viewController, TViewController viewdidload () у меня есть методы .addobserver ()

Когда я нажимаю кнопку на SViewController и отправляю уведомление

Выполняется селектор View Controller , а не TviewController .

Я загрузил TviewController только в метод FirstVC, т.е. ViewController viewdidload ().

Поскольку segue снова выполняет viewdidload () из SviewController в TviewController с помощью другой кнопки, я попытался выделить строку обработчика завершения в глобальную переменную, чтобы ее значение оставалось таким же, и распечатать его (измененное значение) при повторной загрузке представления, тогда я пришел к знайте, что обработчик завершения вообще не выполняется, вот код

ViewController

import UIKit

extension Notification.Name{
    static var fnote = Notification.Name("fnote")
}

class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
 
    NotificationCenter.default.addObserver(self, selector: #selector(fhandle(notification:)), name: .fnote, object: nil)
    
    let storyboad = UIStoryboard(name: "Main", bundle: nil)
    let tvc = storyboad.instantiateViewController(identifier: "1") as! TViewController
    
    let _ = tvc.view
    print(tvc.isViewLoaded)
    
    print("journey")
}

@objc func fhandle(notification:Notification){
    label.text = "Haii welcome to the hyderabad"
}


}

SViewController

import UIKit
var temp:String = "HHH"

class SViewController: UIViewController {

 
 
    @IBAction func click(_ sender: Any) {
        
        NotificationCenter.default.post(name: .fnote, object: nil)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }
}

TviewController

import UIKit



class TViewController: UIViewController {

    @IBOutlet weak var label2: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(handler(notification:)) , name: .fnote, object: nil)
       
        print(temp)
        print("happy")
    }

   @objc func handler(notification:Notification)
    {
        print("jackson")
        label2.text = "Hurray"
        temp = label2.text ?? "Nothing"
    }
}

Может кто-нибудь, пожалуйста, помогите мне с этим

-1
Sri 14 Сен 2021 в 20:02

2 ответа

Лучший ответ

Вы не показали и не объяснили, где / когда / как вы собираетесь отображать представление из TViewController, но чтобы объяснить первую вещь, которую вы делаете неправильно ...

В этом коде:

override func viewDidLoad() {
    super.viewDidLoad()
 
    NotificationCenter.default.addObserver(self, selector: #selector(fhandle(notification:)), name: .fnote, object: nil)
    
    let storyboad = UIStoryboard(name: "Main", bundle: nil)
    let tvc = storyboad.instantiateViewController(identifier: "1") as! TViewController
    
    let _ = tvc.view
    print(tvc.isViewLoaded)
    
    print("journey")
}

Как только viewDidLoad() завершится (то есть сразу после строки print("journey")), ваш экземпляр tvc TViewController будет уничтожен. То есть он выгружается из памяти, и никакой код внутри него не может выполняться, потому что он больше не существует.

Это называется «выход за рамки».

Итак, когда вы пытаетесь опубликовать уведомление от SViewController, TViewController не существует, поэтому его код не работает, чтобы "наблюдать" за уведомлением.

Вот очень простой пример нескольких контроллеров представления, наблюдающих за уведомлением:

enter image description here

Когда вы push из ViewController в TViewController, вы получаете новый экземпляр TViewController, а исходный экземпляр ViewController все еще существует.

Когда вы push из TViewController в SViewController, вы получаете новый экземпляр SViewController и обоих ViewController и TViewController все-еще существует.

Когда вы нажимаете кнопку «Опубликовать», ViewController и TViewController каждый выполнит функцию, которую вы назначили для наблюдения за уведомлением.

Когда вы затем вернетесь к TViewController, вы увидите, что текст метки изменился, а когда вы вернетесь к ViewController, вы увидите, что текст метки также изменился.

Обратите внимание: если вы затем снова нажмете на TViewController, вы получите новый экземпляр , и его метка вернется к исходному тексту.

extension Notification.Name{
    static var fnote = Notification.Name("fnote")
}

class ViewController: UIViewController {
    
    @IBOutlet weak var label: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        NotificationCenter.default.addObserver(self, selector: #selector(fhandle(notification:)), name: .fnote, object: nil)
        print("journey")
    }
    
    @objc func fhandle(notification:Notification) {
        print("Got it!")
        label.text = "Haii welcome to the hyderabad"
    }
    
}

class TViewController: UIViewController {
    
    @IBOutlet weak var label2: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        NotificationCenter.default.addObserver(self, selector: #selector(handler(notification:)), name: .fnote, object: nil)
        print("happy")
    }
    
    @objc func handler(notification:Notification) {
        print("jackson")
        label2.text = "Hurray"
    }

}

class SViewController: UIViewController {

    @IBOutlet var infoLabel: UILabel!
    
    @IBAction func click(_ sender: Any) {
        NotificationCenter.default.post(name: .fnote, object: nil)
        infoLabel.text = "Notification Posted"
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}
0
DonMag 15 Сен 2021 в 13:34
let storyboad = UIStoryboard(name: "Main", bundle: nil)
let tvc = storyboad.instantiateViewController(identifier: "1") as! TViewController
let _ = tvc.view
print(tvc.isViewLoaded)

Это не способ проверить уведомление. Отодвиньте контроллер TViewController от контроллера ViewController. Затем отправьте уведомление от вашего целевого контроллера.

-1
nitin.agam 14 Сен 2021 в 17:32