2017-12-06 12 views
0

私はswiftを使用して開発している連絡先アプリで作業しています。私は最近セクションを実装しましたが、今度はディテール・コントローラーが正しく機能していません。連絡先をクリックするたびに、他の連絡先の詳細が表示されます。私は主な問題はprepareforsegue機能にあると思うが、私はそれを理解することはできない。ヘルプPls!iOSマスター詳細秒

// 
// 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. 
    } 
    */ 

} 

答えて

0

私は一貫して、すべてのテーブル操作のために同じデータ構造を使用することをお勧め。あなたの辞書を取り込む試してみてください。

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

そのように、あなたは常に、アレイ内のオフセット権利を見つけるために、右アレイとrowを見つけるためにsectionを使用することができます。

テーブルのデータ内の連絡先から名前を分離すると、同期が外れるように招待されています。

+0

ご返信ありがとうございます。私はあなたの提案を実装しましたが、今はテーブルビューのセルに辞書を割り当てる間にエラーが発生しています。 cell.textLabel?.text = groupedNames [groupedLetters [indexPath.section]!![indexPath.row] String型にContact型の値を代入することはできません。あなたの助けが大いにありがとう! –

+0

したがって、既存のコードを使用して 'Contact'オブジェクトを取得し、ラベルに割り当てる文字列としてその名前を抽出します。 –

関連する問題