prepareForSegue 里面的函数不会执行

Posted

技术标签:

【中文标题】prepareForSegue 里面的函数不会执行【英文标题】:Function inside prepareForSegue will not execute 【发布时间】:2017-02-19 21:38:02 【问题描述】:

我正在制作一个表格视图,其中包含频道,用户可以点击该频道进入该频道。当用户点击该频道时,我想从 firebase 获取频道的 ID 和名称。以下功能应该可以工作,但事实并非如此。执行 segue 函数本身的准备,但不执行 if let channel = sender as?频道 //未执行 。所以我没有看到“执行”的打印。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    super.prepare(for: segue, sender: sender)
        if let channel = sender as? Channel 
        print("executed")
        let chatVc = segue.destination as! channelMultiplayerViewController
        chatVc.channel = channel
        chatVc.channelRef = channelRef.child(channel.id)
    

如果你需要,这是我的完整代码:

import UIKit
import Firebase
import Foundation

enum Section: Int 
    case createNewChannelSection = 0
    case currentChannelsSection


extension multiplayerChannelView: UISearchResultsUpdating 
    func updateSearchResults(for searchController: UISearchController) 
        filterContentForSearchText(searchText: searchController.searchBar.text!)
    


class multiplayerChannelView: UITableViewController 


    // MARK: Properties
    var channels: [Channel] = []
    let searchController = UISearchController(searchResultsController: nil)
    var filteredChannels = [Channel]()
    private lazy var channelRef: FIRDatabaseReference = FIRDatabase.database().reference().child("channels")
    private var channelRefHandle: FIRDatabaseHandle?
    var senderDisplayName: String?
    var newChannelTextField: UITextField?


    override func viewDidLoad() 
        super.viewDidLoad()
        title = "Rooms"
        observeChannels()
        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        definesPresentationContext = true
        tableView.tableHeaderView = searchController.searchBar
    
    deinit 
        if let refHandle = channelRefHandle 
            channelRef.removeObserver(withHandle: refHandle)
        
    
    func filterContentForSearchText(searchText: String, scope: String = "All") 
        filteredChannels = channels.filter  Channel in
            return (Channel.name.lowercased().range(of: searchText.lowercased()) != nil)
        

        tableView.reloadData()
    
    @IBAction func createChannel(_ sender: AnyObject) 
        if let name = newChannelTextField?.text 
            let newChannelRef = channelRef.childByAutoId()
            let channelItem = [
                "name": name
            ]
            newChannelRef.setValue(channelItem)
        
    

    override func viewDidAppear(_ animated: Bool) 
        super.viewDidAppear(animated)
    
    private func observeChannels() 
        channelRefHandle = channelRef.observe(.childAdded, with:  (snapshot) -> Void in // 1
            let channelData = snapshot.value as! Dictionary<String, AnyObject> // 2
            let id = snapshot.key
            if let name = channelData["name"] as! String!, name.characters.count > 0 
                self.channels.append(Channel(id, name: name))
                self.tableView.reloadData()
             else 
                print("Error! Could not decode channel data")
            
        )
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int 
        return 2
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        if let currentSection: Section = Section(rawValue: section) 
            switch currentSection 
            case .createNewChannelSection:
                return 1

            case .currentChannelsSection:
                if searchController.isActive && searchController.searchBar.text != "" 
                    return filteredChannels.count
                
                else
                    return channels.count
                
            
         else 
            return 0
        
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let reuseIdentifier = (indexPath as NSIndexPath).section == Section.createNewChannelSection.rawValue ? "NewChannel" : "ExistingChannel"
        let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath)

        if (indexPath as NSIndexPath).section == Section.createNewChannelSection.rawValue 
            if let createNewChannelCell = cell as? CreateChannelCell 
                newChannelTextField = createNewChannelCell.newChannelNameField
            
         else if (indexPath as NSIndexPath).section == Section.currentChannelsSection.rawValue 
            if searchController.isActive && searchController.searchBar.text != "" 
                cell.textLabel?.text = filteredChannels[(indexPath as NSIndexPath).row].name
             else 
                cell.textLabel?.text = channels[(indexPath as NSIndexPath).row].name
            
        

        return cell
    

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
        super.prepare(for: segue, sender: sender)
            if let channel = sender as? Channel 
            print("executed")
            let chatVc = segue.destination as! channelMultiplayerViewController
            chatVc.channel = channel
            chatVc.channelRef = channelRef.child(channel.id)
        
    

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        if indexPath.section == Section.currentChannelsSection.rawValue 
            var channel = channels
            if searchController.isActive && searchController.searchBar.text != "" 
                channel = [filteredChannels[(indexPath as NSIndexPath).row]]
                     
            else
            
                channel = [channels[(indexPath as NSIndexPath).row]]
            

            self.performSegue(withIdentifier: "ShowChannel", sender: channel)
        
    


这是一个 Channel 类型的 .swift 文件

import Foundation

class Channel: NSObject 
    let id:String
    let name:String
    init (_ id:String, name:String)
        self.id = id
        self.name = name
    

谢谢!

【问题讨论】:

您确定在 Interface Builder 中正确设置了 segue 标识符和链接吗? 有一个push segue“ShowChannel”链接到另一个视图控制器,我认为这部分工作正常。 【参考方案1】:

我也回复了您的上一篇文章,但是您正在向

发送一系列频道
override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    super.prepare(for: segue, sender: sender)
        if let channel = sender as? Channel 
        print("executed")
        let chatVc = segue.destination as! channelMultiplayerViewController
        chatVc.channel = channel
        chatVc.channelRef = channelRef.child(channel.id)
    

那么块 - 如果让通道 = 发件人为?频道 - 不起作用。

将单元格选择代码更改为:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    if indexPath.section == Section.currentChannelsSection.rawValue 
        if searchController.isActive && searchController.searchBar.text != "" 
            let channel = filteredChannels[indexPath.row]
            self.performSegue(withIdentifier: "ShowChannel", sender: channel)
                 
        else
        
            let channel = channels[indexPath.row]
            self.performSegue(withIdentifier: "ShowChannel", sender: channel)
        
    

【讨论】:

这里有同样的问题,我没有得到“执行”的打印。当我在 self.performSegue 之后立即打印(频道)时,我得到了这个:[] 所以不是应该是这样的 ID 和名称

以上是关于prepareForSegue 里面的函数不会执行的主要内容,如果未能解决你的问题,请参考以下文章

prepareForSegue 不会初始化新视图

prepareForSegue 更新到 iOS9 后冻结

如何在 iOS 中的 prepareForSegue 之前执行按钮按下操作?

无法覆盖prepareForSegue函数[重复]

prepareforsegue 函数中的变量为空

覆盖 prepareForSegue 函数时 IBAction 中的线程错误