Reputation: 145
I have an alert view that i made using presentr from GitHub. I used a simple view controller
that will overlay over the current view controller. Now i have elements such as a UIImage
and a UIlabel
from the first view controller
that needs to be accessed by the alert view controller
. But when I click a unbutton in the alert view controller
to access the uiimage
and text
from uilabel
from the firstviewcontroller. Here is the code. Can you show me how I can fix this. I can't segue the data because I'm presenting the view controller and the data I'm trying to access is too much too segue anyway. I keep getting this error "fatal error: unexpectedly found nil while unwrapping an Optional value" overtime i click the save button in alertviewcontroller
.
class firstviewcontroller: UIViewController{
var photos2: [ImageSource]?
@IBOutlet weak var Label: UIlabel!
@IBOutlet weak var Image: UIImage!
}
class alertviewcontroller: UIViewController{
@IBAction func Save(_ sender: Any) {
dismiss(animated: true, completion: nil)
let storyboard: UIStoryboard = UIStoryboard.init(name: "Main", bundle: nil)
let firstViewController: firstviewcontroller = storyboard.instantiateViewController(withIdentifier: "firstviewcontroller") as! firstviewcontroller
if let image = firstViewController.Image {
imageview.image = image
}
if let label = firstViewController.Label {
label.text = Label.text
}
}
}
Upvotes: 0
Views: 845
Reputation: 5349
The biggest mistake you're making is that you are creating a new instance of firstviewcontroller
instead of just accessing the current one.
class alertviewcontroller: UIViewController{
@IBAction func Save(_ sender: Any) {
dismiss(animated: true, completion: nil)
let storyboard: UIStoryboard = UIStoryboard.init(name: "Main", bundle: nil)
let firstViewController: firstviewcontroller = storyboard.instantiateViewController(withIdentifier: "firstviewcontroller") as! firstviewcontroller // This is the mistake
if let image = firstViewController.Image {
imageview.image = image
}
if let label = firstViewController.Label {
label.text = Label.text
}
}
}
What you should do instead is access the presentingViewController
since you presented the alertviewcontroller
using the present
function
The code would look like this
class alertviewcontroller: UIViewController{
@IBAction func Save(_ sender: Any) {
dismiss(animated: true, completion: nil)
let storyboard: UIStoryboard = UIStoryboard.init(name: "Main", bundle: nil)
// NOTE: only do implicit unwrapping `as!` if you're sure that the value you're unwrapping is not `nil` or it is of the correct `data type` cause it might cause your app to crash
let firstViewController: firstviewcontroller = self.presentingViewController as! firstviewcontroller
if let image = firstViewController.Image {
imageview.image = image
}
if let label = firstViewController.Label {
label.text = Label.text
}
}
}
Tip: Please review Swift coding guidelines since there are some minor mistakes regarding your naming of methods
, variables
, and classes
.
Upvotes: 1
Reputation: 2455
Might I am wrong but after review your code I have found this messing statement
let firstViewController: firstviewcontroller = storyboard.instantiateViewController(withIdentifier: "firstviewcontroller") as! firstviewcontroller
In this statement you are creating a new instance of firstviewcontroller
not accessing already created instance of firstviewcontroller
.
Next, you said
I used a simple view controller that will overlay over the current view controller
So I have assumed you didn't present or push alertviewcontroller
on current viewController, on that behave I suggest you the following solutions
In alertviewcontroller
get the instance of topViewController by using this method
class func topViewController(base: UIViewController? = (UIApplication.shared.delegate as! AppDelegate).window?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return topViewController(base: nav.visibleViewController)
}
if let tab = base as? UITabBarController {
if let selected = tab.selectedViewController {
return topViewController(base: selected)
}
}
if let presented = base?.presentedViewController {
return topViewController(base: presented)
}
return base
}
then you can transfer your data from alertviewcontroller
to topViewController.
alertviewcontroller
to firstviewcontroller
by using delegates.Upvotes: 0