-1

I have a controller with a Segment Control and two subviews

@IBOutlet weak var firstContainerView: UIView!
@IBOutlet weak var secondContainerView: UIView!

@IBAction func segmentControlChanged(sender: AnyObject) {
  if myController.selectedSegmentIndex == firstIndex {
    self.view.sendSubview(toBack: secondContainerView)
  }
  else {
    self.view.sendSubview(toBack: firstContainerView)
  }
}

The view controller for the first subview occasionally fires up an SVProgressHUD whilst working on a big task. If I change views, this can be hidden, or re-shown in the viewWillAppear / viewWillDisappear functions

override func viewWillAppear(_ animated: Bool) {
  super.viewWillAppear(animated)
  if (isWaiting) {
    SVProgressHUD.show()
    ...
  }
}

override func viewWillDisappear(_ animated: Bool) {
  super.viewWillDisappear(animated)
  if (isWaiting) {
    SVProgressHUD.dismiss()
  }
}

However, view.sendSubView(toBack: firstContainerView) does not fire viewWillDisappear.

Is there an event which the SubView viewController can receive to notify it of the change?

EDIT

After a lot of searching I found a way to get the viewController for the containing subView in this answer. In my case it was considerably complicated by the fact that this contained a a UIPageViewContainer which was created programtically; however I was able to get the viewController of the current page by following this tutorial

So I added this to the outermost view controller

override func prepare(for segue: UIStoryboardSegue, identifier: SegueIdentifier, sender: Any?) {
  switch identifier {
    case .PagingVCSegue:
      if let pvc = segue.destination as? PagingVCContainer {
        self.pagingViewContainer = pvc
        }
        default: break
        }
  }

This to the paging container

func getCurView() -> firstContainerView? {
  if (pagingVC?.viewControllers?.count)! > 0 {
    return pagingVC?.viewControllers![0] as? firstContainerView
  }
  return nil
}

and was then able to call a method in the view to hide the SVProgressHUD.

Community
  • 1
  • 1
QuantumTiger
  • 970
  • 1
  • 10
  • 22

3 Answers3

0

the thing is viewDidLoad, viewWillAppear, etc. are called on VCs, not on views. that's why it's better to use parent and child view controllers, so you can track the changes https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html

RinaLiu
  • 400
  • 2
  • 9
0

You cannot not know when the SVProgressHUD appears, because you are the one who is saying SVProgressHUD.show(). Similarly, you cannot not know when the view is sent to the back, because you are the one saying self.view.sendSubview(toBack:).

Therefore there is no need for any "event" or "notification" of what is happening. You know what is happening because you are doing it. If there is some method in your view that you want called at this moment, call it at this moment!

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Okay, so maybe I'm not understanding your answer. The show and dismiss are on a different view controller to the sendToBack, and the superview controller only has reference to the subviews, not their view controllers. So the question is how do I call a method in the subview controller – QuantumTiger Mar 02 '17 at 17:27
0

First I'd get rid of the view will appear and disappear stuff. Then I'd implement something simular to the following:

if selected == first
    bringFirstToFront();
    return
bringSecondToFront();

func bringFirstToFront(){
    topTag = func getTopViewName() -> view.children[0].tag 
    topTag == "$first_tag_name"
        //do nothing
        return
    //init views, start tasks... do w.e this view needs
}

...then do the about the same for the bringSecondToFront();

MarcJames
  • 189
  • 9