问题
I have two UILabels
with two UITapGestureRecognizers
in a UITableViewCell
.
cell.Username.tag = indexPath.row
cell.SharedUser.tag = indexPath.row
let tapGestureRecognizer2 = UITapGestureRecognizer(target:self, action:"GoToProfil:")
let tapGestureRecognizer3 = UITapGestureRecognizer(target:self, action:"GoToProfil:")
cell.Username.userInteractionEnabled = true
cell.Username.addGestureRecognizer(tapGestureRecognizer2)
cell.SharedUser.userInteractionEnabled = true
cell.SharedUser.addGestureRecognizer(tapGestureRecognizer3)
func GoToProfil (sender: AnyObject!) {
self.performSegueWithIdentifier("GoToProfilSegue", sender: sender)
}
I'm using a Segue
to push another UIViewController
, and I'm overriding the PrepareSegue
function to send the needed information corresponding to the Sender
tag.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
let ProfilView = segue.destinationViewController as! Profil
ProfilView.hidesBottomBarWhenPushed = true
ProfilView.title = posts[sender.view!.tag].User?.objectForKey("Name") as? String
ProfilView.User = posts[sender.view!.tag].User
}
My problem is that I want to know which UILabel
was pressed, knowing that I'm already using tag
.
回答1:
Your GoToProfile:
function should be written properly. The parameter isn't the "sender", it's the gesture recognizer.
func GoToProfil (gestureRecognizer: UITapGestureRecognizer) {
}
From there, you can determine the label by using the view
property of the gesture recognizer.
But you seem to have two conflicting requirements. You want to know which of the two labels was tapped and you want to know which row the label is in.
Normally you would use the label's tag
to know which of the two labels was tapped. But you are using their tags to track the row.
The solution I recommend is to use the tag to differentiate the two labels. Then you can calculate the row based on the frame of the label.
See the following answer for sample code that translates the frame of a cell's subview to the cell's indexPath
.
回答2:
Making the following assumptions:
- You are trying to uniquely identify the label using
UIView.tag
- You want different behaviour for Username & SharedUser
I recommend the following, first define your tags below your #imports
#define kUsername 1
#define kSharedUser 2
Then assign them to your views
cell.Username.tag = kUsername
cell.SharedUser.tag = kSharedUser
Then in your prepareSegue
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
int tag = [sender.view!.tag]
if (tag == kUsername) {
//Username logic
} else if(tag == kSharedUser) {
//Shared User Logic
}
}
This way you can easily and simply determine tap, Note this might have different results if you have more then 1 Username & SharedUser labels. Then you will either need more #defines or change how you generate your tags.
回答3:
You can add a property to UILabel to track the label's type. (I used an enum since there's just 2 cases, but it could be a string, etc.)
enum LabelDest : String
{
case Username = "Username"
case SharedUser = "SharedUser"
}
extension UILabel
{
struct Static {
static var key = "labelDest"
}
var labelDest:LabelDest? {
set { objc_setAssociatedObject( self, &Static.key, newValue?.rawValue, .OBJC_ASSOCIATION_COPY_NONATOMIC )
}
get {
guard let val = objc_getAssociatedObject( self, &Static.key ) as? String else { return nil }
return LabelDest( rawValue:val )
}
}
}
Now you can just do this:
let label = UILabel()
label.labelDest = .Username
Later:
switch label.labelDest
{
case .Some(.Username):
// handle user name
break
...
If you want to use the .tag field on your labels you can use a different technique to find the table row associated with a label: (again using class extensions)
extension UIView
{
var enclosingTableViewCell:UITableViewCell? {
return superview?.enclosingTableViewCell
}
var enclosingTableView:UITableView? {
return superview?.enclosingTableView
}
}
extension UITableViewCell
{
var enclosingTableViewCell:UITableViewCell? {
return self
}
}
extension UITableView
{
var enclosingTableView:UITableView? {
return self
}
}
extension UIView {
var tableRow:Int? {
guard let cell = self.enclosingTableViewCell else { return nil }
return self.enclosingTableView?.indexPathForCell( cell )?.row
}
}
Now, from your gesture recognizer action:
func goToProfil( sender:UIGestureRecognizer! )
{
guard let tappedRow = sender.view?.tableRow else { return }
// handle tap here...
}
回答4:
You can access the sender data, and read the tag of the object that send you, like in this sample code.
To uniquely identify each row and each label, you can use something like this:
cell.Username.tag = (indexPath.row*2)
cell.SharedUser.tag = (indexPath.row*2)+1
With this, if you have a even tag, its the Username, odd will be the SharedUser. Dividing by the floor of 2 you can have the row back.
@IBOutlet weak var test1: UILabel!
@IBOutlet weak var test2: UILabel!
override func viewWillAppear(animated: Bool) {
test1.tag = 1
test2.tag = 2
test1.userInteractionEnabled = true
test2.userInteractionEnabled = true
self.test1.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "handleSingleTap:"))
self.test2.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "handleSingleTap:"))
}
func handleSingleTap(sender: UITapGestureRecognizer) {
print(sender.view?.tag)
}
来源:https://stackoverflow.com/questions/35280424/how-to-know-the-senders-identifier-in-swift