【问题标题】:Move to new view after contact is select from CNContactPickerViewController从 CNContactPickerViewController 中选择联系人后移动到新视图
【发布时间】:2016-06-17 08:44:51
【问题描述】:

我正在编写一个概念聊天应用程序。我现在可以开始新的聊天了。

我想要的是,当用户使用 CNContactPickerViewController 选择联系人时,选择器会被关闭(这是有效的),并且联系人详细信息会发送到新的聊天视图(这无效)。我得到的错误是func contactPickerdelegate 返回nil。我一直在关注this 教程,将联系人数据从 ChatsViewController 获取到 ChatViewController。相关代码:

import UIKit
import Contacts
import ContactsUI

class ChatsViewController: UITableViewController, CNContactPickerDelegate {
    var chats:[Chat] = chatData
    var selectedContact: CNContact = CNContact()
    @IBAction func createNewChat(sender: AnyObject) {
        let contactPickerViewController = CNContactPickerViewController()
        contactPickerViewController.delegate = self
        presentViewController(contactPickerViewController, animated: true, completion: nil)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false
        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    // MARK: - Table view data source
    
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }
    
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return chats.count
    }
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("ChatCell", forIndexPath: indexPath) as! ChatCell
        
        let chat = chats[indexPath.row] as Chat
        cell.chat = chat
        return cell
    }
    
    func contactPicker(picker: CNContactPickerViewController, didSelectContact contact: CNContact) {
        self.selectedContact = contact
        self.performSegueWithIdentifier("idContactSelected", sender: self)
    }
    
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "idContactSelected" {
            let chatVC = segue.destinationViewController as! ChatViewController
            chatVC.contact = self.selectedContact
        }
    }
}

这是新的聊天视图控制器。

import UIKit
import Contacts
import ContactsUI

class ChatViewController: UIViewController {
    
    @IBOutlet weak var testLabel: UILabel!
    var contact: CNContact = CNContact()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        self.testLabel.text = contact.givenName
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

回顾一下:我有一个 ViewController,我可以在那里按下一个按钮来开始一个新的聊天,这会打开联系人选择器。一旦选择了一个联系人,func contactPicker 就会被执行,但不会发送联系人数据,也不会显示新的聊天 ViewController 并且delegatenil。为什么会这样?我认为这是因为 delegate 从未设置,只是创建,但在本教程中,这就是他们所做的一切,而且似乎有效。

提前感谢您对此的任何想法。

编辑: 最终解决方案:我不需要委托,我可以通过prepareForSegueWithIdentifier 推送数据。此外,segue 未正确连接,重新连接 segue 修复了转换无法正常工作的问题。

【问题讨论】:

  • 显示您的故事板屏幕。
  • 感谢 Nirav 的快速回复,这里:imgur.com/ZiOzndu
  • 来自故事板ChatViewController 是您的第一个屏幕。对吗?
  • ChatsViewController 是第一个屏幕。最右边的屏幕是ChatViewController。完整概述故事板:imgur.com/wKbcZDg
  • 那你为什么在ChatViewController进行segue。

标签: ios swift contacts


【解决方案1】:

尝试这样的事情。像这样改变你的代码

ChatsViewController

import UIKit
import Contacts
import ContactsUI

class ChatsViewController: UITableViewController, CNContactPickerDelegate {
    var chats:[Chat] = chatData
    var selectedContact: CNContact = CNContact()
    @IBAction func createNewChat(sender: AnyObject) {
        let contactPickerViewController = CNContactPickerViewController()
        contactPickerViewController.delegate = self
        presentViewController(contactPickerViewController, animated: true, completion: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false
        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
    }

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

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return chats.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("ChatCell", forIndexPath: indexPath) as! ChatCell

        let chat = chats[indexPath.row] as Chat
        cell.chat = chat
        return cell
    }

    func contactPicker(picker: CNContactPickerViewController, didSelectContact contact: CNContact) {
         self.selectedContact = contact
         self.performSegueWithIdentifier("idContactSelected", sender: self)
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
         if segue.identifier == "idContactSelected" {
             let chatVC = segue.destinationViewController as! ChatViewController
             chatVC.contact = self.selectedContact
         }
    }
}

之后更改您的ChatViewController

import UIKit
import Contacts
import ContactsUI
class ChatViewController: UIViewController {

     @IBOutlet weak var testLabel: UILabel!
     var contact: CNContact = CNContact()

     override func viewDidLoad() {
         super.viewDidLoad()
         // Do any additional setup after loading the view.
         self.testLabel.text = contact.givenName
     }

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

希望这会对你有所帮助。

【讨论】:

  • 非常感谢!它不再崩溃(因为代表不在场),但是它没有呈现ChatViewController。我没有收到任何错误.. 编辑:我读到需要从主 UI 线程调用 performSegueWithIdentifier,所以我将它封装在 dispatch_async(dispatch_get_main_queue()) 中。这不起作用,因为视图不在窗口层次结构中。
  • 使用我的回答,您还将在ChatViewController 中获得选定的联系人。
  • 我明白了,谢谢。但是新的 viewcontroller 并没有展示自己(空的,新的聊天 view controller 说“成功!”永远不会显示)
  • 这就是为什么我说试试我的代码它会推送你的ChatViewController 并带有你想要的所选联系人的名字。
  • 我知道。我做到了。我确实将您的代码复制到了我的项目中,但它没有显示 ChatViewController
猜你喜欢
  • 2016-01-15
  • 1970-01-01
  • 2017-05-10
  • 2012-09-06
  • 2016-09-24
  • 1970-01-01
  • 2020-02-23
  • 2023-03-10
  • 1970-01-01
相关资源
最近更新 更多