将相同的视图控制器推入堆栈有奇怪的行为

Posted

技术标签:

【中文标题】将相同的视图控制器推入堆栈有奇怪的行为【英文标题】:pushing the same viewcontroller onto stack has odd behaviour going back 【发布时间】:2017-01-29 11:20:16 【问题描述】:

我在导航控制器中嵌入了一个 AccountViewController。

这就像一个包含关注者列表的 AccountProfile 屏幕

当我点击关注者时,我将相同的 ViewController 推到顶部,并填充该用户点击的详细信息。

当我在导航栏中回击时,我希望返回到以前的用户个人资料屏幕,但是它在丢弃顶部后显示新点击的用户屏幕。

这就是我正在做的推动

let userId = self.followerUsers[pickedCellIndexPathRow].userId!
let newUserVC = self.storyboard?.instantiateViewController(withIdentifier: "AccountVC") as! AccountViewController
newUserVC.userId = userId
self.navigationController?.pushViewController(newUserVC, animated: true)

这很好,但如前所述,返回会丢弃屏幕,但旧屏幕中有新用户的详细信息

我该如何解决它 - 基本上我应该能够堆叠配置文件并返回它们

AccountViewController:

import UIKit
import SwiftEventBus

class AccountViewController: UIViewController,UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, SegmentClickedDelegate 

func userClickedSegment(segmentNumber: Int)

    segmentIndex = segmentNumber



var segmentIndex = 0
    
    didSet
             collectionView.reloadData()
    




@IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() 
    super.viewDidLoad()

    collectionView.dataSource = self
    collectionView.delegate = self


    let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout
    layout?.sectionHeadersPinToVisibleBounds = true



 var model = UserProfileViewModel()

var user: UserResponse?
    didSet
        containerCell.user = self.user
        mapUserPhotos()
        mapFollowers()
        mapFollowing()
        if collectionView != nil 
            collectionView.reloadData()
        
    


public var userId : String="" 
    didSet
        model.getUserInfo(userId: userId)
        SwiftEventBus.onMainThread(self, name:EventBus.GetUserEvent)  result in
            let user = result.object as! UserResponse
            self.user = user
        

    


var reviews = [UserReviews]()
    didSet

        if collectionView != nil 
            //collectionView.reloadData()
        
    


var followingUsers = [UserFollowing]()
    didSet
        if collectionView != nil 
           // collectionView.reloadData()
        

    


var followerUsers = [UserFollowers]()
    didSet
        if collectionView != nil 
            //collectionView.reloadData()
        

    


func mapUserPhotos()
    if let result = user
        self.reviews = result .reviews!
    



func mapFollowers()

    if let result = user
        self.followerUsers = result .followers!
    


func mapFollowing()

    if let result = user
        self.followingUsers = result .following!

    







// number of sections is 2. Section above search and below search
func numberOfSections(in collectionView: UICollectionView) -> Int 
    return 2


//number of items for each section. Section above search will have only one and below search will be dynamic as per images we have
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 

    if section == 0 
        return 1
     else 
        switch segmentIndex//segmentedControl.selectedSegmentIndex 
        case 0 :
            return self.reviews.count
        case 1:
            return self.followerUsers.count
        case 2:
            return self.followingUsers.count

        default://break
            return self.reviews.count
        

    


private struct UserPostsBoard
    static let PhotoCellIdentifier = "UserPhotoCell"
    static let FollowerCellIdentifier = "FollowerCell"
    static let FollowingCellIdentifier = "FollowingCell"



