for 循环 (Swift) 中的 onClick 事件不起作用
onClick event in a for loop (Swift) not working
使用 segue 在两个视图控制器之间共享数据在 for 循环中不起作用。我正在使用 Xcode9 和 Swift
swift4
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 [=11=].firstAttribute == attribute
{
removeConstraint([=11=])
}
}
}
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)
}
}
第二ViewController.swift
import UIKit
class SecondViewController: UIViewController {
@IBOutlet weak var label: UILabel!
var mystring = String()
override func viewDidLoad() {
super.viewDidLoad()
label.text=mystring
}
}
当我单击电影名称文本时,我希望使用 segue 将其显示在第二个视图中。
https://i.stack.imgur.com/dvm8j.png
但它始终显示最后一部电影的名称。请帮我解决这个问题。
https://i.stack.imgur.com/UqyqM.png
ViewController 中的 self.testtext 属性 设置不正确。每次调用 tapFunction() 时都应设置它。
我建议您以任何方式使用 UITabiewViewController 和一个数据源数组,该数组应包含要显示的所有元素。
您应该更新您的 tapFunction
@objc func tapFunction(sender:UITapGestureRecognizer) {
let touchedLabel = sender.view as! UILabel
self.testtext = touchedLabel.text
self.performSegue(withIdentifier: "Segue", sender: self)
}
希望对您有所帮助
编辑
现在你要传递多个值,你可以做的是:
首先将 for in 循环从
更改为
for distics in self.data1 {
到
for (index, distics) in self.data1.enumerated() {
现在,将标签设置为该行下方的标签
lbltiTle.addGestureRecognizer(tap)
// Add tag to your label
lbltiTle.tag = index
//**TIP: You should name the variables in camelCase format**
现在修改你的函数,它检测标签上的点击并获取带有索引的对象,该对象以标签的形式与标签一起传递。修改为.
@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)
}
您可以从中打印所需的值。
注意:对于纯 swift 方法,您应该避免使用 NSDictionary,最好使用 [String: Any] 这是一个键值对。
希望对您有所帮助
问题
那是因为您将 testtext
作为参数传递给下一个 ViewController.mystring
。 testtext
每次在循环中都被更改,最后一次更改是在最后一个元素上。因此你需要保存一个索引来知道你按下的位置。
解决方案
更改您的 for 循环以获取您正在迭代的元素的索引,如上
for index in 0..<self.data1.count {
let distics = self.data1[index]
// Other lines of code
lbltiTle.tag = index
}
如下更改您的处理程序
@objc func tapFunction(sender:UITapGestureRecognizer) {
print("tap working")
guard let index = sender.view?.tag,
let title = (self.data1[index] as? NSDictionary)["title"] else { return }
testtext = title
self.performSegue(withIdentifier: "Segue", sender: self)
}
为您的标签再添加一项功能。
lbltiTle.target(forAction: onClickLabel, withSender:)
定义 -
func onClickLabel(sender: UILabel) {
self.testtext = sender.text
}
在你的 tap 函数中调用它
使用 segue 在两个视图控制器之间共享数据在 for 循环中不起作用。我正在使用 Xcode9 和 Swift
swift4
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 [=11=].firstAttribute == attribute
{
removeConstraint([=11=])
}
}
}
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)
}
}
第二ViewController.swift
import UIKit
class SecondViewController: UIViewController {
@IBOutlet weak var label: UILabel!
var mystring = String()
override func viewDidLoad() {
super.viewDidLoad()
label.text=mystring
}
}
当我单击电影名称文本时,我希望使用 segue 将其显示在第二个视图中。
https://i.stack.imgur.com/dvm8j.png
但它始终显示最后一部电影的名称。请帮我解决这个问题。
https://i.stack.imgur.com/UqyqM.png
ViewController 中的 self.testtext 属性 设置不正确。每次调用 tapFunction() 时都应设置它。 我建议您以任何方式使用 UITabiewViewController 和一个数据源数组,该数组应包含要显示的所有元素。
您应该更新您的 tapFunction
@objc func tapFunction(sender:UITapGestureRecognizer) {
let touchedLabel = sender.view as! UILabel
self.testtext = touchedLabel.text
self.performSegue(withIdentifier: "Segue", sender: self)
}
希望对您有所帮助
编辑
现在你要传递多个值,你可以做的是:
首先将 for in 循环从
更改为for distics in self.data1 {
到
for (index, distics) in self.data1.enumerated() {
现在,将标签设置为该行下方的标签
lbltiTle.addGestureRecognizer(tap)
// Add tag to your label
lbltiTle.tag = index
//**TIP: You should name the variables in camelCase format**
现在修改你的函数,它检测标签上的点击并获取带有索引的对象,该对象以标签的形式与标签一起传递。修改为.
@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)
}
您可以从中打印所需的值。
注意:对于纯 swift 方法,您应该避免使用 NSDictionary,最好使用 [String: Any] 这是一个键值对。
希望对您有所帮助
问题
那是因为您将 testtext
作为参数传递给下一个 ViewController.mystring
。 testtext
每次在循环中都被更改,最后一次更改是在最后一个元素上。因此你需要保存一个索引来知道你按下的位置。
解决方案
更改您的 for 循环以获取您正在迭代的元素的索引,如上
for index in 0..<self.data1.count {
let distics = self.data1[index]
// Other lines of code
lbltiTle.tag = index
}
如下更改您的处理程序
@objc func tapFunction(sender:UITapGestureRecognizer) {
print("tap working")
guard let index = sender.view?.tag,
let title = (self.data1[index] as? NSDictionary)["title"] else { return }
testtext = title
self.performSegue(withIdentifier: "Segue", sender: self)
}
为您的标签再添加一项功能。
lbltiTle.target(forAction: onClickLabel, withSender:)
定义 -
func onClickLabel(sender: UILabel) {
self.testtext = sender.text
}
在你的 tap 函数中调用它