Data sharing between two view controllers by using segue is not working in for loop. I am using Xcode9 and Swift
ViewController.swift
import UIKit
import SwiftyJSON
import Alamofire
class ViewController: UIViewController {
var distnames = [String]()
var distcodes = [String]()
var data1: [AnyObject] = []
var values = [String]()
var values1 = [String]()
var current_arr :[String] = []
var ofcnames = " ";
var ofccodes = " ";
var code = " ";
var testtext = "";
var id = "";
var tiTle = "";
var releaseYear = "";
@IBOutlet weak var Verticalstackview: UIStackView!
@IBOutlet weak var scrollview: UIScrollView!
@IBOutlet weak var testlabel: UILabel!
@IBOutlet weak var mainView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
print("code is \(code)")
self.values = [String]()
self.values1 = [String]()
self.ofcnames = "";
self.ofccodes = "";
Alamofire.request("https://facebook.github.io/react-native/movies.json")
.responseJSON { (response) in
if ((response.result.value) != nil) {
let jsondata = JSON(response.result.value!)
// print(jsondata)
if let da = jsondata["movies"].arrayObject
{
self.data1 = da as [AnyObject]
print("resp is \(da) ")
}
print("respcode count is \(self.data1.count) ")
self.Verticalstackview.height(constant: 40)
self.mainView.height(constant: CGFloat(40 * self.data1.count))
self.scrollview.height(constant: CGFloat(40 * self.data1.count))
for distics in self.data1 {
if let resp = distics as? NSDictionary {
self.id = resp["id"] as! String
self.tiTle = resp["title"] as! String
self.releaseYear = resp["releaseYear"] as! String
let stackView = UIStackView()
stackView.height(constant: 40)
stackView.distribution = .fill
stackView.alignment = .fill
stackView.axis = .horizontal
stackView.spacing = 5
let lblId = UILabel()
lblId .text = "\(self.id)"
lblId .font = UIFont(name: "verdana", size: 15.0)
lblId .textAlignment = .center
lblId .textColor = .gray
lblId .numberOfLines = 0
lblId .width(constant: 55)
let lbltiTle = UILabel()
lbltiTle.text = "\(self.tiTle)"
lbltiTle.font = UIFont(name: "verdana", size: 15.0)
lbltiTle.textAlignment = .left
lbltiTle.textColor = .black
lbltiTle.numberOfLines = 0
lbltiTle.width(constant: 120)
let tap = UITapGestureRecognizer.init(target:self,action: #selector(self.tapFunction) )
lbltiTle.isUserInteractionEnabled = true
lbltiTle.addGestureRecognizer(tap)
self.testtext = lbltiTle.text!
let lblRYear = UILabel()
lblRYear.text = "\(self.releaseYear)"
lblRYear.font = UIFont(name: "verdana", size: 15.0)
lblRYear.textAlignment = .right
lblRYear.textColor = .black
lblRYear.numberOfLines = 0
lblRYear.width(constant: 100)
stackView.addArrangedSubview(lblId )
stackView.addArrangedSubview(lbltiTle)
stackView.addArrangedSubview(lblRYear)
self.Verticalstackview.addArrangedSubview(stackView)
}
}
}
print(self.values1)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@objc func tapFunction(sender:UITapGestureRecognizer) {
print("tap working")
self.performSegue(withIdentifier: "Segue", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let secondcntroller = segue.destination as! SecondViewController
secondcntroller.mystring = self.testtext
}
}
extension UIView{
func height(constant : CGFloat){
setConstraint(value: constant,attribute: .height)
}
func width(constant : CGFloat){
setConstraint(value: constant,attribute: .width)
}
private func removeConstraint(attribute: NSLayoutAttribute){
constraints.forEach {
if $0.firstAttribute == attribute
{
removeConstraint($0)
}
}
}
private func setConstraint(value:CGFloat ,attribute: NSLayoutAttribute){
removeConstraint(attribute: attribute)
let Constraint =
NSLayoutConstraint(item: self,
attribute: attribute,
relatedBy: NSLayoutRelation.equal,
toItem: nil,
attribute: NSLayoutAttribute.notAnAttribute,
multiplier: 1,
constant: value)
self.addConstraint(Constraint)
}
}
SecondViewController.swift
import UIKit
class SecondViewController: UIViewController {
@IBOutlet weak var label: UILabel!
var mystring = String()
override func viewDidLoad() {
super.viewDidLoad()
label.text=mystring
}
}
When I click the movie name text, I want that to be displayed on the second view using segue.
https://i.sstatic.net/dvm8j.png
But always it displays the last movie name. Please assist me sorting this issue.
https://i.sstatic.net/UqyqM.png
You should update your tapFunction
@objc func tapFunction(sender:UITapGestureRecognizer) {
let touchedLabel = sender.view as! UILabel
self.testtext = touchedLabel.text
self.performSegue(withIdentifier: "Segue", sender: self)
}
Hope it helps
EDIT
Now as you wants to pass the multiple values, what you can do is:
First change your for in loop from
for distics in self.data1 {
To
for (index, distics) in self.data1.enumerated() {
Now, set the tag to your label below this line
lbltiTle.addGestureRecognizer(tap)
// Add tag to your label
lbltiTle.tag = index
//**TIP: You should name the variables in camelCase format**
Now modify your function, that detects the tap on label and get the object with index being passed with the label in form of it's tag. Modify it to.
@objc func tapFunction(sender:UITapGestureRecognizer) {
let touchedLabel = sender.view as! UILabel
let touchedIndex = touchedLabel.tag
let selectedDict: NSDictionary = self.data1[touchedIndex]
print("selectedDict:\(selectedDict)")
self.performSegue(withIdentifier: "Segue", sender: self)
}
You can print the required values from it.
NOTE: For the pure swift approach, you should Avoid using NSDictionary, better use [String: Any] which is a key value pair.
Hope it helps