如何将选定的单元格发送到另一个视图控制器?

Posted

技术标签:

【中文标题】如何将选定的单元格发送到另一个视图控制器?【英文标题】:How to send selected cell to another view controller? 【发布时间】:2017-03-29 04:48:40 【问题描述】:

大家好,我正在开发一个应用程序,在该应用程序中我从我的设备中导入了一个联系人列表,我可以选择“添加”联系人,但它在功能方面并没有太大作用。我不是最好的编码员,所以试着听我说。我要做的是获取数据/选定的表格视图单元格并将其显示在另一个页面上。我“认为”这是我应该做的,因为我试图在另一个页面上显示数据,但是当我移动我的 OVERRIDE 函数时出现错误。这让我相信我需要获取我认为是 newContact 的数据?并将其设置为变量,然后将其显示在新页面上,我可以在其中创建新的视图控制器并添加代码而不会出错。

我基本上需要弄清楚我的 JSON 数据保存为什么,然后如果可能的话将其设置为一个字符串,这样我就可以将它发送到我的新视图控制器,或者使用我已经编写的代码将它发送到我的数据库已创建。

我只是不确定在哪里输入语句,因为我遇到了错误以及确切的代码是什么。

抱歉,我对我正在尝试执行的操作进行了糟糕的描述,我知道需要做什么,但我是初学者。

我的主视图控制器从我的手机中获取联系人并访问它们。

import UIKit
import Contacts
import ContactsUI

class MainViewController: UIViewController 

@IBOutlet weak var textField: UITextField!
@IBOutlet weak var tableView: UITableView!

var store = CNContactStore()
var contacts: [CNContact] = []

override func viewDidLoad() 
    super.viewDidLoad()


//MARK: - User Actions

@IBAction func contactListPressed(_ sender: AnyObject) 
    let contactPickerViewController = CNContactPickerViewController()
    contactPickerViewController.delegate = self
    present(contactPickerViewController, animated: true, completion:      nil)


@IBAction func addContactPressed(_ sender: AnyObject) 
    let newContact = CNMutableContact()

    newContact.givenName = "Apps"
    newContact.familyName = "Foundations"
    newContact.nickname = "AF"

    if let image = UIImage(named: "logo-apps-foundation.jpg"),
        let data = UIImagePNGRepresentation(image)
        newContact.imageData = data
    

    let phone = CNLabeledValue(label: CNLabelWork, value:   CNPhoneNumber(stringValue: "+441234567890"))
    newContact.phoneNumbers = [phone]

    let email = "" //Your Input goes here
    let Email = CNLabeledValue(label:CNLabelWork, value: email as NSString)
    newContact.emailAddresses = [Email]


    newContact.jobTitle = "Apps Foundation"
    newContact.organizationName = "Apps Foundation"
    newContact.departmentName = "IT"

    let facebookProfile = CNLabeledValue(label: "Facebook", value:   CNSocialProfile(urlString: "https://www.facebook.com/appsfoundation", username: "AppsFoundation", userIdentifier: "appsfoundation", service: CNSocialProfileServiceFacebook))
    let twitterProfile = CNLabeledValue(label: "Twitter", value: CNSocialProfile(urlString: "https://twitter.com/AppsFoundation", username: "AppsFoundation", userIdentifier: "appsfoundation", service: CNSocialProfileServiceTwitter))
    newContact.socialProfiles = [facebookProfile, twitterProfile]

    let skypeProfile = CNLabeledValue(label: "Skype", value: CNInstantMessageAddress(username: "AppsFoundation", service: CNInstantMessageServiceSkype))
    newContact.instantMessageAddresses = [skypeProfile]

    var birthday = DateComponents()
    birthday.year = 1991
    birthday.month = 1
    birthday.day = 1
    newContact.birthday = birthday

    let request = CNSaveRequest()
    request.add(newContact, toContainerWithIdentifier: nil)
    do 
        try store.execute(request)
        let alert = UIAlertController(title: "Contacts ios 9", message: "New contact has been created", preferredStyle: UIAlertControllerStyle.alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        present(alert, animated: true, completion: nil)
     catch let error
        print(error)
    


@IBAction func textFieldValueChanged(_ sender: AnyObject) 
    if let query = textField.text 
        findContactsWithName(query)
    


//MARK: - Private Methods

func findContactsWithName(_ name: String) 
    AppDelegate.sharedDelegate().checkAccessStatus( (accessGranted) -> Void in
        if accessGranted 
            DispatchQueue.main.async(execute:  () -> Void in
                do 
                    let predicate: NSPredicate = CNContact.predicateForContacts(matchingName: name)
                    let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactBirthdayKey, CNContactViewController.descriptorForRequiredKeys()] as [Any]
                    self.contacts = try self.store.unifiedContacts(matching: predicate, keysToFetch:keysToFetch as! [CNKeyDescriptor])
                    self.tableView.reloadData()
                
                catch 
                    print("Unable to refetch the selected contact.")
                
            )
        
    )


