Reputation: 625
I'm trying to segue an image from a "tableview controller" into a separate view where the image can be viewed "full-screen". The code I was using worked great until I updated to Swift 3. I've been reading about unwrapping optional values and I can't figure out what the error is here.
Thanks!
The line of code that the error is on:
Detailimageview.sd_setImage(with: URL(string:self.sentData1))
ERROR: fatal error: unexpectedly found nil while unwrapping an Optional value
The "full-screen" view controller in which this error is happening:
import UIKit
class PhotoView: UIViewController, UIPopoverPresentationControllerDelegate, UIScrollViewDelegate {
@IBOutlet weak var containerView: UIView!
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var Detailimageview: UIImageView!
var sentData1:String!
func scrollViewDidZoom(_ scrollView: UIScrollView) {
let imageViewSize = Detailimageview.frame.size
let scrollViewSize = scrollView.bounds.size
let verticalPadding = imageViewSize.height < scrollViewSize.height ? (scrollViewSize.height - imageViewSize.height) / 2 : 0
let horizontalPadding = imageViewSize.width < scrollViewSize.width ? (scrollViewSize.width - imageViewSize.width) / 2 : 0
scrollView.contentInset = UIEdgeInsets(top: verticalPadding, left: horizontalPadding, bottom: verticalPadding, right: horizontalPadding)
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return Detailimageview
}
func setZoomScale() {
let imageViewSize = Detailimageview.bounds.size
let scrollViewSize = scrollView.bounds.size
let widthScale = scrollViewSize.width / imageViewSize.width
let heightScale = scrollViewSize.height / imageViewSize.height
scrollView.minimumZoomScale = min(widthScale, heightScale)
scrollView.zoomScale = 1.0
}
override func viewWillLayoutSubviews() {
setZoomScale()
}
override func viewDidLoad() {
super.viewDidLoad()
Detailimageview.sd_setImage(with: URL(string:self.sentData1))
// Do any additional setup after loading the view.
setZoomScale()
}
func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return containerView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func DismissView(_ sender: AnyObject) {
self.dismiss(animated: true, completion: nil)
}
@IBAction func showPopup(_ sender: AnyObject) {
let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "sbPopUpID") as! PopUpViewController
self.addChildViewController(popOverVC)
popOverVC.view.frame = self.view.frame
self.view.addSubview(popOverVC.view)
popOverVC.didMove(toParentViewController: self)
}
override var prefersStatusBarHidden: Bool {
get {
return true
}
}
The "tableview controller":
import UIKit
class ListViewController: UITableViewController {
var imageURLs = [String]()
let cellVenue = ["Example Venue","Example Venue1","Example Venue2","Example Venue3","Example Venue4","Example Venue5"]
let cellLocation = ["Example Venue, Location","Example Venue, Location1","Example Venue, Location2","Example Venue, Location3","Example Venue, Location4","Example Venue, Location5"]
let cellDate = ["Example Date, 1970","Example Date, 1971","Example Date, 1972","Example Date, 1973","Example Date, 1974","January 1st, 1975"]
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
override func viewDidLoad() {
super.viewDidLoad()
imageURLs = ["https://i.imgur.com/bSfVe7l.jpg","https://i.imgur.com/vRhhNFj.jpg","https://i.imgur.com/bSfVe7l.jpg","https://i.imgur.com/vRhhNFj.jpg","https://i.imgur.com/bSfVe7l.jpg"]
self.tableView.separatorStyle = .none
// tableView.indicatorStyle = UIScrollViewIndicatorStyle.white
self.view.backgroundColor = UIColor.black
self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
navigationController!.navigationBar.barTintColor = UIColor.black
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return imageURLs.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: ListViewCell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! ListViewCell
let imageView = cell.viewWithTag(1) as! UIImageView
imageView.sd_setImage(with: URL(string: imageURLs[indexPath.row]))
imageView.sd_setHighlightedImage(with: URL(string: imageURLs[indexPath.row]), options: [.continueInBackground, .progressiveDownload, .avoidAutoSetImage])
cell.cellVenue.text = cellVenue[indexPath.row]
cell.cellLocation.text = cellLocation[indexPath.row]
cell.cellDate.text = cellDate[indexPath.row]
return cell
}
func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "DetailView") {
// segue.destination is correct, xcode keeps switching it to segue.description
let VC = segue.destination as! PhotoView
if let indexpath = self.tableView.indexPathForSelectedRow {
let Imageview = imageURLs[indexpath.row] as String
VC.sentData1 = Imageview
}
}
}
override var prefersStatusBarHidden: Bool {
get {
return true
}
}
Upvotes: 0
Views: 781
Reputation: 23624
It looks like this is a view lifecycle issue. viewDidLoad
on the child controller is getting called before prepareForSegue
is called or at least before it is completed on the parent. Looking around I see conflicting info on whether this is supposed to happen and I don't typically use storyboards so I'm not positive myself. In any case, an easy fix in your case is just to move your image setting code out of viewDidLoad
and into viewWillAppear
. The URL should definitely be set by that point and your optional will be unwrapped successfully.
Upvotes: 2