for 循环中的 onClick 事件 (Swift) 不起作用



使用 segue 在两个视图控制器之间共享数据在 for 循环中不起作用。我正在使用 Xcode9 和 Swift

斯威夫特4

视图控制器.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)
}
}

第二视图控制器.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

你应该更新你的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] 这是一个键值对。

希望对你有帮助

ViewController 中的 self.testtext 属性未正确设置。每次调用tapFunction((时都应该设置它。 无论如何,我建议你使用 UITabiewViewController 和一个数据源数组,它应该容纳要显示的所有元素。

问题

这是因为您要testtext作为参数传递给下一个ViewController.mystringtesttext每次在循环中都会更改,最后一次更改时,它在最后一个元素上。因此,您需要保存索引以了解按下的位置。

溶液

更改 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
}

在点击函数中调用它

最新更新