var containerCell = AboveSearchCollectionViewCell()
// cell for item at given indexpath: if section is 0 then return cell above search, if section is 1 then return cell below search
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

    if indexPath.section == 0 
        // above search cell
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "aboveSearch", for: indexPath)

        containerCell = (cell as? AboveSearchCollectionViewCell)!
        containerCell.user = self.user

        return cell
     else 


        // below search cell

        print("self.segmentIndex\(self.segmentIndex)")

        //switch item//self.segmentIndex//segmentedControl.selectedSegmentIndex 
        switch self.segmentIndex//segmentedControl.selectedSegmentIndex 
        case 0 :
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: UserPostsBoard.PhotoCellIdentifier, for: indexPath)
            let item = self.reviews[indexPath.row]

            if let itemCell = cell as? UserPhotoCollectionViewCell
                itemCell.photo = item
            
            return cell
        case 1:
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: UserPostsBoard.FollowerCellIdentifier, for: indexPath)
            let item = self.followerUsers[indexPath.row]

            if let itemCell = cell as? UserFollowersCollectionViewCell
                itemCell.user = item
            
            return cell
        case 2:
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: UserPostsBoard.FollowingCellIdentifier, for: indexPath)
            let item = self.followingUsers[indexPath.row]

            if let itemCell = cell as? UserFollowingCollectionViewCell
                itemCell.user = item
            
            return cell

        default://break
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: UserPostsBoard.PhotoCellIdentifier, for: indexPath)
            let photoItem = self.self.reviews[indexPath.row]

            if let photoCell = cell as? UserPhotoCollectionViewCell
                photoCell.photo = photoItem
            
            return cell
        








    


    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
        if collectionView == self.collectionView 
            //pickedCell = collectionView.cellForItem(at: indexPath)
            //pickedCellIndexPathRow = indexPath.row
            //self.performSegue(withIdentifier: "showUserRating", sender: self)

        pickedCellIndexPathRow = indexPath.row

        switch segmentIndex//segmentedControl.selectedSegmentIndex 
            case 0 : self.performSegue(withIdentifier: "showUserRating", sender: self)
            case 1 : //self.performSegue(withIdentifier: "showFollower", sender: self)
                let userId = self.followerUsers[pickedCellIndexPathRow].userId!
                let newUserVC = self.storyboard?.instantiateViewController(withIdentifier: "AccountVC") as! AccountViewController
                newUserVC.userId = userId
                self.navigationController?.pushViewController(newUserVC, animated: true)//push(avc, animated: true, completion: nil)
                //self.navigationController?.popViewController(animated: false)

            //case 2 : self.performSegue(withIdentifier: "showFollower", sender: self)
            default:  break

        
        

                
var pickedCellIndexPathRow = 0



func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    if indexPath.section == 0 
        return CGSize(width: collectionView.frame.width, height: 200)
    else

        switch segmentIndex//segmentedControl.selectedSegmentIndex 
        case 0 :
            let width = (collectionView.frame.width / 3) - 1
            return CGSize(width: width, height: width)
        default:
            return CGSize(width: collectionView.frame.width, height: 80)
        

    


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat 

    return 1.0


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat 
    return 1.0





// implementation of function viewForSupplementaryElementOfKind, for section header of collectionView
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView 
    // returning the search bar for header
    let segmentView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "search", for: indexPath) as! TopBarCollectionReusableView
    segmentView.delegate = self
    return segmentView


// size for header in section: since we have 2 sections, collectionView will ask size for header for both sections so we make section header of first section with height 0 and width 0 so it remains like invisible.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize 
    // if section is above search bar we need to make its height 0
    if section == 0 
        return CGSize(width: 0, height: 0)
    
    // for section header i.e. actual search bar
    return CGSize(width: collectionView.frame.width, height: 50)

【问题讨论】:

您需要发布更多信息或代码以便我们提供帮助。 我刚刚构建了一个简单的项目来尝试复制问题(带有一些文本的标签,以及一个推动第二个视图的按钮,以及您的代码的复制粘贴),但一无所获。我同意@BurhanuddinSunelwala:我们可能需要更多代码来解决这个问题。 @raklos:这里有很多东西要解压(对于初学者,我找不到为 segmentIndex 分配除 0 以外的值的位置)。有时间我看看能不能把问题提炼出来;同时,如果您没有得到答案,您可能需要在这些 didSets 中使用断点和打印,以确定您的原始 VC 的用户 ID 被更改的位置。 【参考方案1】:

好的,我正在使用 SwiftEventBus,它会在网络调用返回响应时填充字段。

愚蠢的是,我忘了在课程中包含这个 - 所以没有它所有实例都会更新

override func viewWillDisappear(_ animated: Bool) 
        super.viewWillDisappear(animated)

        SwiftEventBus.unregister(self)
    

【讨论】:

以上是关于将相同的视图控制器推入堆栈有奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章

当视图控制器弹出或推入导航控制器堆栈时如何获得通知

UINavigationController 与子视图控制器的奇怪行为

推入导航堆栈时隐藏 TabBar 并在弹出导航堆栈时将其返回

UITableViewController 没有将视图推送到堆栈上

关闭视图控制器意外行为

将控制器推入堆栈后,后退按钮未显示