2016-11-28 4 views
2

Мне нужно обновить мою коллекциюView, когда пользователь вернется к этому VC, потому что то, что он сделал в detailVC, влияет на предыдущие данные VC. Я попробовал collectionView.reloadData() как в viewDidLoad(), так и в viewDidAppear() моего VC имеет collectionView. И пришло, что когда пользователь забирает 'Back' в detailVC, оба viewDidLoad() и viewDidAppear() не работают. Итак, я попытался позвонить одному из них в detailVC с экземпляром firstVC (который имеет collectionView) , после чего я получил ошибку времени выполнения, которая указала collectionView is nil. Есть предположения? (Кстати, то переход между ними ShowPush, и я не могу изменить это, потому что я должен иметь переход этого Segue в моем приложении.)Запуск функции при отладке пользователя `Back` в контроллере подробного представления

Вот firstVC:

class SkillsController: UIViewController{ 

    @IBOutlet weak var collectionView: UICollectionView! 

    var TAGS: [TAG] = [] 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     let nib = UINib(nibName: "TagCell", bundle: nil) 
     collectionView.register(nib, forCellWithReuseIdentifier: "tagCell") 
     self.sizingCell = (nib.instantiate(withOwner: nil, options: nil) as NSArray).firstObject as! TagCell? 
     self.loadMore() 
    } 

    override func viewDidAppear(_ animated: Bool) { 
     super.viewDidAppear(animated) 
     print("back to skills") 
     self.TAGS = TagManager.shared.tagList 
     collectionView.reloadData() 
    } 

} 

TAGS это моя данные, которые хранятся в базе данных Realm.

Вот detailVC:

class SeeSelectedController: UICollectionViewController { 

    var TAGS: [TAG] = [] 

    @IBOutlet weak var layout: FSQCollectionViewAlignedLayout! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     if currentTab.shared.isSkill { 
      self.title = "Selected Skills" 
      //init tags 
      let list = RealmManager.shared.skills 
      if let list = list { 
       for element in list { 
        TAGS.append(TAG(n: element.value!, iS: true)) 
       } 
      } 
      collectionView?.reloadData() 
     }else{ 
      self.title = "Selected Needs" 
      //init tags 
      let list = RealmManager.shared.needs 
      if let list = list { 
       for element in list { 
        TAGS.append(TAG(n: element.value!, iS: true)) 
       } 
      } 
      collectionView?.reloadData() 
     } 

     let nib = UINib(nibName: "TagCell", bundle: nil) 
     collectionView?.register(nib, forCellWithReuseIdentifier: "tagCell") 
    } 

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 
     let item = TAGS[indexPath.row].name! 
     let currentState = TAGS[indexPath.row].isSelected! 
     TAGS[indexPath.row].isSelected = currentState ? false:true 
     if currentState { 
      print("deselect") 
      //remove from realm 
      RealmManager.shared.deleteItemFromList(type: getTypeOfTag(isSkill: currentTab.shared.isSkill), item: item) 
     }else{ 
      print("select") 
      //add to realm 
      RealmManager.shared.addItemToList(type: getTypeOfTag(isSkill: currentTab.shared.isSkill), item: item) 
     } 
     if currentTab.shared.isSkill { 
      let VC: SkillsController = storyboard?.instantiateViewController(withIdentifier: "SkillsController") as! SkillsController 
      VC.viewDidAppear(true) 
     } 
     collectionView.reloadData() 
     //addd 
    } 

} 

Так как это работает? в файле SkillsVC пользователь может выбрать несколько тегов из пула, в detailVC, который является SeeSelecteVC, он может удалить выбранные теги. Он постоянно меняется в Царстве, как вы можете видеть. Проблема, когда пользователь сбросил некоторые теги в detailVC и нажал кнопку Back, сброшенные теги по-прежнему выглядят как выбранные в SkillsVC. Однако, если пользователь переходит в другой VC и возвращается к SkillsVC (таким образом, viewDidLoad() будет работать), отбрасываемые теги, кажется, не выбраны. Это все.

+0

