6

I have a Split View Controller and when the user clicks a cell in the Table View, the app shows a View Controller with a Container View and a Segment Control to switch between two children view controllers.

The first child view controller is a Collection View Controller. In every cell of the Collection View there is a word.

The view looks like this:

view screen

I add the child view controller programmatically with this code (from the Detail View Controller, the container of Subviews):

override func viewDidLoad() {


    self.currentViewController = self.storyboard?.instantiateViewController(withIdentifier: "WordCollectionViewControllerID")
    (self.currentViewController as! WordCollectionViewController).text = self.text
    self.currentViewController?.view.translatesAutoresizingMaskIntoConstraints = false
    self.addChildViewController(self.currentViewController!)
    self.addSubview(subView: self.currentViewController!.view, toView: self.textContainerView)
    self.currentViewController?.view.layoutIfNeeded()
    self.currentViewController?.didMove(toParentViewController: self)

    super.viewDidLoad()

}

func addSubview(subView: UIView, toView parentView: UIView) {
    parentView.addSubview(subView)

    var viewBindingsDict = [String: AnyObject]()
    viewBindingsDict["subView"] = subView
    parentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[subView]|", options: [], metrics: nil, views: viewBindingsDict))
    parentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[subView]|", options: [], metrics: nil, views: viewBindingsDict))
}

Here is the code for switch between the two children views with the segmented control:

@IBAction func changeChildViewController(_ sender: UISegmentedControl) {
    if sender.selectedSegmentIndex == 0 {
        let newViewController = self.storyboard?.instantiateViewController(withIdentifier: "WordCollectionViewControllerID")
        (newViewController as! WordCollectionViewController).text = self.text
        newViewController!.view.translatesAutoresizingMaskIntoConstraints = false
        cycle(from: self.currentViewController!, to: newViewController!)
        self.currentViewController = newViewController
        print("Reorder")
    } else {
        let newViewController = self.storyboard?.instantiateViewController(withIdentifier: "NavigationControllerEditTextViewControllerID")
        (newViewController?.childViewControllers[0] as! EditTextViewController).text = self.text
        newViewController!.view.translatesAutoresizingMaskIntoConstraints = false
        cycle(from: self.currentViewController!, to: newViewController!)
        self.currentViewController = newViewController
        print("Edit")
    }
}

func cycle(from: UIViewController, to: UIViewController) {
    from.willMove(toParentViewController: nil)
    self.addChildViewController(to)

    self.addSubview(subView: to.view, toView: self.textContainerView)

    to.view.layoutIfNeeded()

    from.view.removeFromSuperview()

    from.removeFromParentViewController()
    to.didMove(toParentViewController: self)
}

To be able to reorder the cells I have implemented this method for my custom CollectionViewController class:

override func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {

    // Swap values if sorce and destination
    let change = textArray[sourceIndexPath.row]


    textArray.remove(at: sourceIndexPath.row)
    textArray.insert(change, at: destinationIndexPath.row)


    // Save changes in Core Data
    text?.reordered_text = textArray.joined(separator: " ")

    (UIApplication.shared.delegate as! AppDelegate).saveContext()


    collectionView.reloadData()
}

The problem is that when I click the Table View Cell and the app shows the Container View with the Collection View Controller embedded, I can't reorder the cells,and to be able to do this I have to change the Child (with the Segmented Control) and then return to the Collection View.

How can I solve this problem?

alessionossa
  • 923
  • 2
  • 15
  • 41

2 Answers2

0

I would check two things:

Firstly you call willMoveToParentViewController in your cycle(from: UIViewController, to: UIViewController) method, but not in viewDidLoad, try to do this. From what I can read you should be able to call cycle in your viewDidLoad method, calling a method on a Nil-object (from) does nothing.

Secondly check if your WordCollectionViewController collectionView delegate and dataSource are set properly when it loads the first time. These can be tricky at times when loading from StoryBoard if elements are not initialised in time.

Aerows
  • 760
  • 6
  • 22
0

Try to implement these methods:

func beginInteractiveMovementForItem(at: IndexPath) -> Bool
func updateInteractiveMovementTargetPosition(targetPosition: CGPoint)
func endInteractiveMovement()
func cancelInteractiveMovement()

You can follow this tutorial: http://nshint.io/blog/2015/07/16/uicollectionviews-now-have-easy-reordering/