func updateContact(_ contactIdentifier: String) 
    do 
        let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactBirthdayKey, CNContactPhoneNumbersKey, CNContactViewController.descriptorForRequiredKeys()] as [Any]
        let contact = try store.unifiedContact(withIdentifier:  contactIdentifier, keysToFetch:keysToFetch as! [CNKeyDescriptor])

        let contactToUpdate = contact.mutableCopy() as! CNMutableContact
        contactToUpdate.phoneNumbers = [CNLabeledValue(label: CNLabelWork, value: CNPhoneNumber(stringValue: "+440987654321"))]

        let saveRequest = CNSaveRequest()
        saveRequest.update(contactToUpdate)
        try store.execute(saveRequest)
     catch let error
        print(error)
    




 //MARK: - UITableViewDataSource

extension MainViewController: CNContactPickerDelegate 

func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) 
    let selectedContactID = contact.identifier
    updateContact(selectedContactID)




 //MARK: - UITableViewDataSource

    extension MainViewController: UITableViewDataSource 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return contacts.count


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let CellIdentifier = "MyCell"
    let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier)
    cell!.textLabel!.text = contacts[indexPath.row].givenName + " " + contacts[indexPath.row].familyName

    if let birthday = contacts[indexPath.row].birthday 
        let formatter = DateFormatter()
        formatter.dateStyle = DateFormatter.Style.long
        formatter.timeStyle = .none

        cell!.detailTextLabel?.text = formatter.string(from: ((birthday as NSDateComponents).date)!)
    
    return cell!


 

//MARK: - UITableViewDelegate

 extension MainViewController: UITableViewDelegate 

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    let controller = CNContactViewController(for: contacts[indexPath.row])
    controller.contactStore = self.store
    controller.allowsEditing = false
    self.navigationController?.pushViewController(controller, animated: true)



我知道我需要合并这样的东西,但我不确定在哪里或如何将 JSON 数据设置为变量或正确的类型,然后合并这种类型的代码

override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
if segue.identifier == "showDetail" 
    if let indexPath = self.tableView.indexPathForSelectedRow 
        let controller = segue.destination as! ViewControllerB
        controller.selectedName = objects[indexPath.row]
    


对不起,糟糕的解释。任何可能的帮助将不胜感激,我已经挣扎了很长一段时间。

【问题讨论】:

创建模型类,用模型类填充单元格,MVC意味着模型和视图的分离。然后通过selected Model class instance to the next ViewController Passing Data between View Controllers的可能重复 使用 json 创建模型并将这些模型从一个 vc 传递到另一个 vc 【参考方案1】:

首先,您需要有另一个您尝试向其传递数据的视图控制器。它可以在 Interface Builder 上或以编程方式完成(我假设它现在在 IB 上)。然后你需要在 Main VC 和 Details VC 之间设置一个 segue 并给它一个 identifier 例如showDetail.

接下来是确定 Details VC 正常工作所需的数据。您可以为每个数据项设置单独的变量(例如姓名、年龄、电话、电子邮件等),但通常如果有很多信息,最好使用数据模型。在您的情况下,由于您试图显示联系信息,您可以简单地重复使用 CNContact

因此,您只需在详细信息 VC 中设置一个 CNContact,然后在 prepareForSegue 函数中从主 VC 转换之前设置它。要启动 segue,您只需调用 performSegue 函数即可。

希望至少能给你一些方向

【讨论】:

以上是关于如何将选定的单元格发送到另一个视图控制器?的主要内容,如果未能解决你的问题,请参考以下文章

将数组从自定义单元格发送到另一个视图控制器

将 collectionView 数据发送到另一个视图控制器中的网点

如何将 UIPickerView 选定的行发送到另一个 ViewController

将信息发送到另一个视图控制器

如何将标签中的数据从表视图行操作发送到视图控制器?

单击表格单元格时将变量值发送到下一个视图控制器