代码之家  ›  专栏  ›  技术社区  ›  Utku Dalmaz

使用标记访问上一个viewController元素

  •  0
  • Utku Dalmaz  · 技术社区  · 6 年前

    在我的场景中,如果按钮存在,我需要访问上一个viewController中带有特定标记的按钮。该按钮将位于重用的表视图单元中。

    我想从当前视图中更改该按钮的文本。我考虑过用NotificationCenter发送数据,但可能有几个viewController已切换到当前视图,所以这不是一个好方法。

    试过一个

    override func didMove(toParentViewController parent: UIViewController?) {
        super.didMove(toParentViewController: parent)
    
        if parent == self.navigationController?.parent {
            //check if previous viewController has the button and access it    
        }
    }
    

    有什么帮助吗?

    1 回复  |  直到 6 年前
        1
  •  0
  •   FruitAddict    6 年前

    你说你的按钮代表你的模型(配置文件)的一个“跟随”状态。您可能希望有一个表示配置文件的模型:

    class Profile {
        var following : Bool = false
    }
    

    你的第一个 ViewController 可能是这样的:

    class ProfileListViewController : UIViewController, ProfileDetailsViewControllerDelegate {
        var profiles : [Profile] = [...]
    
        func userDidChangeProfileInfo(_ profile : Profile)() {
            (...)
        }
    }
    

    当你打开一个配置文件时,你会在你的 ProfileListViewController :

    func openProfileDetails(at indexPath: IndexPath) {
        let profile = profiles[indexPath.row]
    
        let detailsViewController = ProfileDetailsViewController.getInstance()
        detailsViewController.profile = profile
        detailsViewController.delegate = self
    
        self.navigationController?.pushViewController(detailsViewController, animated: true)
    }
    

    这个 delegate

    protocol ProfileDetailsViewControllerDelegate : class {
        func userDidChangeProfileInfo(_ profile : Profile)
    }
    

    这个 ProfileDetailsViewController

    class ProfileDetailsViewController : UIViewController {
    
       var profile: Profile? 
    
       weak var delegate : ProfileDetailsViewControllerDelegate?
    
       func didTapFollowButton() {
           profile.following = true
           delegate?.userDidChangeProfileInfo(profile)
       }
    }
    

    回到你的生活中 ProfileListView控制器 代表 方法,您可以重新加载行(如果愿意,也可以重新加载整个tableview):

    func userDidChangeProfileInfo(_ profile : Profile)() {
        if let row = profiles.firstIndex(where: { $0 == profile }) {
            tableView.reloadRows(at: [IndexPath(row: row, section: 0)], with: .automatic)
        }
    }
    

    接下来将在此索引处重新创建单元格,以便 cellForRowAt

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
        let cell = tableView.dequeueReusableCell(...)
    
        let profile = profiles[indexPath.row]
    
        if profile.following {
            cell.type = .following
        } else {
            cell.type = .notFollowing
        }
    
        return cell
    
    }
    

    细胞本身可以是这样的:

    enum ProfileTableCellMode {
        case following
        case notFollowing
    }
    
    class ProfileTableCell : UITableViewCell {
    
        @IBOutlet weak var followButton : UIButton!
    
        var state: ProfileTableCellMode = .notFollowing { //default value
            didSet {
                onStateUpdated()
            }
        }
    
        func onStateUpdated() {
            switch state {
    
            case .following:
                followButton.setTitle("Unfollow", for: .normal)
    
    
            case .notFollowing:
                followButton.setTitle("Follow", for: .normal)
    
            }
        }
    
    }
    

    你也可以跳过所有的授权工作,直接做这样的事情 ProfileListView控制器 :

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.tableView.reloadData()
    }
    

    所以当 又回到了最高控制者的位置。