'viewDidAppear()' является правильным местом для 'collectionView.reloadData()' , ut before, вам также необходимо обновить данные, используемые в коллекцииView, и я полагаю, что вы этого не сделали. – shallowThought

+0

Нет, я постоянно обновляю данные, но в 'detailVC' данные должны обновляться. поэтому он существует. Когда пользователь решает вернуться к «firstVC», данные уже обновлены, но я не могу запустить функцию для перезагрузки 'collectionView' – Faruk

+0

, вы показываете свой код, я думаю, причина, по которой вы не показывали – aircraft

ответ

1

Если то, что вы ищете просто перезагрузить на кнопку назад

Что вы можете сделать, это создать свой собственный UIBarButtonItem, который сделает вам перемещаться в обратном направлении от вашего «подробно контроллера представления». Что вы должны сделать после добавления своей кнопки назад, добавьте IBAction для UIBarBUttonItem и pop ваш «контроллер представления деталей».

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

Следующая не лучший способ добиться того, что вы хотите: В вашем didSelectItem для второго контроллера представления, вы создаете новый контроллер представления здесь, и вы не должны заставлять вызов viewDidAppear. Поскольку вы создаете новый UIViewController, вы не ссылаетесь на предыдущий UIViewController, из которого вы пришли, и ваш UICollectionView - это нуль.

if currentTab.shared.isSkill { 
    //remove the below lines and call the delegate here 
    let VC: SkillsController = storyboard?.instantiateViewController(withIdentifier: "SkillsController") as! SkillsController 
    VC.viewDidAppear(true) 
} 
collectionView.reloadData() 

То, что вы должны делать: Вы должны использовать делегат для отправки обратных вызовов предыдущих контроллеров просмотра или выполнения действий. Чтобы создать delegate-

Использование первого подхода (с помощью вашей собственной кнопки возврата) -

protocol delegateVC{ 

    func reloadCollectionView() 
} 

class SeeSelectedController: UICollectionViewController{ 
    //add this inside this class 
    var delegate : delegateVC? 
    ... 

    //implement your IBAction for back button and inside it- 
    ... { 

     self.delegate.reloadCollectionView() 
    } 
} 

ИЛИ второй подход я указал, (Просто измените ваш didSelectItem и перезагрузит CollectionView, нет необходимости беспокоиться о задних кнопках на все и сохранить хлопоты, я настоятельно рекомендую этот подход)

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 
     let item = TAGS[indexPath.row].name! 
     let currentState = TAGS[indexPath.row].isSelected! 
     TAGS[indexPath.row].isSelected = currentState ? false:true 
     if currentState { 
      print("deselect") 
      //remove from realm 
      RealmManager.shared.deleteItemFromList(type: getTypeOfTag(isSkill: currentTab.shared.isSkill), item: item) 
     }else{ 
      print("select") 
      //add to realm 
      RealmManager.shared.addItemToList(type: getTypeOfTag(isSkill: currentTab.shared.isSkill), item: item) 
     } 
     if currentTab.shared.isSkill { 
      self.delegate.reloadCollectionView() 
     } 
    } 
} 

и в первом взгляде контроллер-

func reloadCollectionView(){ 
    collectionView.reloadData() 
} 

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

+0

спасибо за ваш ответ. Я сделал небольшое исследование, и некоторые говорят, что «NotificationCenter» может быть полезным (http://stackoverflow.com/a/25921822/1404324). что вы думаете об этом решении? Мне понравилось больше, но мне нужна дополнительная помощь для его реализации, поскольку у меня нет опыта с делегатами. – Faruk

+0

Прочитайте делегатов, поскольку они очень важны, когда дело касается iOS. См. Пример, который я написал, это довольно просто. По сути, протокол - это то, как вы идете об использовании делегатов. Вы можете использовать «NotificationCenter», но вам потребуется передать словарь, если вам нужно передать аргументы и удалить наблюдателей, а что нет. Проведите некоторое исследование относительно того, каковы ваши личные предпочтения и что лучше, и где, не верьте мне на слово. Есть несколько случаев, когда вам также нужны уведомления. Также есть много уроков, посвященных делегатам: – Rikh

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