我正在使用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/