Reputation: 12206
I have a UITableView list. I added code so when a list-item/row is tapped, the user can edit the cell contents in a modal view:
The problem:
It's a weird behavior. When I test the app, the first time I tap a cell after opening the app, there's sometimes a delay of 2-3 seconds before the modal view appears. I also notice that the delay happens the first time I tap each cell, but not the second. Lastly, sometimes after opening the app up, it appears to ignore the first tap. Is this normal core data fetch request behavior?
Code loaded on main VC ViewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//Break
//Load the list from Core Data
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
let fetchRequest = NSFetchRequest(entityName:"TodayTask")
var error: NSError?
let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as? [NSManagedObject]
if let results = fetchedResults {
todayTaskList = results
} else {
println("Could not fetch \(error), \(error!.userInfo)")
}
//Break
//This provides a variable height for each row
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 80.0
//Break
//Part of code for cell drag and drop functionality
let longpress = UILongPressGestureRecognizer(target: self, action: "longPressGestureRecognized:")
tableView.addGestureRecognizer(longpress)
}
Code run on cell tap
//Action: Performs 'tap on edit' segue
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
passingEdit = true
performSegueWithIdentifier("modalToEditor", sender: nil)
}
//Prepares variables to be passed for editing
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "modalToEditor") && passingEdit == true {
//Assign selection to a variable 'currentCell'
let indexPath = tableView.indexPathForSelectedRow();
let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as! CustomTableViewCell;
//Set cell text into variables to pass to editor
var cellNameForEdit = currentCell.nameLabel!.text
var cellDescForEdit = currentCell.descLabel.text
//Pass values to EditorView
var editorVC = segue.destinationViewController as! EditorView;
editorVC.namePassed = cellNameForEdit
editorVC.descPassed = cellDescForEdit
editorVC.indexOfTap = indexPath
}
}
Upvotes: 1
Views: 545
Reputation: 12206
Fixed!
After receiving a few comments and researching the suggestions, I've been able to resolve this issue of my cell-taps not segueing quickly on first tap (but a double tap gets a quick response!).
One comment was that I should call CoreData in the background, if that works, then lots of opinions I read are wrong. I read a lot that said background threads might actually be causing the issue. I didn't try this though, so I can't confirm if it is right or wrong.
Instead, the comment by @pdasdf set me on the right path. If you're creating a table that segues when a cell is tapped, you're probably doing so in code that looks like this:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("modalToEditor", sender: nil)
}
That is what my code looked like. I had a few other things for telling my prepareForSegue what was coding on, but above is the important part. All I did was change from that to this:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self.performSegueWithIdentifier("modalToAllocEditor", sender: nil)
}
}
I had never used dispatch before. It is, however, inline with my reading that there's some kind of queueing issue behind cell-tap-segues being delayed... so I assume this is remedying whatever the specific queue issue is.
Side note:
If the above fixed all your problems, stop reading! This is likely not relevant to everybody.
If your didSelectRowAtIndexPath is like mine, you actually have a little more code than above. I had a variable call 'passingEdit' that would be updated when a cell was tapped and it would tell my prepareForSegue if data needs to be passed.
In the new method, if I set this variable within the dispatch {} brackets, it wouldn't run. So if you need to do other stuff, make sure you do it within the tableView function but outside of the dispatch function:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self.performSegueWithIdentifier("modalToAllocEditor", sender: nil)
}
passingEdit = true
}
Good luck.
Upvotes: 3