表情包生成器:如何在didSelectRow中Push视图控制器而非模态呈现?
Hey there! Let's break down how to fix your slide-in push transition issue, plus answer your question about using segues in didSelectRowAt.
Can you use segues inside didSelectRowAt?
Absolutely! But since you're already manually instantiating your DetailsViewController, it's not necessary. If you wanted to use segues anyway, you'd need to:
- Create a manual segue in your storyboard (from your table view controller to the details view controller) and give it a unique identifier (e.g., "ShowDetailsSegue").
- Call
performSegue(withIdentifier: "ShowDetailsSegue", sender: meme)insidedidSelectRowAt. - Override
prepare(for segue: UIStoryboardSegue, sender: Any?)in your table view controller to pass the meme data to the details controller.
That said, sticking with manual instantiation is totally fine—let's focus on making the push transition work correctly.
Fixing the Push Transition (No Segues Needed)
Your current code uses present() which triggers a modal presentation. To get the slide-in push effect, you need to use pushViewController() instead. Here's what you need to do:
1. Ensure Your Table View Controller is in a Navigation Controller
First, double-check that your table view controller is embedded in a UINavigationController. If it's not:
- In Storyboard: Select your table view controller, go to Editor > Embed In > Navigation Controller.
- If using code: Initialize your table view controller inside a navigation controller when presenting it (e.g.,
let navController = UINavigationController(rootViewController: yourTableViewController)).
2. Update Your didSelectRowAt Code
Modify your existing code to use pushViewController() instead of present(), and move the data assignment before pushing the controller (this avoids issues where the image view might not be initialized yet):
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let meme = memes[indexPath.row] // Instantiate the details controller let detailController = UIStoryboard(name: "DetailsStoryboard", bundle: nil).instantiateViewController(withIdentifier: "DetailsViewController") as! DetailsViewController // Pass the meme image (pro tip: use a dedicated property instead of direct image view access) detailController.detailsImageView.image = meme.memedImage // Push the controller instead of presenting modally navigationController?.pushViewController(detailController, animated: true) // Deselect the table view row for better UX tableView.deselectRow(at: indexPath, animated: true) }
3. (Optional) Improve Data Passing
Directly accessing detailsImageView can cause problems if the view hasn't loaded yet (the image view will be nil). A better approach is to add a property to DetailsViewController:
// In DetailsViewController.swift var memeImage: UIImage? override func viewDidLoad() { super.viewDidLoad() detailsImageView.image = memeImage }
Then update your table view controller code to set this property instead:
// Replace detailController.detailsImageView.image = meme.memedImage with: detailController.memeImage = meme.memedImage
This is a more robust pattern that follows MVC best practices.
内容的提问来源于stack exchange,提问作者Andrew Tuzson

