Swift/iOS8: set imageView for next View Controller before Segue - ios

depending on a few parameters I am trying to set an Image on the second VC, but somehow it always returns null??
this is what i do:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showDetail" {
println("going forth!")
println(self.myButton.selected)
let controller = segue.destinationViewController as? DetailVC
if myButton.selected == true {
var newImage = UIImage(named:"Test1")
var oldImage = controller?.imageView.image
println(oldImage)
oldImage = newImage
} else {
var newImage = UIImage(named:"Test2")
var oldImage = controller?.imageView.image
println(oldImage)
oldImage = newImage
}
} else {
println("roflcopter")
}
}
the detail VC basically has "nothing":
import UIKit
class DetailVC: UIViewController {
#IBOutlet weak var imageView: UIImageView!
var testString:String!
#IBAction func goBacktoMain(segue: UIStoryboardSegue) {
println("going back")
}
override func viewDidLoad() {
super.viewDidLoad()
println("view Did Load")
println(testString)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
the second VC has a default image set via Storyboard but when I stop with a breakpoint #let controller it will tell me that imageview actually is null, does this only get set once the detail vc was shown once?
€dit: setting the string and printing it out on the second VC works perfectly fine

Where are you setting the image?
Inside the prepareForSegue the UIImageView IBOutlet will not have loaded. You have to declare an image variable in your DetailVC class like below and set that image in viewDidLoad.
class DetailVC
{
var image:UIImage? = nil
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad()
{
imageView.image = image
}
}
In your prepareSegue function, set
let controller = segue.destinationViewController as? DetailVC
controller?.image = //Your Image according to conditions.

Declare a UIImage variable in the destination segue, pass the image object to it.
On viewDidLoad on the destination object, assign the image to the imageView.Image property
Most probably the Outlet is not yet initialized

Related

Passing image from ViewController to ViewController

I try to pass an image from one ViewController1 to another ViewController2 when a button is tapped. I am using segues in my Storyboard.
ViewController1
import UIKit
class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
var imagePicker: UIImagePickerController!
#IBAction func editPhoto(_ sender: UIButton) {
let editViewController = storyboard?.instantiateViewController(withIdentifier: "EditImageViewController") as! EditImageViewController
editViewController.imageForEdit = imageView.image!
print(imageView)
print(imageView.image!)
navigationController?.pushViewController(editViewController, animated: true)
}
#IBOutlet weak var imageView: UIImageView! {
didSet {
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
print(imageView) results in
some(UIImageView: 0x7fc34df0e630; frame = (8 29; 303 443); clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = CALayer: 0x60000023e520)
and print(imageView.image!) in
size {3000, 2002} orientation 0 scale 1.000000
ViewController2
import UIKit
class EditImageViewController: UIViewController {
var imageForEdit = UIImage()
#IBOutlet weak var editingImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
editingImage.image = imageForEdit
print(imageForEdit)
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
print(imageForEdit) results in
size {0, 0} orientation 0 scale 1.000000
Why is that? Why isnt the image passed to ViewController2?
It seems to me that this could be a lot simpler. If you're using a Storyboard with a segue, you can easily accomplish this in prepare(for segue: UIStoryboardSegue, sender: Any?). Here's a sample storyboard:
In this case, ViewController has a segue on the Edit Image button to the EditImageViewController.
When you push that button, you get your prepare(for segue: call. Here's a sample ViewController:
class ViewController: UIViewController {
var imagePath = Bundle.main.path(forResource: "icon8", ofType: "png")
var anEditableImage:UIImage?
override func viewDidLoad() {
super.viewDidLoad()
if let imagePath = imagePath {
anEditableImage = UIImage(contentsOfFile: imagePath)
}
}
// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? EditImageViewController {
destination.imageForEdit = anEditableImage
}
}
}
And here's the EditImageViewController:
class EditImageViewController: UIViewController {
var imageForEdit:UIImage?
override func viewDidLoad() {
super.viewDidLoad()
print(imageForEdit ?? "Image was nil")
}
}
Using prepare(for segue: UIStoryboardSegue, sender: Any?) is the preferred way for a Storyboard-based app to pass data between View Controllers. It's very simple and it works.
Sample project is here if you want to see the working code:
https://www.dropbox.com/s/eog01bmha67c5mv/PushImage.zip?dl=0
var imageForEdit: UIImage? {
didSet {
editingImage.image = imageForEdit
}
}
Replace var imageForEdit = UIImage() with var imageForEdit : UIImage?
i test code my self , make sure that imageView have image
#IBOutlet weak var imageView: UIImageView! {
didSet {
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
}
}
You can create an public variable so you can pase data from one viewcontroller to another view controller.
class variables
{
static var image = UIImage()
}
the 2 controller:
#IBOutlet weak var anotherviewcontroller: UIImageView!
anotherviewcontroller.image = variables.image

