passing data from one view controller to other showing nil - swift

//first viewController where Tvshowpath contains data. I print Tvshowpath2 in this viewController data is printed//
#objc var TvshowPath = NSDictionary()
override func viewDidLoad()
{
super.viewDidLoad()
let playerPage =
self.storyboard?.instantiateViewController(withIdentifier:
"playerLayer")
as! PlayerLayerViewController
playerPage.TvshowPath2 = TvshowPath
print(playerPage.TvshowPath2)
self.navigationController?.pushViewController(playerPage, animated: true)
}
//In the second viewController where Tvshowpath2 data getting nil
#objc var TvshowPath2 = NSDictionary()
override func viewDidLoad()
{
super.viewDidLoad()
print(TvshowPath2)
}

Related

No Storyboard Member within my ViewController when calling another view controller

When I run my code below within my view controller
import UIKit
class SecondViewController: UIViewController {
let fifthVC = self.storyboard?.instantiateViewController(withIdentifier: "fifthVC") as? FifthViewController
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func twentyLife() {
fifthVC.lifePointsInt = 20
}
#IBAction func thirtyLife() {
fifthVC.lifePointsInt = 30
}
#IBAction func fortyLife() {
fifthVC.lifePointsInt = 50
}
}
I am getting error
Value of type '(SecondViewController) -> () -> SecondViewController'
has no member 'storyboard'
How can I fix this?
I don't know what you are trying to do here but to remove that error , you should call the following line inside some function
let fifthVC = self.storyboard?.instantiateViewController(withIdentifier: "fifthVC") as? FifthViewController
You can either call it in viewDidLoad or you can make a separate function and call it. But first you need to define fifthVC variable in view controller.
var fifthVC:UIViewController?
Then inside viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
fifthVC = self.storyboard?.instantiateViewController(withIdentifier: "fifthVC") as? FifthViewController
}

How to send an array of struct between two view controllers?

Im trying to send an array "ranking" of Struct between two VC after tapping the "rankingButton". I don't know what to code in the second vc to get and manipulate the array.
First VC:
struct TopPoint{
let user: String
let points: Int
var position: Int
}
var ranking: [TopPoint] = []
override func viewDidLoad() {
super.viewDidLoad()
let user1 = TopPoint(user: "fran", points: 1324, position: 1)
ranking.append(user1)
}
#IBAction func rankingButton(_ sender: Any) {
let vc = TopUserTableViewController(nibName: "TopUserTableViewController", bundle: nil)
vc.ranking = ranking
navigationController?.pushViewController(vc, animated: true)
}
Second VC:
class TopUserTableViewController: UITableViewController {
var ranking = [TopPoint]()
override func viewDidLoad() {
super.viewDidLoad()
}
//what to code to get the array?
}
Once your secondVC pushed, you can directly access the array in the secondVC. Because you set its ranking property equal to ranking in the firstVC For example consider having a method to iterate through array elements and print user of each struct element inside your array. You can do it by:
class TopUserTableViewController: UITableViewController {
var ranking: [TopPoint]!
override func viewDidLoad() {
super.viewDidLoad()
iterateElements()
}
func iterateElements() {
ranking.forEach { (element) in
print(element.user)
}
}
}
You could also access directly inside your viewDidLoad, I added iterateElements method as reference, access directly in viewDidLoad as:
override func viewDidLoad() {
super.viewDidLoad()
ranking.forEach { (element) in
print(element.user)
}
}
viewDidLoad() is too early in the lifecycle. Just move your code:
func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
ranking.forEach { (element) in print(element.user) } }
}

Swift delegate beetween two VC without segue

