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()
Related
The image is not from one VC to another VC.
The problem is displaying it to the image view in the main UIViewController. I have everything hooked up correctly in the Storyboard.
Click here to view my storyboard layout.
Please note some of my unnecessary code has been removed from both ViewController classes.
Here is my first UIViewController:
import UIKit
class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
var imagePicker: UIImagePickerController!
#IBAction func editPhoto(_ sender: UIButton) {
let ViewController2 = storyboard?.instantiateViewController(withIdentifier: "AddNewEaterySegue") as! ViewController2
ViewController2.imageForEdit = imageView.image!
print(imageView)
print(imageView.image!)
navigationController?.pushViewController(ViewController2, animated: true)
}
#IBOutlet weak var imageView: UIImageView! {
didSet {
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
}
}
}
Here is my second UIViewController:
import UIKit
class ViewController2: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
var filter : CIFilter!
var imageForEdit = UIImage()
var imagePicker: UIImagePickerController!
#IBOutlet weak var select: UISegmentedControl!
#IBOutlet weak var imageLabel: UIImageView!
#IBOutlet weak var textField: UITextField!
#IBAction func saveButtonPressed(_ sender: UIImage) {
if textField.text == "" {
print("Не все поля заполнены")
} else {
}
performSegue(withIdentifier: "unwindSegueFromViewController", sender: sender)
}
override func viewDidLoad() {
super.viewDidLoad()
imageLabel.image = imageForEdit
print(imageLabel)
// Do any additional setup after loading the view.
}
#IBAction func tappedEnter(_ sender: Any) {
if textField.text?.isEmpty ?? true {
return
} else {
if let texttxt = textField.text {
let data = texttxt.data(using: .ascii, allowLossyConversion: false)
if select.selectedSegmentIndex == 0
{
filter = CIFilter(name: "CICode128BarcodeGenerator")
} else {
filter = CIFilter(name: "CIQRCodeGenerator")
}
filter.setValue(data, forKey: "inputMessage")
let transform = CGAffineTransform(scaleX: 5, y: 5)
let image = UIImage(ciImage: filter.outputImage!.transformed(by: transform))
imageLabel.image = image
}
}
}
}
When you are pushing to ViewController2 your imageView in ViewController is empty.
Where exactly are you setting the image for imageView?
In your storyboard, the imageView in ViewController is empty and also in the didSet method for imageView in ViewController you have not set any image to the imageView.
Try this in ViewController:
#IBOutlet weak var imageView: UIImageView! {
didSet {
//Add a test image to your project.
imageView.image = UIImage(named: "YOUR_TEST_IMAGE_NAME.jpeg")
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
}
}
EDIT: Ok I guess I was not clear on your question. So in order to send the image from "ViewController2" back to "ViewController", you can use many methods but the way I would do it is by using Protocols.
I have done it in a generic way but you can apply this to send any kind of data from one view controller back to the previous view controller.
Try this in ViewController:
import UIKit
protocol ImageViewProtocol{
func sendImageToViewController(theImage: UIImage)
}
class ViewController: UIViewController, ImageViewProtocol {
func sendImageToViewController(theImage: UIImage) {
imageView.image = theImage
}
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
let viewcontroller2 = storyboard?.instantiateViewController(withIdentifier: "viewcontroller2") as! ViewController2
viewcontroller2.delegate = self
self.navigationController?.pushViewController(viewcontroller2, animated: true)
}
}
Try this in ViewController2:
import UIKit
class ViewController2: UIViewController {
var delegate: ImageViewProtocol!
#IBOutlet weak var barcodeImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
barcodeImageView.image = UIImage(named: "test_image.jpg")
}
#IBAction func saveButtonAction(_ sender: Any) {
delegate.sendImageToViewController(theImage: barcodeImageView.image!)
self.navigationController?.popViewController(animated: true)
}
}
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
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.
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;
}
}
}
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