how to pass a UI ImageView from one view controller to another? swift 3

I am trying to pass this UI Image View from one view controller to another on the same storyboard. I have already passed a UI TextField to a UI Label and UI Button. Now I need to do it with a UI Image View.
Here are my two view controllers.
import UIKit
class PhotoShareViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var contentTextView: UITextView!
#IBOutlet weak var thatTextField: UITextField!
#IBOutlet weak var thisTextField: UITextField!
var presenter: PhotoShareModuleInterface!
var image: UIImage!
#IBAction func thisUploadPhoto(_ sender: Any) {
if thisTextField.text != "" && thatTextField.text != ""
{
performSegue(withIdentifier: "segue", sender: nil)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
var photoShareLabelViewController = segue.destination as! PhotoShareLabelViewController
photoShareLabelViewController.thisString = thisTextField.text!
photoShareLabelViewController.thatString = thatTextField.text!
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
imageView.image = image
}
override var prefersStatusBarHidden: Bool {
return true
}
#IBAction func didTapCancel(_ sender: AnyObject) {
presenter.cancel()
presenter.pop()
}
/* #IBAction func didTapDone(_ sender: AnyObject) {
guard let message = thatTextField.text, !message.isEmpty else {
return
}
guard let messageOne = thisTextField.text, !messageOne.isEmpty else {
return
}
presenter.finish(with: image, content:message)
presenter.dismiss()
}
}
*/
}
extension PhotoShareViewController: PhotoShareViewInterface {
var controller: UIViewController? {
return self
}
}
if someone could tell me how to send the image from one view controller into another that would be awesome!
You didn't show PhotoShareLabelViewController, but presumably it has:
var thisString: String?
Add
var thisImage: UIImage?
And then pass it along the same way as thisString
photoShareLabelViewController.thisImage = imageView.image
And pick it up in the viewDidLoad of PhotoShareLabelViewController (which is probably where you pick up thisString). Something like:
self.imageView.image = self.thisImage
But, using whatever variable name you are using.
In short, just copy what you are doing for thisString, but use a UIImage as the type instead of String.
NOTE: You are not passing a UIImageView from one VC to another (that is impossible). You are passing the image from an imageview from one VC to another.

pass UIImage with a segue

I want to pass an UIImage between two view with a segue. The problem is that my UIImage appear white in the second view controller.
The segue :
var screenShot = UIImage()
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "screenshotEmbed") {
let svc = segue.destinationViewController as! screenshotViewController
svc.toPass = self.screenshot
}
The secondViewController :
class screenshotViewController: UIViewController {
#IBOutlet var screenshotView: UIImageView!
var toPass = UIImage()
override func viewDidLoad() {
super.viewDidLoad()
self.screenshotView.image = self.toPass
}
}
My UIImage is just a screenshot, here the function :
func captureScreen() -> UIImage {
var window: UIWindow? = UIApplication.sharedApplication().keyWindow
window = UIApplication.sharedApplication().windows[0]
UIGraphicsBeginImageContextWithOptions(window!.frame.size, window!.opaque, 0.0)
window!.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image;
}
EDIT. Screenshot storage on a button :
#IBAction func photoAction(sender: AnyObject) {
self.screenShot = captureScreen()
}
I've tried lot of thing but still blank (not empty cause the memory adress is good).
Not sure if your screenshotImage object has Image or not.
I tried below code and it's working fine.
import UIKit
class ViewController: UIViewController {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "screenshotEmbed") {
let svc = segue.destinationViewController as! ScreenshotViewController
svc.toPass = captureScreen()
}
}
func captureScreen() -> UIImage {
var window: UIWindow? = UIApplication.sharedApplication().keyWindow
window = UIApplication.sharedApplication().windows[0]
UIGraphicsBeginImageContextWithOptions(window!.frame.size, window!.opaque, 0.0)
window!.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image;
}
}
Result with this code:
Project Sample for more Info.
in second scene you should modified the property to
var toPass: UIImage!
because in second scene you initial the image to UIImage()

moving the UIImageView from the main view to another

