ios - 推送 NContactViewController 会导致黑色导航栏。为什么?

标签 ios swift uitableview navigationbar cncontactviewcontroller

我一直在尝试解决这个问题,所以这是我的问题:

我想创建一个具有给定值集的未知联系人,您可能会说:

fileprivate func showUnknownContactViewController() {
    let aContact = CNMutableContact()
    let newEmail = CNLabeledValue(label: CNLabelWork, value: email! as NSString)
    aContact.emailAddresses.append(newEmail)

    let workPhone = CNLabeledValue(label: CNLabelWork, value: CNPhoneNumber(stringValue : phone!))
    aContact.phoneNumbers.append(workPhone)


    let ucvc = CNContactViewController(forUnknownContact: aContact)
    ucvc.delegate = self
    ucvc.allowsEditing = true
    ucvc.allowsActions = true
    ucvc.alternateName = firstName! + " " + lastName!
    ucvc.title = "Company"
    ucvc.message = UserDefaults.standard.string(forKey: "company")!
    ucvc.contactStore = self.store //needed for editing/adding contacts?

    self.navigationController?.pushViewController(ucvc, animated: true)
}

我还调用了委托(delegate)函数,我不确定它有什么作用:

func contactViewController(_ viewController: CNContactViewController, shouldPerformDefaultActionFor property: CNContactProperty) -> Bool {

    return true
}

当按下 ucvc 时,我的导航栏变成黑色,而我遵循的本教程却没有。注意:我没有使用 tableview,我只是使用了 showUnknownContactViewController 函数。

import UIKit
import Contacts
import ContactsUI
enum ActionType: Int {
    case pickContact = 0
    case createNewContact
    case displayContact
    case editUnknownContact
}
// Height for the Edit Unknown Contact row
let kUIEditUnknownContactRowHeight: CGFloat = 81.0

