2017-05-08 94 views
0

My story board image is below附加观察者和不执行

当用户在小区中它会去详细视图控制器点击选择方法这里我张贴与所选择的索引(一个类的对象)的通知。详细视图控制器我使用了一个容器视图。在这个容器视图中,我使用了具有两个视图控制器的页面视图控制器,让我们对应地说A和B.我创建的这两个视图控制器都添加了观察者方法。但只有'A'视图控制器正在注册通知。如何获得B视图控制器中选定的索引(类的对象)..?

详细视图控制器的代码

override func viewDidLoad() { 
    super.viewDidLoad() 
    NotificationCenter.default.post(name: Notification.Name(rawValue: mynotificationkey), object: nil, userInfo: ["object": self.treatobj]) 



} 




override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if segue.identifier == "pageView2" { 
     if let destination = segue.destination as? PageViewController { 
      destination.treatmentObject = treatobj 



     } 



    } 

} 

,其执行第二视图控制器的细

override func viewDidLoad() { 
    super.viewDidLoad() 

    NotificationCenter.default.addObserver(self, selector: #selector(display(notification:)), name: Notification.Name(rawValue: mynotificationkey), object: nil) 

     } 

override func viewWillDisappear(_ animated: Bool) { 
    NotificationCenter.default.removeObserver(self) 
} 


    func display(notification: Notification){ 
    if let object = notification.userInfo { 
     if let obj = object["object"] { 

      treatObject = obj as! TreatMents 
      print(treatObject) 
      self.detailTitleLabel.text = treatObject.trtName 
      self.DesctextView.text = treatObject.desc1 




     } 
    } 

} 

代码不执行添加观察者

override func viewDidLoad() { 
    super.viewDidLoad() 


    about.text = treatObj.aboutkerala 
    //benifits = treatObj.benifits! 



    NotificationCenter.default.addObserver(self, selector: #selector(notfrecieved(notification:)), name: NSNotification.Name(rawValue: mynotificationkey), object: nil) 


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


func notfrecieved(notification: Notification) { 

    if let object = notification.userInfo { 
     if let obj = object["object"] { 
      print(obj) 
      treatObj = obj as! TreatMents 
      about.text = treatObj.aboutkerala 
      benifits = treatObj.benifits! 
      DispatchQueue.main.async { 
       self.tableView.reloadData() 
      } 


     } 
    } 

} 

首先视图控制器的代码页面视图控制器代码

class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource { 


var treatmentObject = TreatMents() 

lazy var VCArray : [UIViewController] = { 

    return [self.VCInstance(name: "DescFisrtVC"), 
      self.VCInstance(name: "DescSecondVC"), 
      ] 
}() 


private func VCInstance(name: String) -> UIViewController { 

    return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: name) 


} 


public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { 

    guard let viewControllerIndex = VCArray.index(of: viewController) else { 
     return nil 
    } 


    let previousIndex = viewControllerIndex - 1 

    guard previousIndex >= 0 else { 
     return VCArray.last 
    } 

    guard VCArray.count > previousIndex else { 
     return nil 
    } 



    return VCArray[previousIndex] 
} 


public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { 

    guard let viewControllerIndex = VCArray.index(of: viewController) else { 
     return nil 
    } 

    let nextIndex = viewControllerIndex + 1 

    guard nextIndex < VCArray.count else { 
     return VCArray.first 
    } 

    guard VCArray.count > nextIndex else { 
     return nil 
    } 


    return VCArray[nextIndex] 

} 


// A page indicator will be visible if both methods are implemented, transition style is 'UIPageViewControllerTransitionStyleScroll', and navigation orientation is 'UIPageViewControllerNavigationOrientationHorizontal'. 
// Both methods are called in response to a 'setViewControllers:...' call, but the presentation index is updated automatically in the case of gesture-driven navigation. 

public func presentationCount(for pageViewController: UIPageViewController) -> Int { 

    return VCArray.count 
} 


public func presentationIndex(for pageViewController: UIPageViewController) -> Int { 


    guard let firstViewController = viewControllers?.first, let firstViewcontrollerIndex = VCArray.index(of: firstViewController) else { 
     return 0 
    } 

    return firstViewcontrollerIndex 
} 
override func viewDidLoad() { 

      super.viewDidLoad() 
    self.dataSource = self 
    self.delegate = self 


    if let firstVc = VCArray.first { 

     setViewControllers([firstVc], direction: .forward, animated: true, completion: nil) 
    } 





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

您在哪里发布此通知NSNotification.Name(rawValue:mynotificationkey)。 ? – KKRocks

+0

您需要使用不同的密钥进行通知。 – KKRocks

+0

我将全局变量声明为mynotificationkey并将值存储到该变量 –

回答

0

从流程看来,在发布通知时,UIPageViewControllers中的两个VC尚未加载。

看一看的explanation given in doc

当定义一个页面视图控制器接口,可以提供 内容视图控制器一次一个(或两个在同一时间,这取决于 于脊柱位置和双面状态)或根据需要使用 数据源。当一次提供一个内容视图控制器时,您可以使用setViewControllers(_:direction:animated:completion :)方法来设置当前内容视图控制器。要支持 基于手势的导航,您必须使用 数据源对象提供视图控制器。

所以我的猜测是,由于一次页面加载,所以你的第二个控制器没有注册这个事件。

我对这个使用NSNotification的过程设计有异议,因为从你的代码看,当我看到你想要在屏幕上评估你的TreatMents对象时,你可以使用Singleton概念(使用会话)或使用KVO来解决这个问题。

编辑:

在PageViewController您实现这两个函数:

public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? 
public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? 

从VCArray返回一个VC,如:

return VCArray[previousIndex] 

您还可以在PageViewController treatmentObject,可以你可以在上面的委托函数中将这个变量传递给你的两个viewcontrollers离子如:

public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { 

    guard let viewControllerIndex = VCArray.index(of: viewController) else { 
     return nil 
    } 


    let previousIndex = viewControllerIndex - 1 

    guard previousIndex >= 0 else { 
     return VCArray.last 
    } 

    guard VCArray.count > previousIndex else { 
     return nil 
    } 

    let VC = VCArray[previousIndex]  // <------ Check this out 
    VC.treatObj = self.treatmentObject; // <------ Check this out 

    return VC 
} 

或者你也可以保存你选择的治疗在会话中,并检索它在两个视图控制器。

+0

在表视图中,它显示许多处理数。所有细节都存储在一个名为Treatments的类中,它的对象存储在一个处理数组中。当用户选择一个单元格时,我想将治疗阵列中的选定治疗对象传递给UIPageViewController的两个视图控制器... –

+0

我检查了这个方法。但是给出一个错误“类型'UIViewController'的值没有成员'treatObj'” –

+0

你没有这个'treatObject = obj as!治疗剂“在你的视图控制器? – NeverHopeless

0
  • 如果您想通知中心,那么您需要首先在内存中加载该类。

  • 如果您在课堂中添加了NotificationCenter,但该类未加载,所以这将不起作用。