我正在使用Swift开发的Contacts应用程序。我最近实现了各节,现在详细信息控制器无法正常工作。每当我单击某个联系人时,它就会显示其他一些联系人的详细信息。我认为主要问题是在prepareforsegue函数中,但我无法弄清楚。帮助请!



//
//  ContactListViewController.swift
//  TechOriginators
//
//  Created by Xcode User on 2017-10-09.
//  Copyright © 2017 Xcode User. All rights reserved.
//

import UIKit
import Foundation
class ContactListViewController : UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchResultsUpdating {


    @IBOutlet var contactsTableView : UITableView!

    var contactViewController: ContactViewController? = nil
    var  contacts : [Contact] = [] {
        didSet{
            self.contactsTableView.reloadData()
        }
    }

    //Variables to implement sections in UITableView
    var sectionLetters: [Character] = []
    var contactsDict = [Character: [String]]()
    var contactsName = [String]()

    //Search Controller
    let searchController = UISearchController(searchResultsController: nil)

    //Variable to store filtered contacts through search
    var filteredContacts = [Contact]()

    //Function to show details of a contact record
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showDetail"{
            if let indexPath = contactsTableView.indexPathForSelectedRow{
                let object = contacts[indexPath.row]

                //let object = contactsDict[sectionLetters[indexPath.section]]![indexPath.row]
                let controller = segue.destination as! ContactViewController
                controller.detailItem = object
            }
        }
    }

    func createDict(){
        contactsName = contacts.map{$0.FirstName}
        //print(contactsName)
        sectionLetters = contactsName.map{ (firstName) -> Character in
            return firstName[firstName.startIndex]
        }

        sectionLetters.sorted()

        sectionLetters = sectionLetters.reduce([], { (list, firstName) -> [Character] in
            if !list.contains(firstName){
                return list + [firstName]
            }
            return list
        })

        for entry in contactsName{
            if contactsDict[entry[entry.startIndex]] == nil {
                contactsDict[entry[entry.startIndex]] = [String]()
            }
            contactsDict[entry[entry.startIndex]]!.append(entry)
        }

        for (letter, list) in contactsDict{
            contactsDict[letter] = list.sorted()
        }
        print(sectionLetters)
        print(contactsDict)
    }

//    //Function to load contacts
    func loadContacts()
    {
       self.contacts = getContacts()
    }

    /*private let session: URLSession = .shared
    func loadContacts()
    {
        //let url = URL(string: "http://127.0.0.1:8080/api/Contacts")!
        let url = URL(string: "http://10.16.48.237/api/Contacts")!
        let task = session.dataTask(with: url) { (data, response, error) in
            print("dataRecieved \(data)")
            print("error \(error)")
            print ("response \(response)")
            guard let data = data else { return }
            do {
                self.contacts = try parse(data)
            }
            catch {
                print("JSONParsing Error: \(error)")
            }
        }
        task.resume()  // firing the task
    }*/


    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 44
    }

    func numberOfSections(in tableView: UITableView) -> Int {

        return sectionLetters.count
    }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        if self.searchController.isActive {
            return nil
        } else {
            return String(sectionLetters[section])
        }
        //return String(sectionLetters[section])
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if searchController.isActive && searchController.searchBar.text != "" {
            return filteredContacts.count
        }
        //return self.contacts.count
        print(contactsDict[sectionLetters[section]]!.count)
        return contactsDict[sectionLetters[section]]!.count
    }

    //Function to display cells in UITableView
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell =  tableView.dequeueReusableCell(withIdentifier: "Cell" , for : indexPath)
        let contact = contacts[indexPath.row]
        let object: Contact

        if searchController.isActive && searchController.searchBar.text != ""{
            let contact = self.filteredContacts[indexPath.row]
            cell.textLabel?.text = contact.FirstName + " " + contact.LastName
        }else{
           //contact = contactsDict[sectionLetters[indexPath.section]]![indexPath.row]
            //cell.textLabel?.text = contact.FirstName + " " + contact.LastName
            cell.textLabel?.text = contactsDict[sectionLetters[indexPath.section]]![indexPath.row]
        }
        return cell
    }

    //Function to update search results when the user types in search bar
    func updateSearchResults(for searchController: UISearchController) {
        filterContentForSearchText(searchText: searchController.searchBar.text!)
    }

    func updateSearchResultsForSearchController(searchController: UISearchController){
        filterContentForSearchText(searchText: searchController.searchBar.text!)
    }

    //Function to find matches for text entered in search bar
    func filterContentForSearchText(searchText: String){
        filteredContacts = contacts.filter{p in
            var containsString = false

            if p.FirstName.lowercased().contains(searchText.lowercased()){
                containsString = true
            }else if p.LastName.lowercased().contains(searchText.lowercased()){
                containsString = true
            }else if p.Division.lowercased().contains(searchText.lowercased()){
                containsString = true
            }else if p.Department.lowercased().contains(searchText.lowercased()){
                containsString = true
            }else if p.BusinessNumber.lowercased().contains(searchText.lowercased()){
                containsString = true
            }else if p.HomePhone.lowercased().contains(searchText.lowercased()){
                containsString = true
            }else if p.CellularPhone.lowercased().contains(searchText.lowercased()){
                containsString = true
            }else if p.Role.lowercased().contains(searchText.lowercased()){
                containsString = true
            }
            return containsString
            }

          contactsTableView.reloadData()
        }

    //Function to sorts contacts by First Name
    func sortContacts() {
        contacts.sort() { $0.FirstName < $1.FirstName }
        contactsTableView.reloadData();
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        loadContacts()
        sortContacts()
        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        self.definesPresentationContext = true
        createDict()
        contactsTableView.tableHeaderView = searchController.searchBar
        //contactsTableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: false)
        // Do any additional setup after loading the view.

    }


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

}



    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */



