2017-02-03 1 views
-2

Я создал BaseClassviewController, и все мои контроллеры получены от этого контроллера. Я делаю следующие шаги:Функция переопределения в iOS

  1. Установить пользовательский делегат в BaseClassViewController.
  2. Реализовать всю функцию протокола в BaseClassViewController.
  3. Затем я нажимаю HomeController, полученный от BaseClassViewController.
  4. Снова я толкаю DetailController также полученный из BaseClassViewController.

Теперь, когда функция делегат называется я должен получить контроль в DetailController, но я получаю контроль в HomeController.

Итак, мой вопрос в том, почему его не вызывающий верхний контроллер при навигации i.e DetailController и можно ли вызвать функции делегата в обоих контроллерах?

P.S Я переопределяю функции делегата во всех дочерних контроллерах.

EDIT: После прочтения ответов и комментариев, я думаю, что я не был настолько ясен, поэтому добавлял следующий фрагмент кода.

В Helper Класс:

@objc protocol SampleDelegate: class 
{ 
    @objc optional func shouldCallDelegateMethod() 
} 

class SampleHelper: NSObject 
{ 
    var sampleDelegate:SampleDelegate! 
    static var sharedInstance = SampleHelper() 

    //It is triggered 
    func triggerDelegateMethod() 
    { 
    sampleDelegate!.shouldCallDelegateMethod() 
    } 

    func apiCall() 
    { 
     let urlString = URL(string: "https://google.com") 
     if let url = urlString { 
     let task = URLSession.shared.dataTask(with: url) { (data, response, error) in 
     if error != nil { 
     print(error) 
     } else { 
     if let usableData = data { 
      self. triggerDelegateMethod() 
      } 
     } 
     } 
     task.resume() 
    } 
    } 
} 

В BaseClass

class BaseClassViewController: UIViewController,SampleDelegate{ 

    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 

    override func viewWillAppear(_ animated: Bool) 
    { 
     super.viewWillAppear(true) 
     SampleHelper.sharedInstance.delegate = self; 
    } 

    func shouldCallDelegateMethod() 
    { 
     //Override 
    } 


} 

В HomeController то есть первый контроллер для толкания

class HomeViewController: BaseClassViewController{ 

     override func shouldCallDelegateMethod() 
     { 
      // 
     } 
} 

В DetailController т.е. второй контроллер выталкивается после HomeController от HomeController ,

class DetailViewController: BaseClassViewController{ 
     override func viewDidLoad() 
     { 
      super.viewDidLoad() 
      SampleHelper.sharedInstance.apiCall() 
     } 
     override func shouldCallDelegateMethod() 
     { 
      // 
     } 
} 

Теперь мой вопрос, когда делегат вызывается из вспомогательного класса он называет shouldCallDelegateMethod в HomeViewController, но не в DetailViewController. Но DetailViewController находится в верхней части навигационного массива.

Также есть ли возможность запускать одну и ту же функцию в обоих контроллерах одновременно с делегатом?

+0

Пожалуйста, поделитесь своим фрагментом кода объявления и переопределения делегатов. – Aamir

+0

Его довольно большой код, чтобы показать здесь конструктивным способом. Но я думаю, что я объяснил это достойным образом концептуально .. –

+0

@Aamir Если вам нужно что-нибудь конкретное, дайте мне знать, я могу объяснить. –

ответ

0

В BaseClassviewController вы должны иметь переменную/свойство delegate.

В HomeController и DetailController вам необходимо установить, что delegate переменные/свойство self если вы хотите, что класс будет слушать делегат обратных вызовов.

0

Edit 2

После того, как Вы отправили ваш код, я понимаю, что вы использовали одноплодный класс для делегирования.

Делегаты позволяют объекту отправлять сообщение другому объекту.

Ответа на этот вопрос по запросу "No". Вы не можете запускать одну и ту же функцию в обоих контроллерах одновременно с делегатом.

Если вы действительно хотите прослушать событие в обоих классах одновременно, я предлагаю вам вместо 0 делегата использовать NSNotificationCenter.

+0

Write SampleHelper.sharedInstance.delegate = self; in viewWillappear метод homeVC и DetailVC. – Mahesh

+0

Тогда это бьет цель подкласса, а также я переопределил методы во всех дочерних классах. –

0

Основная проблема заключается в том, что вы используете делегат с singleton.

Установка делегата в viewWillAppear также не является хорошим решением. Короче говоря, когда диспетчеры просмотра отображаются и скрыты, делегат на вашем синглете будет меняться все время.

Не используйте делегатов с одиночными точками. Используйте обратный вызов завершения. В противном случае вы столкнетесь с проблемами.

func apiCall(onCompletion: (() -> Void)?) { 
    let urlString = URL(string: "https://google.com") 
    if let url = urlString { 
     let task = URLSession.shared.dataTask(with: url) { (data, response, error) in 
      if error != nil { 
       print(error) 
      } else if let usableData = data { 
       onCompletion?() 
      } 
     } 

     task.resume() 
    } 
} 

называется как

SampleHelper.apiCall { 
    // do something 
} 
+0

Я согласен с вашей точкой, но все же он не отвечает на мой вопрос, почему он не вызвал func в деталях, чем в Home Controller. –

+0

Также, если вы можете разработать немного, чтобы подробно остановиться на вашей точке, будет полезно. –

+0

Но этот делегат можно вызывать из нескольких мест в одном классе. Например, createGroup для XMPP .. в этом случае я могу получить ответ API а также сообщить, что группа была создана, а также я могу получать сообщения через XMPP. Поэтому мне нужно обновить контроллеры, чтобы обновить их интерфейс. –

-1

То не правильный путь для достижения этой цели. Я считаю, что правильный способ установить делегат только в соответствующем UIViewController вместо того, чтобы реализовать этот протокол на BaseViewController, а затем переопределить в дочерних классах. Поэтому ваша реализация должна быть такой.

В HomeViewController

class HomeViewController: BaseClassViewController { 

    override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(true) 
    SampleHelper.sharedInstance.delegate = self; 
    } 

    func shouldCallDelegateMethod() { 
    // Provide implementation 
    } 

} 

В DetailViewController

class DetailViewController: BaseClassViewController { 

    override func viewWillAppear(_ animated: Bool) { 
    super.viewDidLoad() 
    SampleHelper.sharedInstance.delegate = self; 
    } 

    func shouldCallDelegateMethod() { 
    // Provide implementation 
    } 

} 

Используя этот imeplementation вы будете иметь только один-к-одному связи шаблон проектирования, обеспечивая право UIViewController называться.

+0

Ну почему это не правильный путь? –

+0

Поскольку мы устанавливаем другой уровень косвенности путем реализации протокола в «BaseViewController», мы должны реализовать его непосредственно в соответствующем ViewController. – Aamir

+0

Но мне нужно реализовать его в разных контультерах. И я не могу понять, почему он добавляет уровень косвенности, поскольку делегат всегда назначается BaseClassViewController, и мы просто переопределяем эти функции. –

 Смежные вопросы

  • Нет связанных вопросов^_^