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

时间:2017-03-29 04:48:40

标签: swift tableview xcode8 ios10 viewcontroller

嘿伙计们,所以我正在开发一个应用程序,我从我的设备导入了一个联系人列表,我可以选择“添加”联系人,但在功能方面它确实没有做太多。我不是最好的编码员,所以试着听我说。我想要做的是获取数据/选定的表视图单元格并将其显示在另一页面上。我“认为”这是我应该做的,因为我试图在另一页上显示数据但在移动我的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]
    }
}
}
抱歉可怕的解释。任何可能的帮助将不胜感激,我已经挣扎了很长一段时间。

1 个答案:

答案 0 :(得分:0)

首先,您需要使用您尝试将数据传递到的其他视图控制器。它既可以在Interface Builder上,也可以通过编程方式完成(我现在假设它在IB上)。然后,您需要在主VC和详细信息VC之间设置segue并为其提供标识符,例如showDetail

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

因此,在从CNContact函数中的主VC转换之前,您需要在Details VC中设置prepareForSegue。要启动segue,您所要做的就是调用performSegue函数。

希望至少能给你一些指导