I added a button on my custom tableViewCell and i want that after the button is tapped it pass data according to the cell on which the button is located, so to find out on which cell is the button i added a tag, but i'm getting this error
我在我的自定义tableViewCell上添加了一个按钮,我希望在按下按钮后根据按钮所在的单元格传递数据,以便找出哪个单元格是按钮我添加了标签,但我是得到这个错误
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.tag, section: 0)
let rev = segue.destination as! ReviewClass
}
}
How can i adjust it?
我该怎么调整呢?
(cell.reviewButton.tag = indexPath.row
) this is the tag i added in my cellForRowAt
(cell.reviewButton.tag = indexPath.row)这是我在cellForRowAt中添加的标签
UPDATE
UPDATE
this is the button action in my VC
这是我VC中的按钮操作
@IBAction func ReviewButtonTap(_ sender: UIButton) {
performSegue(withIdentifier: "goToReview" , sender: self)
}
and this is the outlet in my custom tableViewCell class
这是我的自定义tableViewCell类中的插座
@IBOutlet weak var reviewButton: UIButton!
i do not understand how can i associate this button with
我不明白我怎么能把这个按钮关联起来
else if segue.identifier == "goToReview", let button = sender as? UIButton, let rev = segue.destination as? ReviewClass {
let index3 = IndexPath(row: button.tag, section: 0)
5 个解决方案
#1
1
Force downcast the optional Any
to expected UIButton
and IndexPath
and use an else
clause instead of if
twice
强制将可选的Any转发给预期的UIButton和IndexPath,并使用else子句而不是两次
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
}
or use a switch
或使用开关
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
}
The code must not crash. If it does you made a design mistake.
代码不得崩溃。如果它确实你犯了设计错误。
Edit
编辑
You have to pass the UIButton
instance (the sender
) from the IBAction
to the sender
parameter of performSegue
. The outlet is irrelevant.
您必须将UIButton实例(发件人)从IBAction传递到performSegue的sender参数。出口是无关紧要的。
performSegue(withIdentifier: "goToReview" , sender: sender)
#2
1
It is common you will provide a sender as Any
in your method in cases where it can be different object. In such case you will need to typecast it to a specific object which is best done as let button = sender as? UIButton
in swift.
通常情况下,如果发送方可能是不同的对象,您将在方法中提供发送方为Any。在这种情况下,您需要将其类型转换为特定对象,最好将let button = sender作为? UIButton迅速。
By doing so you will receive an optional value and its tag would be button?.tag
and its type Int?
which then again disallows you to create an index path.
通过这样做,您将收到一个可选值,其标签将是按钮?.tag及其类型Int?然后再次禁止您创建索引路径。
So a proper way for this method should be as follows:
所以这种方法的正确方法应该如下:
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
}
}
Note that I have changed both if
statements and managed to even remove an extra force-unwrap (The !
thing). If you don't mind force-unwrapping which crashes your app when incorrect then you could as well just do:
请注意,我已经更改了两个if语句,甚至设法删除了额外的force-unwrap(The!thing)。如果您不介意在不正确的情况下强制解包会导致您的应用崩溃,那么您也可以这样做:
let index3 = IndexPath(row: (sender as! UIButton).tag, section: 0)
But I suggest you avoid all force-unwrapping to improve stability. For your case that would be:
但我建议你避免所有的力量展开以提高稳定性。对于你的情况,将是:
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
}
}
#3
0
Just you need to change your segue method with below method
只需要用下面的方法改变你的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
}
}
#4
0
For manage this problem first you need to first assign tag of button in cell for row which is you already done.
要首先管理此问题,您需要首先在单元格中为行已分配的按钮标记。
cell.reviewButton.tag = indexPath.row
After that you can add target actions on your button in the cell for row
之后,您可以在行的单元格中的按钮上添加目标操作
cell.reviewButton.addTarget(self, action:#selector(self.
func_Navigate(_:)), for:UIControlEvents.touchUpInside)
Out side cell for row make implement one function like that:-
用于行的外侧单元格实现如下功能: -
@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)
}
#5
0
You can get UIButton object from sender then UIButton object have tag property to access.
您可以从发件人获取UIButton对象,然后UIButton对象具有要访问的标记属性。
let button = sender as? UIButton
let index3 = IndexPath(row: button?.tag ?? 0, section: 0)
#1
1
Force downcast the optional Any
to expected UIButton
and IndexPath
and use an else
clause instead of if
twice
强制将可选的Any转发给预期的UIButton和IndexPath,并使用else子句而不是两次
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
}
or use a switch
或使用开关
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
}
The code must not crash. If it does you made a design mistake.
代码不得崩溃。如果它确实你犯了设计错误。
Edit
编辑
You have to pass the UIButton
instance (the sender
) from the IBAction
to the sender
parameter of performSegue
. The outlet is irrelevant.
您必须将UIButton实例(发件人)从IBAction传递到performSegue的sender参数。出口是无关紧要的。
performSegue(withIdentifier: "goToReview" , sender: sender)
#2
1
It is common you will provide a sender as Any
in your method in cases where it can be different object. In such case you will need to typecast it to a specific object which is best done as let button = sender as? UIButton
in swift.
通常情况下,如果发送方可能是不同的对象,您将在方法中提供发送方为Any。在这种情况下,您需要将其类型转换为特定对象,最好将let button = sender作为? UIButton迅速。
By doing so you will receive an optional value and its tag would be button?.tag
and its type Int?
which then again disallows you to create an index path.
通过这样做,您将收到一个可选值,其标签将是按钮?.tag及其类型Int?然后再次禁止您创建索引路径。
So a proper way for this method should be as follows:
所以这种方法的正确方法应该如下:
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
}
}
Note that I have changed both if
statements and managed to even remove an extra force-unwrap (The !
thing). If you don't mind force-unwrapping which crashes your app when incorrect then you could as well just do:
请注意,我已经更改了两个if语句,甚至设法删除了额外的force-unwrap(The!thing)。如果您不介意在不正确的情况下强制解包会导致您的应用崩溃,那么您也可以这样做:
let index3 = IndexPath(row: (sender as! UIButton).tag, section: 0)
But I suggest you avoid all force-unwrapping to improve stability. For your case that would be:
但我建议你避免所有的力量展开以提高稳定性。对于你的情况,将是:
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
}
}
#3
0
Just you need to change your segue method with below method
只需要用下面的方法改变你的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
}
}
#4
0
For manage this problem first you need to first assign tag of button in cell for row which is you already done.
要首先管理此问题,您需要首先在单元格中为行已分配的按钮标记。
cell.reviewButton.tag = indexPath.row
After that you can add target actions on your button in the cell for row
之后,您可以在行的单元格中的按钮上添加目标操作
cell.reviewButton.addTarget(self, action:#selector(self.
func_Navigate(_:)), for:UIControlEvents.touchUpInside)
Out side cell for row make implement one function like that:-
用于行的外侧单元格实现如下功能: -
@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)
}
#5
0
You can get UIButton object from sender then UIButton object have tag property to access.
您可以从发件人获取UIButton对象,然后UIButton对象具有要访问的标记属性。
let button = sender as? UIButton
let index3 = IndexPath(row: button?.tag ?? 0, section: 0)