36

I am developing an IOS Application. I have added the UIViewController in View Pager. I want to reinitialize it when the language is changed. Here I want to remove all child UIViewController from UIViewPager and again back to add all UIViewController into Viewpager. How can I do that?

Sample Code

let viewPager = ViewPagerController()
viewPager.options = options
viewPager.dataSource = self
viewPager.delegate = self
self.addChildViewController(viewPager)

Swift 3.1

xcode 8.3.3

Mahendra
  • 8,448
  • 3
  • 33
  • 56
Noorul
  • 3,386
  • 3
  • 32
  • 54

9 Answers9

88

After the long search to remove the view controllers from viewpager. I did it in the following way.

 if self.childViewControllers.count > 0{
        let viewControllers:[UIViewController] = self.childViewControllers
        for viewContoller in viewControllers{
            viewContoller.willMove(toParentViewController: nil)
            viewContoller.view.removeFromSuperview()
            viewContoller.removeFromParentViewController()
        }
    }

here self is , Current UIViewController which has View Pager. I need to remove all the childview controllers from the view pager. So, i get the list of view controllers from Current UIViewController. Then i removed it from the Parent view.

For swift 4.2

 if self.children.count > 0{
        let viewControllers:[UIViewController] = self.children
        for viewContoller in viewControllers{
            viewContoller.willMove(toParent: nil)
            viewContoller.view.removeFromSuperview()
            viewContoller.removeFromParent()
        }
    }

EDIT

Remove top childview controller:

   func removeTopChildViewController(){
         if self.children.count > 0{
             let viewControllers:[UIViewController] = self.children
                viewControllers.last?.willMove(toParent: nil)
                viewControllers.last?.removeFromParent()
                viewControllers.last?.view.removeFromSuperview()
         }
     }
Noorul
  • 3,386
  • 3
  • 32
  • 54
  • 7
    Do you know why chilid viewcontrollers would remain in memory? – János Dec 06 '17 at 15:04
  • 2
  • 4
    For swift 4.2 `self.children.forEach({ $0.willMove(toParent: nil); $0.view.removeFromSuperview(); $0.removeFromParent() })` – M Abubaker Majeed Nov 27 '18 at 23:53
  • 1
    @János it depends how you add the children. If you define a child VC as a property on parent, then add it as a child, and eventually remove it, the child will remain in memory. This is because it is still a property on parent VC. It will remain there until you make something like `childVC = nil` or parent is removed from the navigation stack, etc. – Rufat Mirza Dec 28 '18 at 08:53
  • 1
    According to the [manual](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621405-didmove) it's not necessary to call `willMove(toParent: nil)` if you call `removeFromParent()` – adnako Jul 23 '19 at 16:15
14
childViewControllers.forEach({
  $0.willMove(toParentViewController: nil)
  $0.view.removeFromSuperview()
  $0.removeFromParentViewController()
})

This answer is for swift 4.2 and above one is less than 4.2 versions.

children.forEach({
  $0.willMove(toParent: nil)
  $0.view.removeFromSuperview()
  $0.removeFromParent()
})

Here is the more concise version for removing all child controllers from the parent. You can use self.childViewControllers to define explicitly. As this approach, you can get rid of these extra conditions to check.

aturan23
  • 4,798
  • 4
  • 28
  • 52
Rehan Ali
  • 428
  • 4
  • 8
11

Swift 4.2 and above

create extension on UIViewController and add removeChild() method

extension UIViewController {
        
  func removeChild() {
    self.children.forEach {
      $0.willMove(toParent: nil)
      $0.view.removeFromSuperview()
      $0.removeFromParent()
    }
  }
} 

Usage:

call removeChild from parent UIViewController

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    self.removeChild()
}
aturan23
  • 4,798
  • 4
  • 28
  • 52
Suhit Patil
  • 11,748
  • 3
  • 50
  • 60
  • You should call `willMove(toParent: nil)` instead of `didMove(toParent: nil)`, `removeFromParent()` automatically calls `didMove(toParent: )` – Balázs Vincze Jan 27 '20 at 15:18
4

To add viewController:

let forgetPasswordVc = ForgetPasswordViewController()
self.addChild(forgetPasswordVc)
self.view.addSubview(forgetPasswordVc.view)
forgetPasswordVc.didMove(toParent: self)

To remove (inside the ForgetPasswordViewController):

self.removeFromParent()
self.view.removeFromSuperview()
aturan23
  • 4,798
  • 4
  • 28
  • 52
Zouhair Sassi
  • 1,403
  • 1
  • 13
  • 30
3

Swift 4.2 , XCode 10 , ios 12 , 2018 Answer

self.children.forEach{$0.willMove(toParent: nil);$0.view.removeFromSuperview();$0.removeFromParent()}

Hope it is helpful to someone

Prashant Tukadiya
  • 15,838
  • 4
  • 62
  • 98
3

Update for Swift 4

if self.children.count > 0{
    let viewControllers:[UIViewController] = self.children
    for viewContoller in viewControllers{
        viewContoller.willMove(toParent: nil)
        viewContoller.view.removeFromSuperview()
        viewContoller.removeFromParent()
    }
}
aturan23
  • 4,798
  • 4
  • 28
  • 52
user1872384
  • 6,886
  • 11
  • 61
  • 103
0
  if self.childViewControllers.count > 0{
        let viewControllers:[UIViewController] = self.childViewControllers
        for viewContoller in viewControllers{
            viewContoller.willMove(toParentViewController: nil)
            viewContoller.view.removeFromSuperview()
            viewContoller.removeFromParentViewController()
        }
    }
user1828845
  • 1,304
  • 1
  • 10
  • 17
-1

For add and remove child ViewController

//Remove child view controllers
for viewController in self.childViewControllers {
     self.remove(asChildViewController: viewController)

}

//Add child view controllers
self.add(asChildViewController: ViewController)
Nikhlesh Bagdiya
  • 4,316
  • 1
  • 19
  • 29
-1
  if self.childControllers.count > 0{
           let viewControllers:[UIViewController] = self.childControllers
           for viewContoller in viewControllers{
               viewContoller.willMove(toParentViewController: nil)
               viewContoller.view.removeFromSuperview()
               viewContoller.removeFromParentViewController()
           }
       }
  • It can be helpful for your problem – Nurillo Umarov Jun 15 '22 at 10:37
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 17 '22 at 15:14