TableView行与Swift中的数据不一致

时间:2015-04-30 11:39:19

标签: ios uitableview swift

我正在使用联系人列表中的数据加载UITableViewController。使用一小组数据在模拟器中一切正常,但在我的iPhone上有82个联系人,我从0到大多数数据加载了不同数量的行,但从来没有所有数据,总是不同的数量。这几乎就像在数据数组完成之前加载和显示表一样。如果我手动将numberOfRowsInSection返回设置为82,则可以正常工作,但设置为contactdatalist.count时,它会得到较少的数字。有什么我做错了,或者我可以减慢tableview负载,直到所有数据加载完成?它在操作中似乎是异步的。

import UIKit
import AddressBook

class TableViewControllerContacts: UITableViewController {
    
    var contactdatalist = [ContactData]()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
            
        self.contactdatalist = []

        let addressBook : ABAddressBookRef? = ABAddressBookCreateWithOptions(nil, nil).takeRetainedValue()
        ABAddressBookRequestAccessWithCompletion(addressBook, { (granted : Bool, error: CFError!) -> Void in
            if granted == true {
                let allContacts : NSArray = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue()
                for contactRef:ABRecordRef in allContacts { // first name
                    let myPBfirstname = ABRecordCopyValue(contactRef, kABPersonFirstNameProperty)?.takeRetainedValue() as! NSString? ?? ""
                    let myPBlastname = ABRecordCopyValue(contactRef, kABPersonLastNameProperty)?.takeRetainedValue() as! NSString? ?? ""
                    let phonesRef: ABMultiValueRef = ABRecordCopyValue(contactRef, kABPersonPhoneProperty)?.takeRetainedValue() as ABMultiValueRef? ?? ""
                    var phonesArray  = Array<Dictionary<String,String>>()
                    for var i:Int = 0; i < ABMultiValueGetCount(phonesRef); i++ {
                        let myPhLabel = ABMultiValueCopyLabelAtIndex(phonesRef, i)?.takeRetainedValue() as NSString? ?? ""
                        let myPhValue = ABMultiValueCopyValueAtIndex(phonesRef, i)?.takeRetainedValue() as! NSString? ?? ""
                        if myPhLabel.containsString("Mobile") {
                            self.contactdatalist.append(ContactData(firstname:myPBfirstname as String, lastname:myPBlastname as String, phone:myPhValue as String))
                        }
                    }
                }
            }
        })
        self.tableView.reloadData()
    }

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

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Potentially incomplete method implementation.
        // Return the number of sections.
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete method implementation.
        // Return the number of rows in the section.
        return self.contactdatalist.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
        // Configure the cell...
        let contactdata = self.contactdatalist[indexPath.row]
        cell.textLabel!.text = ("\(contactdata.firstname) \(contactdata.lastname)")
        return cell
    }

2 个答案:

答案 0 :(得分:2)

更新viewDidLoad,以便在单独的线程中获取联系人,并在获取联系人时加载tableview。

override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()

        self.contactdatalist = []

dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.value), 0)) { 
    let addressBook : ABAddressBookRef? = ABAddressBookCreateWithOptions(nil, nil).takeRetainedValue()
        ABAddressBookRequestAccessWithCompletion(addressBook, { (granted : Bool, error: CFError!) -> Void in
            if granted == true {
                let allContacts : NSArray = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue()
                for contactRef:ABRecordRef in allContacts { // first name
                    let myPBfirstname = ABRecordCopyValue(contactRef, kABPersonFirstNameProperty)?.takeRetainedValue() as! NSString? ?? ""
                    let myPBlastname = ABRecordCopyValue(contactRef, kABPersonLastNameProperty)?.takeRetainedValue() as! NSString? ?? ""
                    let phonesRef: ABMultiValueRef = ABRecordCopyValue(contactRef, kABPersonPhoneProperty)?.takeRetainedValue() as ABMultiValueRef? ?? ""
                    var phonesArray  = Array<Dictionary<String,String>>()
                    for var i:Int = 0; i < ABMultiValueGetCount(phonesRef); i++ {
                        let myPhLabel = ABMultiValueCopyLabelAtIndex(phonesRef, i)?.takeRetainedValue() as NSString? ?? ""
                        let myPhValue = ABMultiValueCopyValueAtIndex(phonesRef, i)?.takeRetainedValue() as! NSString? ?? ""
                        if myPhLabel.containsString("Mobile") {
                            self.contactdatalist.append(ContactData(firstname:myPBfirstname as String, lastname:myPBlastname as String, phone:myPhValue as String))
                        }
                    }
                }
            }
        })

    dispatch_async(dispatch_get_main_queue()) { 
      self.tableView.reloadData() 
    }
  }
}

答案 1 :(得分:0)

请求地址簿是一种异步操作。因此,您应该在最后一步中在该块内的表视图中重新加载数据,而不是在viewDidLoad的末尾。