Reputation: 2866
I have UITableViewController that needs to present a view controller modally when a cell is tapped. I'm using didSelectRowAt
for this.
The modal view controller is a custom UIViewController subclass that has a loadFromStoryboard()
class method to load it.
Sometimes when I tap the cell, the view controller is presented quickly without issue. However, other times it doesn't show until I, for instance, try to scroll on the tableview or tap another cell.
I'm guessing this is some sort of problem with threading. However, throughout my entire app, I never delegate a task to another thread or start another queue at all.
N.B.: I am using Swift 3.
Update
Here's the loadFromStoryboard()
method:
class func loadFromStoryboard(particle: ParticleProtocol, isFavourite: Bool = false) -> ParticleDisplayViewController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let viewController = storyboard.instantiateViewController(withIdentifier: "ParticleDisplayViewController") as? ParticleDisplayViewController {
viewController.particle = particle
viewController.isFavourite = isFavourite
return viewController
} else {
fatalError("Can't find ParticleDisplayViewController in Main storyboard")
}
}
And here is didSelectRowAt
from my UITableViewController:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.section {
case 1:
let isFavourite = ParticleStorageManager.standardModelParticleIsFavourite(index: indexPath.row)
self.present(ParticleDisplayViewController.loadFromStoryboard(particle: standardModelParticles[indexPath.row], isFavourite: isFavourite), animated: true, completion: nil)
case 0:
let isFavourite = ParticleStorageManager.savedParticleIsFavourite(index: indexPath.row)
self.present(ParticleDisplayViewController.loadFromStoryboard(particle: self.particles[indexPath.row], isFavourite: isFavourite), animated: true, completion: nil)
default:
self.contextKey = "AddingParticle"
self.present(CreateParticleTableViewController.loadFromStoryboard(reciever: self), animated: true, completion: nil)
}
}
ParicleStorageManager
simply reads and writes data to the UserDefaults
.
Here's viewDidLoad()
from the modal view controller:
override func viewDidLoad() {
self.view.backgroundColor = .clear()
self.particleViewContainer.layoutIfNeeded()
self.particleViewContainer.addSubview(ParticleView(position: CGPoint.zero, width: particleViewContainer.width, particle: self.particle, isFavourite: self.isFavourite))
propertiesTableView.backgroundColor = UIColor.white().withAlphaComponent(0.3)
propertiesTableView.layer.borderWidth = 1.5
propertiesTableView.layer.borderColor = UIColor.black().cgColor
self.propertiesTableView.blur()
}
Upvotes: 0
Views: 454
Reputation: 429
Calling self.present
from within func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
is the reason here as UIPresentationController
may take time to find the layout from tableview row selection and causes a delay in presenting a new controller modally.
A better way to present is using the DispatchQueue
on main thread. This way the delay can be avoided.
DispatchQueue.main.async {
//Your Presentation code should be called here....
}
Upvotes: 1