allocate
allocate

Reputation: 1343

Setting a subview.hidden = false locks up UI for many seconds

I'm using a button to populate a UIPickerView on a hidden UIVisualEffectView. The user clicks the button, the VisualEffectView blurs everything else, and the PickerView displays all the names in their contact list (I'm using SwiftAddressBook to do this.)

This works fine except when the user clicks the button, the UI locks up for about 5-10 seconds. I can't find any evidence of heavy CPU or memory usage. If I just print the sorted array to the console, it happens almost immediately. So something about showing the window is causing this bug.

@IBAction func getBffContacts(sender: AnyObject) {
    swiftAddressBook?.requestAccessWithCompletion({ (success, error) -> Void in
        if success {
            if let people = swiftAddressBook?.allPeople {
                self.pickerDataSource = [String]()
                for person in people {
                    if (person.firstName != nil && person.lastName != nil) {
                        //println("\(person.firstName!) \(person.lastName!)")
                        self.pickerDataSource.append(person.firstName!)
                    }
                }
            //println(self.pickerDataSource)
            println("done")
            self.sortedNames = self.pickerDataSource.sorted { $0.localizedCaseInsensitiveCompare($1) == NSComparisonResult.OrderedAscending }
            self.pickerView.reloadAllComponents()
            self.blurView.hidden = false
            }


        }
        else {
            //no success, access denied. Optionally evaluate error
        }
    })

}

Upvotes: 2

Views: 68

Answers (1)

matt
matt

Reputation: 536037

You have a threading issue. Read. The. Docs!

requestAccessWithCompletion is merely a wrapper for ABAddressBookRequestAccessWithCompletion. And what do we find there?

The completion handler is called on an arbitrary queue

So your code is running in the background. And you must never, never, never attempt to interact with the user interface on a background thread. All of your code is wrong. You need to step out to the main thread immediately at the start of the completion handler. If you don't, disaster awaits.

Upvotes: 5

Related Questions