class ViewController: UITableViewController, CNContactPickerDelegate, CNContactViewControllerDelegate {
    fileprivate var store: CNContactStore!
    fileprivate var menuArray: NSMutableArray?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        store = CNContactStore()
        checkContactsAccess()
    }

    fileprivate func checkContactsAccess() {
        switch CNContactStore.authorizationStatus(for: .contacts) {
            // Update our UI if the user has granted access to their Contacts
        case .authorized:
            self.accessGrantedForContacts()

            // Prompt the user for access to Contacts if there is no definitive answer
        case .notDetermined :
            self.requestContactsAccess()

            // Display a message if the user has denied or restricted access to Contacts
        case .denied,
        .restricted:
            let alert = UIAlertController(title: "Privacy Warning!",
                message: "Permission was not granted for Contacts.",
                preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }
    }

    fileprivate func requestContactsAccess() {

        store.requestAccess(for: .contacts) {granted, error in
            if granted {
                DispatchQueue.main.async {
                    self.accessGrantedForContacts()
                    return
                }
            }
        }
    }

    // This method is called when the user has granted access to their address book data.
    fileprivate func accessGrantedForContacts() {
        // Load data from the plist file
        let plistPath = Bundle.main.path(forResource: "Menu", ofType:"plist")
        self.menuArray = NSMutableArray(contentsOfFile: plistPath!)
        self.tableView.reloadData()
    }


    //MARK: Table view methods

    override func numberOfSections(in tableView: UITableView) -> Int {
        return self.menuArray?.count ?? 0
    }

    // Customize the number of rows in the table view.
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    // Customize the appearance of table view cells.
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let DefaultCellIdentifier = "DefaultCell"
        let SubtitleCellIdentifier = "SubtitleCell"
        var aCell: UITableViewCell?
        // Make the Display Picker and Create New Contact rows look like buttons
        if indexPath.section < 2 {
            aCell = tableView.dequeueReusableCell(withIdentifier: DefaultCellIdentifier)
            if aCell == nil {
                aCell = UITableViewCell(style: .default, reuseIdentifier: DefaultCellIdentifier)
            }
            aCell!.textLabel?.textAlignment = .center
        } else {
            aCell = tableView.dequeueReusableCell(withIdentifier: SubtitleCellIdentifier)
            if aCell == nil {
                aCell = UITableViewCell(style: .subtitle, reuseIdentifier: SubtitleCellIdentifier)
                aCell!.accessoryType = .disclosureIndicator
                aCell!.detailTextLabel?.numberOfLines = 0
            }
            // Display descriptions for the Edit Unknown Contact and Display and Edit Contact rows
            aCell!.detailTextLabel?.text = (self.menuArray![indexPath.section] as AnyObject).value(forKey: "description") as! String?
        }

        aCell!.textLabel?.text = (self.menuArray![indexPath.section] as AnyObject).value(forKey: "title") as! String?
        return aCell!
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if let actionType = ActionType(rawValue: indexPath.section) {
            switch actionType {
            case .pickContact:
                self.showContactPickerController()
            case .createNewContact:
                showNewContactViewController()
            case .displayContact:
                showContactViewController()
            case .editUnknownContact:
                showUnknownContactViewController()
            }
        } else {
            self.showContactPickerController()
        }
    }

    //MARK: TableViewDelegate method
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        // Change the height if Edit Unknown Contact is the row selected
        return (indexPath.section == ActionType.editUnknownContact.rawValue) ? kUIEditUnknownContactRowHeight : tableView.rowHeight
    }

    //MARK: Show all contacts
    // Called when users tap "Display Picker" in the application. Displays a list of contacts and allows users to select a contact from that list.
    // The application only shows the phone, email, and birthdate information of the selected contact.
    fileprivate func showContactPickerController() {
        let picker = CNContactPickerViewController()
        picker.delegate = self

        // Display only a person's phone, email, and birthdate
        let displayedItems = [CNContactPhoneNumbersKey, CNContactEmailAddressesKey, CNContactBirthdayKey]
        picker.displayedPropertyKeys = displayedItems

        // Show the picker
        self.present(picker, animated: true, completion: nil)
    }


    //MARK: Display and edit a person
    // Called when users tap "Display and Edit Contact" in the application. Searches for a contact named "Appleseed" in
    // in the address book. Displays and allows editing of all information associated with that contact if
    // the search is successful. Shows an alert, otherwise.
    fileprivate func showContactViewController() {
        // Search for the person named "Appleseed" in the Contacts
        let name = "Appleseed"
        let predicate: NSPredicate = CNContact.predicateForContacts(matchingName: name)
        let descriptor = CNContactViewController.descriptorForRequiredKeys()
        let contacts: [CNContact]
        do {
            contacts = try store.unifiedContacts(matching: predicate, keysToFetch: [descriptor])
        } catch {
            contacts = []
        }
        // Display "Appleseed" information if found in the address book
        if !contacts.isEmpty {
            let contact = contacts[0]
            let cvc = CNContactViewController(for: contact)
            cvc.delegate = self
            // Allow users to edit the person’s information
            cvc.allowsEditing = true
            //cvc.contactStore = self.store //seems to work without setting this.
            self.navigationController?.pushViewController(cvc, animated: true)
        } else {
            // Show an alert if "Appleseed" is not in Contacts
            let alert = UIAlertController(title: "Error",
                message: "Could not find \(name) in the Contacts application.",
                preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }
    }

    //MARK: Create a new person
    // Called when users tap "Create New Contact" in the application. Allows users to create a new contact.
    fileprivate func showNewContactViewController() {
        let npvc = CNContactViewController(forNewContact: nil)
        npvc.delegate = self
        //npvc.contactStore = self.store //seems to work without setting this.

        let navigation = UINavigationController(rootViewController: npvc)
        self.present(navigation, animated: true, completion: nil)
    }

    //MARK: Add data to an existing person
    // Called when users tap "Edit Unknown Contact" in the application.
    fileprivate func showUnknownContactViewController() {
        let aContact = CNMutableContact()
        let newEmail = CNLabeledValue(label: CNLabelOther, value: "John-Appleseed@mac.com" as NSString)
        aContact.emailAddresses.append(newEmail)

        let ucvc = CNContactViewController(forUnknownContact: aContact)
        ucvc.delegate = self
        ucvc.allowsEditing = true
        ucvc.allowsActions = true
        ucvc.alternateName = "John Appleseed"
        ucvc.title = "John Appleseed"
        ucvc.message = "Company, Inc"
        ucvc.contactStore = self.store //needed for editing/adding contacts?

        self.navigationController?.pushViewController(ucvc, animated: true)
    }

    //MARK: CNContactPickerDelegate methods
    // The selected person and property from the people picker.
    func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) {
        let contact = contactProperty.contact
        let contactName = CNContactFormatter.string(from: contact, style: .fullName) ?? ""
        let propertyName = CNContact.localizedString(forKey: contactProperty.key)
        let message = "Picked \(propertyName) for \(contactName)"

        DispatchQueue.main.async {
            let alert = UIAlertController(title: "Picker Result",
                message: message,
                preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }
    }

    // Implement this if you want to do additional work when the picker is cancelled by the user.
    func contactPickerDidCancel(_ picker: CNContactPickerViewController) {
        picker.dismiss(animated: true, completion: {})
    }


    //MARK: CNContactViewControllerDelegate methods
    // Dismisses the new-person view controller.
    func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
        //
        self.dismiss(animated: true, completion: nil)
    }

    func contactViewController(_ viewController: CNContactViewController, shouldPerformDefaultActionFor property: CNContactProperty) -> Bool {
        return true
    }


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


}

我试过像这样更改 ucvc 的导航 Controller :

ucvc.navigationController?.navigationBar.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 1)

我还尝试将背景图像设置为空图像:

ucvc.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)

当我加载 ucvc 时,我看到一些有趣的东西,我从控制台日志中得到它:

Access to PassKit Shared Cache file denied. Please verify sandbox exceptions and/or file a Radar.

但结果还是黑色。我做错了什么以及如何防止黑色导航栏?它看起来像这样:

Navigation bar

如果我要发布太多代码,请告诉我,我认为太多总比太少好:)

最佳答案

您是否尝试查看教程中的 Storyboard与您的 Storyboard相比如何?

关于ios - 推送 NContactViewController 会导致黑色导航栏。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51119700/

相关文章:

ios - 如何创建多 ImageView 设计?

ios - 在 iOS 上存储对象 - 最佳解决方案?

ios - 保留或批处理 Realm 通知?

ios - 如何在 Storyboard 创建的标签栏 Controller 上编写代码?

ios - 如何使用 Xcode 服务器导出临时存档

swift - 抓取加载的网页 URL? WKWebView macOS

swift - Realm 没有在我的 UILabel 中显示值

ios - 使用 Core Data 创建一个新的 iOS 项目,但我在 AppDelegate 中找不到 ManagedObjectModel 变量

ios - 如何以编程方式在自定义表格 View 中附加搜索栏

ios - 在 iOS 中实现 Google 自定义搜索 API