当用户返回那个 VC
时,我需要刷新我的 collectionView,因为他/她在 detailVC
中所做的会影响以前的 VC 数据。我在 viewDidLoad()
和 viewDidAppear()
中都尝试了 collectionView.reloadData()
我的 VC
有 collectionView
在里面。结果是,当用户在 detailVC
中点击 'Back'
时,viewDidLoad()
和 viewDidAppear()
不工作。因此,我尝试在 detailVC
中调用其中一个并实例化 firstVC
(它具有 collectionView
)
然后我收到一个运行时错误,提示 collectionView is nil
。有什么想法吗? (顺便说一句,它们之间的 segue 是 ShowPush
,我无法更改它,因为我必须在我的应用程序中进行此 segue 的转换。)
这是第一个VC:
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
数据库中。
这是详细VC:
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
他/她可以删除选定的标签。如您所见,它在 Realm 中不断变化。当用户在 detailVC
中删除一些标签并按下 Back
按钮时,删除的标签仍然看起来像在 SkillsVC
中选择的那样。但是,如果用户转到另一个 VC 并返回到 SkillsVC
(通过这种方式 viewDidLoad() 将起作用),则似乎未选择删除的标签。就这样。
最佳答案
如果您正在寻找的只是在后退按钮上重新加载
您可以做的是创建您自己的自定义 UIBarButtonItem
,这将使您从“详细信息 View Controller ”向后导航。添加您自己的后退按钮后,下一步应该为 UIBarBUttonItem
和 pop
添加一个 IBAction
您的“详细信息 View Controller ”。
在执行此操作之前,您应该创建一个委托(delegate),该委托(delegate)将在弹出发生之前执行,这将重新加载您的 UICollectionView
。
以下不是实现您想要的效果的最佳方式:
在你的第二个 View Controller 的 didSelectItem
中,你在这里创建了一个新的 View Controller ,你不应该强制调用 viewDidAppear
。由于您正在创建一个新的 UIViewController
,因此您没有引用您之前的 UIViewController
,因此您的 UICollectionView
为 nil。
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)将回调发送到以前的 View Controller 或执行操作。 创建一个委托(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()
}
}
}
在您的第一个 View Controller 中-
func reloadCollectionView(){
collectionView.reloadData()
}
注意:在您的prepareForSegue
中,请记住将详细 View Controller 的委托(delegate)设置为您的第一个 View Controller
关于ios - 当用户在详细 View Controller 中点击 `Back` 时触发一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40848228/