Ios 类型为'的值;任何?';没有成员';标签';
我在我的自定义tableViewCell上添加了一个按钮,我想在点击按钮后,它会根据按钮所在的单元格传递数据,所以为了找出按钮所在的单元格,我添加了一个标记,但我得到了这个错误 我如何调整它 (Ios 类型为'的值;任何?';没有成员';标签';,ios,swift,uitableview,swift4,Ios,Swift,Uitableview,Swift4,我在我的自定义tableViewCell上添加了一个按钮,我想在点击按钮后,它会根据按钮所在的单元格传递数据,所以为了找出按钮所在的单元格,我添加了一个标记,但我得到了这个错误 我如何调整它 (cell.reviewButton.tag=indexPath.row)这是我在cellForRowAt中添加的标记 更新 这是我的VC中的按钮操作 @IBAction func ReviewButtonTap(_ sender: UIButton) { performSegue(wi
cell.reviewButton.tag=indexPath.row
)这是我在cellForRowAt中添加的标记
更新
这是我的VC中的按钮操作
@IBAction func ReviewButtonTap(_ sender: UIButton) {
performSegue(withIdentifier: "goToReview" , sender: self)
}
这是我自定义tableViewCell类中的插座
@IBOutlet weak var reviewButton: UIButton!
我不明白如何将此按钮与
else if segue.identifier == "goToReview", let button = sender as? UIButton, let rev = segue.destination as? ReviewClass {
let index3 = IndexPath(row: button.tag, section: 0)
您可以从发送方获取UIButton对象,然后UIButton对象具有要访问的标记属性
let button = sender as? UIButton
let index3 = IndexPath(row: button?.tag ?? 0, section: 0)
强制将可选的
Any
向下转换为预期的ui按钮
和indepath
,并使用else
子句代替if
两次
if segue.identifier == "goToLast" {
let dvc = segue.destination as! FinalClass
let indexPath = sender as! IndexPath
dvc.index = indexPath.row
dvc.places = sortedArray
dvc.userLocation = currentLocation
}
else if segue.identifier == "goToReview" {
let button = sender as! UIButton
let index3 = IndexPath(row: button.tag, section: 0)
let rev = segue.destination as! ReviewClass
}
或者使用开关
switch segue.identifier {
case "goToLast":
let dvc = segue.destination as! FinalClass
let indexPath = sender as! IndexPath
dvc.index = indexPath.row
dvc.places = sortedArray
dvc.userLocation = currentLocation
case "goToReview":
let button = sender as! UIButton
let index3 = IndexPath(row: button.tag, section: 0)
let rev = segue.destination as! ReviewClass
default: break
}
代码不得崩溃。如果是这样,你就犯了一个设计错误
编辑
您必须将ui按钮
实例(sender
)从iAction
传递到performsgue
的sender
参数。出口无关紧要
performSegue(withIdentifier: "goToReview" , sender: sender)
通常情况下,如果发送者可以是不同的对象,则在方法中提供发送者作为
Any
。在这种情况下,您需要将其类型转换为一个特定的对象,最好按照let button=sender as?UISWIFT中的按钮
通过这样做,您将收到一个可选值,它的标记将是button?.tag
及其类型Int?
,这同样不允许您创建索引路径
因此,该方法的正确方法应如下所示:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToLast", let indexPath = sender as? IndexPath {
let dvc = segue.destination as! FinalClass
dvc.index = indexPath.row
dvc.places = sortedArray
dvc.userLocation = currentLocation
} else if segue.identifier == "goToReview", let button = sender as? UIButton {
let index3 = IndexPath(row: button.tag, section: 0)
let rev = segue.destination as! ReviewClass
}
}
请注意,我已经更改了两个if
语句,甚至成功地删除了一个额外的力展开(这是!
的事情)。如果您不介意强制展开,当不正确时会导致应用程序崩溃,那么您也可以执行以下操作:
let index3 = IndexPath(row: (sender as! UIButton).tag, section: 0)
但我建议您避免所有强制展开,以提高稳定性。对于您的情况,这将是:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToLast", let indexPath = sender as? IndexPath, let dvc = segue.destination as? FinalClass {
dvc.index = indexPath.row
dvc.places = sortedArray
dvc.userLocation = currentLocation
} else if segue.identifier == "goToReview", let button = sender as? UIButton, let rev = segue.destination as? ReviewClass {
let index3 = IndexPath(row: button.tag, section: 0)
} else {
print("ERROR: Incorrect configuration!") // Put a breakpoint here and analyze what was the identifier and what the sender so none of the statements were hit
}
}
你只需要用下面的方法改变你的segue方法
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToLast" && sender is IndexPath {
let dvc = segue.destination as! FinalClass
dvc.index = (sender as! IndexPath).row
dvc.places = sortedArray
dvc.userLocation = currentLocation
}
if segue.identifier == "goToReview" {
let index3 = IndexPath(row: (sender as! UIButton).tag, section: 0)
let rev = segue.destination as! ReviewClass
}
}
为了首先管理这个问题,您需要首先为行分配单元格中按钮的标记,这是您已经完成的
cell.reviewButton.tag = indexPath.row
之后,您可以在行的单元格中的按钮上添加目标操作
cell.reviewButton.addTarget(self, action:#selector(self.
func_Navigate(_:)), for:UIControlEvents.touchUpInside)
row make的外侧单元格实现如下功能:-
@IBAction func func_Navigate(_ sender: UIButton)
{
If sender.tag == 0
{
\\ here sender.tag = 0 means button belong from fist row of your table view. you can perform navigation like that :-
self.performSegue(withIdentifier: "goToLast", sender: self)
}
else If sender.tag == 1
{
\\ here sender.tag = 1 means button belong from second row of your table view. you can perform navigation like that :-
self.performSegue(withIdentifier: "goToReview", sender: self)
}
将发件人转换为button,然后获取button标签。即使您可以在用户点击按钮时全局存储所选索引,而不是在segue中获取索引。这是编写代码的正确方法。您需要强制转换为UIButton,然后才能使用.tag。索引路径中不能有可选整数。所以可能
IndexPath(行:button?.tag±0,节:0)
默认为0。但这毫无意义,这是一个需要处理的异常。好吧,但有一个问题,@IBAction func reviewbuttonap(u发件人:UIButton){performsgue(带有标识符:“goToReview”,发件人:self)}这是我的按钮,我还必须定义一个出口吗?编译器如何将let按钮与此函数关联?我假设您在某个地方调用performsgue
,并传递标识符和按钮。在这种情况下,强制展开是完全正确的(甚至是推荐的)。如果它崩溃,它将显示一个设计错误。如果在Interface Builder中所有内容都正确连接,则代码不得崩溃。在最坏的情况下,使用第一个语法,代码什么也不做(不执行分段),您也不知道为什么。Matic我更新了问题,因为我不理解thing@vadian完全同意这个案子,这就是为什么我发布了两个版本,并且在非崩溃版本上添加了错误的打印,以便您知道这就是发生的情况。但我不同意你通常应该这么做。对于某些配置,可能未安装插座,或者该插座已被弃用,因此应进行检查。你可以相信我的话,在持续发展中,你最好避免强行展开。@fisher你问题的编辑部分似乎与原文无关。由于vadian已经更新,您需要将按钮而不是“self”发送到调用中,以执行性能检查。至于“不了解一件事”,你最好看看一些教程或一些介绍iOS应用程序开发的原始基础知识的东西。好的,在func navigate的操作中,我将添加performSegue(带有标识符:“goToReview”,发件人:发件人),对吗?在我的func prepare(功能准备)中,我如何判断按钮被按下在哪一行?
@IBAction func func_Navigate(_ sender: UIButton)
{
If sender.tag == 0
{
\\ here sender.tag = 0 means button belong from fist row of your table view. you can perform navigation like that :-
self.performSegue(withIdentifier: "goToLast", sender: self)
}
else If sender.tag == 1
{
\\ here sender.tag = 1 means button belong from second row of your table view. you can perform navigation like that :-
self.performSegue(withIdentifier: "goToReview", sender: self)
}