Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 类型为'的值;任何?';没有成员';标签';_Ios_Swift_Uitableview_Swift4 - Fatal编程技术网

Ios 类型为'的值;任何?';没有成员';标签';

Ios 类型为'的值;任何?';没有成员';标签';,ios,swift,uitableview,swift4,Ios,Swift,Uitableview,Swift4,我在我的自定义tableViewCell上添加了一个按钮,我想在点击按钮后,它会根据按钮所在的单元格传递数据,所以为了找出按钮所在的单元格,我添加了一个标记,但我得到了这个错误 我如何调整它 (cell.reviewButton.tag=indexPath.row)这是我在cellForRowAt中添加的标记 更新 这是我的VC中的按钮操作 @IBAction func ReviewButtonTap(_ sender: UIButton) { performSegue(wi

我在我的自定义tableViewCell上添加了一个按钮,我想在点击按钮后,它会根据按钮所在的单元格传递数据,所以为了找出按钮所在的单元格,我添加了一个标记,但我得到了这个错误

我如何调整它

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)
}