Faced with such anxiety. When registering to a cell and navigating to the DetailViewController, the following error occurs: "Error stream 1: Fatal error: Unexpectedly found nil while implicitly expanding an optional value" and the application crashes.
ViewController
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var segmented: UISegmentedControl!
private let urlSessionApi = Network()
private var posts = [Post]()
//private var fullPost: Detail?
private let segueId = "detailPost"
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView.dataSource = self
self.collectionView.delegate = self
showData()
}
@IBAction func segmentedAction(_ sender: Any) {
switch segmented.selectedSegmentIndex {
case 0:
showData()
case 1:
sortedByLikes()
reloadCollectionView()
case 2:
sortedByDate()
reloadCollectionView()
default:
break
}
}
}
extension ViewController: UICollectionViewDataSource,UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return posts.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! PostCell
let posts = posts[indexPath.row]
cell.setup(post: posts)
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let cell = sender as? UICollectionViewCell,
let indexPath = self.collectionView.indexPath(for: cell) {
let vc = segue.destination as! DetailViewController //Cast with your DestinationController
//Now simply set the title property of vc
vc.fullPost = posts[indexPath.row]
}
}
// MARK: сортировка по лайкам
private func sortedByLikes() {posts.sort{$0.likes_count > $1.likes_count}}
// MARK: сортировка по дате
private func sortedByDate() {posts.sort{$0.timeshamp > $1.timeshamp}}
// MARK: обновление collectionView
private func reloadCollectionView() {collectionView.reloadSections(IndexSet(integer: 0))}
private func showData() {
urlSessionApi.fetchPost {data in
self.posts = data
DispatchQueue.main.async {
self.collectionView.reloadData()}
}
}
}
struct PostArray: Codable {
let posts: [Post]
}
struct Post: Codable{
let postId: Int
let timeshamp: Int
let title: String
let preview_text: String
let likes_count: Int
}
DetailViewController
class DetailViewController: UIViewController {
private var fullPost: Detail?
@IBOutlet weak var titlePost: UILabel!
@IBOutlet weak var previewPost: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
postView()
}
private func postView() {
titlePost.text = fullPost?.title
titlePost.text = fullPost?.text
}
}
How to solve such a problem?
>Solution :
You can’t set text on UIlabel in DetailsViewController from ViewController’s prepareForSeque method.
you just need to do this in prepareForSeque Method :
if let cell = sender as? UICollectionViewCell,
let indexPath = self.collectionView.indexPath(for: cell) {
let vc = segue.destination as! DetailViewController //Cast with your DestinationController
//Now simply set the title property of vc
vc.fullPost = posts[indexPath.row]
}
and you need to remove "private" protection level of fullPost variable. it will work.