I have 3 classes:
ChatLogControoller
GetImageFromLibraty(NSObject class)
ImagePreviewViewController
I want to press a clip from the first VC, then open the media library to pick an image. Then the selected image is passed to the third VC as a previewController. Then if I select 'done' I want to pass it to the first VC.
1st VC
class ChatLogControoller: UICollectionViewController, UICollectionViewDelegateFlowLayout, NSFetchedResultsControllerDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, DataSentDelegate {
func recievePhoto(data: UIImage) {
imageFromView = data
print("-------\(imageFromView = data)")
}
override func viewDidLoad() {
super.viewDidLoad()
let vc = ImagePreviewController()
self.vc.delegate = self
}
2nd class its just picker of image, so i pass image to 3rd VC and this image appears on imageView of 3rd VC successfully!
my 3rd VC
protocol DataSentDelegate {
func recievePhoto(data: UIImage)
}
class PreviewController: UIViewController, UIScrollViewDelegate {
var delegate : DataSentDelegate? = nil
var aImageView: UIImageView!
var aImage: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Add", style: .plain, target: self, action: #selector(actionSend))
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(actionBack))
}
#objc func actionBack() {
dismiss(animated: false, completion: nil)
}
#objc func actionSend() {
let data = aImageView.image
delegate?.recievePhoto(data: data!)
dismiss(animated: true, completion: nil)
}
You need to create one more protocol in your SecondViewController to Pass that delegate from ThirdViewController to FirstViewController.
FirstViewController:
import UIKit
class ViewController: UIViewController, DataSentDelegate, dataSentDelegate {
#IBOutlet weak var imagefromThirdVC: UIImageView!
var thirdVCImage: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func buttonTapped(_ sender: Any) {
let vc = storyboard?.instantiateViewController(withIdentifier: "ViewController2") as! ViewController2
vc.delegate = self
self.navigationController?.pushViewController(vc, animated: true)
}
func goToThirdVC() {
let vc = storyboard?.instantiateViewController(withIdentifier: "ViewController3") as! ViewController3
vc.delegate = self
self.navigationController?.pushViewController(vc, animated: true)
}
func recievePhoto(data: UIImage) {
thirdVCImage = data
imagefromThirdVC.image = thirdVCImage
}
}
SecondViewController:
import UIKit
protocol dataSentDelegate {
func goToThirdVC()
}
class ViewController2: UIViewController {
#IBOutlet weak var passingImage: UIImageView!
var delegate: dataSentDelegate? = nil
var images: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
images = UIImage(named: "screen")
}
#IBAction func actionButton(_ sender: Any) {
self.delegate?.goToThirdVC()
}
}
ThirdViewController:
import UIKit
protocol DataSentDelegate {
func recievePhoto(data: UIImage)
}
class ViewController3: UIViewController {
var delegate: DataSentDelegate? = nil
#IBOutlet weak var passedImageView: UIImageView!
var passedImage: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
passedImage = UIImage(named: "screen")
passedImageView.image = passedImage
}
#IBAction func action(_ sender: Any) {
let data = passedImageView.image
delegate?.recievePhoto(data: data!)
// delegate?.goToFirstVC()
guard let viewControllers = self.navigationController?.viewControllers else {
return
}
for firstViewController in viewControllers {
if firstViewController is ViewController {
self.navigationController?.popToViewController(firstViewController, animated: true)
break
}
}
}
}

How to pass data from one view controller to another?

How do I pass the data from an array of one view controller to another view controller?
FirstViewController:
var myArray = ["some data"]
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
let destinationVC = segue.destination as! SecondViewController
destinationVC.passedArray = myArray
}
SecondViewController:
var passedArray = [String]()
override func viewDidLoad(){
super.viewDidLoad()
print(passedArray)
}
You can try this Solution for Data Transfer.
In FirstViewController.swift
let str = "Hello It's Done"
func callsecondViewController()
{
let controller = storyboard?.instantiateViewController(withIdentifier: "second") as! secondViewController
self.present(controller, animated: true, completion: nil)
}
func temp() -> NSString
{
return str as NSString
}
in SecondViewController.swift
var data = [NSString]()
override func viewDidLoad()
{
super.viewDidLoad()
let view = ViewController()
data = [view.temp()]
print(data)
}
and you get the output String as Hello It's Done

Why can't I assign value on didSet?

I have two view. On my first view i create some data and send to other view lets name view2. So my view1 has code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showUserDetail" {
(segue.destinationViewController as! UserDetailTableViewController).detailContact = detailCoversationContact
}
}
In my detailCoversationContact i have detail about this one user, this detail like number, nick etc. Now as i expect this data are put to variable detailContact in my view2
And this is my cod in view2 this code is work:
class UserDetailTableViewController: UITableViewController {
#IBOutlet weak var nickNameLabel: UILabel!
var nickMy: String = ""
var detailContact: AnyObject? {
didSet {
// Update the user interface for the detail item.
if let detail = self.detailContact {
self.nickMy = (detail.valueForKey("nickName") as? String)!
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
nickNameLabel.text = nickMy
}
}
When i send data to detailContact' i check is didSet if yes i set my nickMy and this is work. But what is first ? setting my var or viewDidLoad?
this is my code and not working and can someone explain why ?
class UserDetailTableViewController: UITableViewController {
#IBOutlet weak var nickNameLabel: UILabel!
var detailContact: AnyObject? {
didSet {
// Update the user interface for the detail item.
if let detail = self.detailContact {
self.title = detail.valueForKey("nickName") as? String
self.nickNameLabel?.text = (detail.valueForKey("nickName") as? String)!
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
Ok this is self.title and work i see the name of user but title is from tableView. But my nickNameLabel is not change ? why ?
At the time of prepareForSegue, the IBOutlets have not been set up yet. So, self.nickNameLabel is still nil, and optional chaining makes self.nickNameLabel?.text = ... safely do nothing.
Set the value in viewDidLoad() when the IBOutlets have been set up:
override func viewDidLoad() {
super.viewDidLoad()
self.nickNameLabel?.text = (detail.valueForKey("nickName") as? String)!
}
Alternatively, you can trigger didSet by setting the detailContact to itself in viewDidLoad(). You have to trick Swift in order to do this because it thinks assigning detailContact to itself does nothing:
override func viewDidLoad() {
super.viewDidLoad()
detailContact = (detailContact) // trigger didSet to set up the label
}