my code works fine in choosing the picture from the gallery and display it in the same view,
what am stuck into now, is transferring that UIImageView chosen to the next activity when "next" button is clicked
here is the code that opens the gallery
#IBAction func gallery(sender: AnyObject) {
if UIImagePickerController.availableMediaTypesForSourceType(.PhotoLibrary) != nil {
picker.allowsEditing = false
picker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
presentViewController(picker, animated: true, completion: nil)
}
}
this is the code that displays the image in the same view
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
var chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
imageChosen.contentMode = .ScaleAspectFit
imageChosen.image = chosenImage
dismissViewControllerAnimated(true, completion: nil)
}
now after the UIImageView saved in the imageChosen, here is the code am using to pass that image to the next view
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var pass:postView = segue.destinationViewController as! postView
if(segue.identifier == "next"){
pass.imgv.image = imageChosen.image
}
}
this line of code that causes the program to crash
pass.imgv.image = imageChosen.image
the imgv in the second view is declared like this
#IBOutlet weak var imgv: UIImageView!
what am i doing wrong here, please direct me
You cannot set data in a view which is not rendered yet . So pass image to second view and set that Image to ImageView in secondView's viewDidLoad
override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!) {
if segue.identifier == "next" {
var pass:second = segue.destinationViewController as! second
pass.currentImage=myImageView.image;
}
}
//Second view
class second: UIViewController {
#IBOutlet weak var tempImgView: UIImageView!
var currentImage:UIImage!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if((currentImage) != nil){
tempImgView.image=currentImage;
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
You are using weak reference for image view and trying to get it in other controllers . do as following .
#IBOutlet Strong var imgv: UIImageView
Secondly your way of fetching view controller wrong ... Try it as following
if segue.identifier == "ShowCounterSegue"
{
if let destinationVC = segue.destinationViewController as? OtherViewController{
destinationVC.numberToDisplay = counter
}
}
You can't access the UIImageView directly in second View Controller. Instead create variable UIImage in second View Controller and assign your selected UIImage to it. Later in viewdidload of second View Controller set the UIImageView.
First View
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let pass:postView = segue.destinationViewController as! postView
if(segue.identifier == "next"){
pass.tempImage = imageChosen.image
}
}
Second View
#IBOutlet weak var imgv: UIImageView!
var tempImage:UIImage!
override func viewDidLoad() {
super.viewDidLoad()
self.imgv.image=tempImage
}
In the PostView, just create variable like var img: UIImage!
Replace this line pass.imgv.image = imageChosen.image with pass.img = imageChosen.image
In viewDidLoad() of PostView, add this line, imgv.image = image
We can not set properties of IBOutlets of secondView from the firstView, because IBOutlets of ViewController will get memory after execution of viewDidLoad()
So you have to create appropriate data variable to pass data to IBOutlet.
Here is the example code.
class FirstViewController: UIViewController {
#IBOutlet weak var imageViewInput: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
//check the condition for your segue.identifier, if any
var destination : NewViewContrller! = segue.destinationViewController as NewViewContrller ;
if let image = imageViewInput?.image {
destination.outputImage = image;
}
}
}
class NewViewContrller: UIViewController {
#IBOutlet weak var outputImageView: UIImageView!
var outputImage: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if let image = outputImage {
outputImageView.image = image;
}
}
}

Pass Image from UITabBarController to subview (Swift)

I am using Xcode 6 with swift.
I am trying to pass an image / UIImage from my UITabBarController to one of the subviews (tabs). The Image itself is being passed to the UITabBarController using the loadImage function (which is in return called by another UIViewController during prepareForSegue).
//this is the tab bar controller
class DesignerTabBarController : UITabBarController{
var pickedImage : UIImage = UIImage() //empty image
var VC1: DesignerTabController = DesignerTabController.alloc()
func loadImage(passedImage: UIImage){
pickedImage = passedImage
println(pickedImage) // image is accessible from here
}
override func viewDidLoad() {
super.viewDidLoad()
println(pickedImage) //image is accessible from here
VC1.pickedImageView.image = pickedImage // this line gives "unexpectedly found nil when unwrapping optional"
}
}
//this is the `UIViewcontroller` I want display the image (inside pickedImageView)
class DesignerTabController : UIViewController{
#IBOutlet weak var pickedImageView: UIImageView!
}
I realize that my way of passing the image from the UITabBarController to the sub-view will not work, even though when there are no syntax errors displayed within Xcode (it suggested pickedImageView when I started typing so I think I am really close to the solution).
If it's not possible passing data from my UITabBarController to the (first) subview, how can I pass data directly to the first subview? As I explained above, I am passing the image from another view using prepareForSegue. Does prepareForSegue directly to the first view work in my case?
Thank you very much for any suggestions, I'll try them and get back with my findings.
Your tab bar controller has viewControllers property. Just iterate through it check which controller is kind of class you need.
func passImage(passedImage: UIImage)
{
if viewControllers!.isEmpty{
return
}
for index in 0...viewControllers!.count{
if let controller = viewControllers[index] as? DesignerTabController
controller.pickedImageView.image = passedImage
}
}
solved by using viewDidLayoutSubviews() instead of viewDidLoad()
see below code for my working solution:
class DesignerTabController : UIViewController{
#IBOutlet weak var pickedImageView: UIImageView!
#IBOutlet weak var labelTest: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
}
class DesignerTabBarController : UITabBarController{
var pickedImage : UIImage = UIImage()
func loadImage(passedImage: UIImage){
pickedImage = passedImage
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidLayoutSubviews() {
if let controller = viewControllers![0] as? DesignerTabController{
controller.pickedImageView.image = pickedImage
}
}
}

Resources