//
//  ContactViewController.swift
//  TechOriginators
//
//  Created by Xcode User on 2017-10-09.
//  Copyright © 2017 Xcode User. All rights reserved.
//

import UIKit

class ContactViewController: UIViewController {

    //@IBOutlet weak var detailDescriptionLabel: UILabel!
    @IBOutlet weak var firstNameLabel: UILabel?
    @IBOutlet weak var lastNameLabel: UILabel?
    @IBOutlet weak var divisionLabel: UILabel?
    @IBOutlet weak var departmentLabel: UILabel?
    @IBOutlet weak var businessPhoneButton: UIButton?
    @IBOutlet weak var homePhoneButton: UIButton?
    @IBOutlet weak var cellularPhoneButton: UIButton?
    @IBOutlet weak var roleLabel: UILabel?

    /*@IBOutlet weak var firstNameLabel: UILabel?
     @IBOutlet weak var lastNameLabel: UILabel?
     @IBOutlet weak var phoneButton: UIButton?
     @IBOutlet weak var emailButton: UIButton?*/

    func configureView() {
        // Update the user interface for the detail item.
        if let detail = self.detailItem {
            self.title = detail.FirstName + " " + detail.LastName
            firstNameLabel?.text = detail.FirstName
            lastNameLabel?.text = detail.LastName
            divisionLabel?.text = detail.Division
            departmentLabel?.text = detail.Department
            businessPhoneButton?.setTitle(detail.BusinessNumber, for: .normal)
            homePhoneButton?.setTitle(detail.HomePhone, for: .normal)
            cellularPhoneButton?.setTitle(detail.CellularPhone, for: .normal)
            roleLabel?.text = detail.Role
        }

    }

    @IBAction func businessPhoneButtonPressed(sender: UIButton){
        if let bPhone = detailItem?.BusinessNumber{
            if let url = URL(string: "tel://\(bPhone)"), UIApplication.shared.canOpenURL(url){
                if #available(iOS 10, *){
                    UIApplication.shared.open(url)
                }else{
                    UIApplication.shared.openURL(url)
                }
            }
        }
    }

    @IBAction func homePhoneButtonPressed(sender: UIButton){
        if let hPhone = detailItem?.HomePhone{
            if let url = URL(string: "tel://\(hPhone)"), UIApplication.shared.canOpenURL(url){
                if #available(iOS 10, *){
                    UIApplication.shared.open(url)
                }else{
                    UIApplication.shared.openURL(url)
                }
            }
        }
    }

    @IBAction func cellularPhoneButtonPressed(sender: UIButton){
        if let cPhone = detailItem?.CellularPhone{
            /*if let url = NSURL(string: "tel://\(phone)"){
             UIApplication.shared.open(url as URL, options: [:], completionHandler: nil)
             }*/
            if let url = URL(string: "tel://\(cPhone)"), UIApplication.shared.canOpenURL(url) {
                if #available(iOS 10, *) {
                    UIApplication.shared.open(url)
                } else {
                    UIApplication.shared.openURL(url)
                }
            }
        }
    }



    /*@IBAction func emailButtonPressed(sender: UIButton){
     if let email = detailItem?.email{
     if let url = URL(string:"mailto:\(email)"){
     UIApplication.shared.open(url as URL)
     }
     }
     }*/

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a      nib.
        configureView()

    }

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

    var detailItem: Contact? {
        didSet {
            // Update the view.
            self.configureView()
        }
    }



    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}

最佳答案

我建议对所有表操作使用相同的数据结构,以使其一致。尝试将字典填充为:

var contactsDict = [Character: [Contact]]()


这样,您始终可以使用section查找正确的数组,并使用row查找数组中的正确偏移量。

将表数据中的联系人姓名与联系人分开,会导致他们不同步。

关于ios - iOS主细节秒,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47676555/

10-09 01:41