滚动后,UITableview单元格不会显示

时间:2021-01-18 21:12:40

Quick context, I have a view controller that has the option to add friends by clicking a UIButton. I want to customize this controller rather than using peoplepicker so I created my own tableview I populate with info from the address book. First, I ask the user if its ok to access their address book. I then put their contacts names into an array to populate the tableview. The weirdest thing though is the names don't show up in the table cells until you first scroll on the tableview. When I stop and relaunch or just unwind and come back, the cells are populated like you'd expect. When I reset the content and restart, the same thing happens where the names don't show up in the cells until you scroll. Any thoughts on what could be happening? Thanks in advance!

快速上下文,我有一个视图控制器,可以选择通过单击UIButton添加朋友。我想自定义这个控制器,而不是使用peoplepicker所以我创建了自己的tableview,我填写了地址簿中的信息。首先,我问用户是否可以访问他们的地址簿。然后我将他们的联系人姓名放入一个数组中以填充tableview。最奇怪的是,在您第一次滚动tableview之前,名称不会显示在表格单元格中。当我停下来重新启动或者只是放松并回来时,细胞就像你期望的那样被填充。当我重置内容并重新启动时,同样的事情发生在滚动之前名称不会显示在单元格中。对可能发生的事情的任何想法?提前致谢!

import UIKit
import AddressBook

class ContactsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var namesTableView: UITableView!

    var addressBook: ABAddressBook!
    var names:[String]?

    func createAddressBook() {

        var error: Unmanaged<CFErrorRef>?

        addressBook = ABAddressBookCreateWithOptions(nil, &error).takeRetainedValue()

    }

    override func viewDidLoad() {
        super.viewDidLoad()

        self.namesTableView.delegate = self
        self.namesTableView.dataSource = self

        accessAddressBook()

        self.namesTableView.backgroundColor = UIColor(red: 74/255, green: 144/255, blue: 226/255, alpha: 1)
        self.namesTableView.allowsMultipleSelection = true

    }

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

    func accessAddressBook () {

        switch ABAddressBookGetAuthorizationStatus(){
        case .Authorized:
            println("Already authorized")
            createAddressBook()
            self.beginContactSearch()

        case .Denied:
            println("You are denied access to the address book")

        case .NotDetermined:
            createAddressBook()
            if let theBook: ABAddressBook = addressBook {

                ABAddressBookRequestAccessWithCompletion(theBook, {(granted: Bool, error: CFError!) in

                    if granted {

                        println("Access is granted")
                        self.beginContactSearch()
                    }
                    else {

                        println("Access is not granted")
                    }
                })
            }
        case .Restricted:
            println("Access is restricted")

        default:
            println("Unhandled")
        }

    }

    func beginContactSearch(){
        let records = ABAddressBookCopyArrayOfAllPeople(self.addressBook).takeRetainedValue() as NSArray as [ABRecord]
        names = Array()
        for record in records {
            let object = ABRecordCopyCompositeName(record)
            if object.toOpaque() == COpaquePointer.null() {

            } else {
                var name = object.takeRetainedValue() as NSString
                self.names!.append(name)
            }
            self.namesTableView.reloadData()
        }
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.names?.count ?? 0
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = namesTableView.dequeueReusableCellWithIdentifier("Tablecell") as UITableViewCell

        cell.textLabel!.text = names![indexPath.row]
        cell.textLabel?.textColor = UIColor.whiteColor()
        cell.backgroundColor = UIColor(red: 74/255, green: 144/255, blue: 226/255, alpha: 1)

        return cell
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        var selectedCell:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
        selectedCell.contentView.backgroundColor = UIColor.whiteColor()
        selectedCell.textLabel?.textColor = UIColor(red: 74/255, green: 144/255, blue: 226/255, alpha: 1)

        println("User selected: \(self.names?[indexPath.row])")

    }

    func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
        var cellToDeSelect:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!

        cellToDeSelect.textLabel?.textColor = UIColor.whiteColor()

    }

}

2 个解决方案

#1


6  

Run your .reloadData on the main thread:

在主线程上运行.reloadData:

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

and it should work.

它应该工作。

#2


0  

First remove this statement self.namesTableView.reloadData() from loop it should be call once you get tableview array

首先从循环中删除此语句self.namesTableView.reloadData(),一旦获得tableview数组,它应该被调用

Use Dispatch async to avoid operation in main thread

使用Dispatch async可以避免在主线程中进行操作

Swift

DispatchQueue.main.async {
    // RELOAD TABLE DATA
}

Objective-C

dispatch_async(dispatch_get_main_queue(), ^{
     // RELOAD TABLE DATA
});

If data takes time then use call backs i.e. completion handlers and in the handler use dispatch async to reload table data as mention above

如果数据需要时间,则使用回调即完成处理程序,并在处理程序中使用dispatch async重新加载表数据,如上所述

#1


6  

Run your .reloadData on the main thread:

在主线程上运行.reloadData:

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

and it should work.

它应该工作。

#2


0  

First remove this statement self.namesTableView.reloadData() from loop it should be call once you get tableview array

首先从循环中删除此语句self.namesTableView.reloadData(),一旦获得tableview数组,它应该被调用

Use Dispatch async to avoid operation in main thread

使用Dispatch async可以避免在主线程中进行操作

Swift

DispatchQueue.main.async {
    // RELOAD TABLE DATA
}

Objective-C

dispatch_async(dispatch_get_main_queue(), ^{
     // RELOAD TABLE DATA
});

If data takes time then use call backs i.e. completion handlers and in the handler use dispatch async to reload table data as mention above

如果数据需要时间,则使用回调即完成处理程序,并在处理程序中使用dispatch async重新加载表数据,如上所述