如何知道 Swift 中的发件人标识符
How to know the sender's identifier in Swift
我有两个 UILabels
和两个 UITapGestureRecognizers
在 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)
}
我正在使用 Segue
推送另一个 UIViewController
,我正在重写 PrepareSegue
函数以发送与 Sender
标签相对应的所需信息.
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
}
我的问题是我想知道按下了哪个 UILabel
,因为我已经在使用 tag
。
你的 GoToProfile:
函数应该写对了。参数不是 "sender",而是手势识别器。
func GoToProfil (gestureRecognizer: UITapGestureRecognizer) {
}
从那里,您可以使用手势识别器的 view
属性 来确定标签。
但是您似乎有两个相互矛盾的要求。您想知道点击了两个标签中的哪一个,并且您想知道标签在哪一行。
通常您会使用标签的 tag
来了解点击了两个标签中的哪一个。但是您正在使用他们的标签来跟踪行。
我推荐的解决方案是使用标签来区分这两个标签。然后就可以根据label的frame计算行数了。
有关将单元格子视图的框架转换为单元格 indexPath
的示例代码,请参阅 。
您可以访问发件人数据,并读取发送给您的对象的标签,就像在这个示例代码中一样。
要唯一标识每一行和每个标签,您可以使用如下内容:
cell.Username.tag = (indexPath.row*2)
cell.SharedUser.tag = (indexPath.row*2)+1
有了这个,如果你有一个偶数标签,它的用户名,奇数将是共享用户。除以 2 的底数,你可以得到该行。
@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)
}
做出以下假设:
- 您正在尝试使用
UIView.tag
来唯一标识标签
- 您希望 Username 和 SharedUser 有不同的行为
我推荐如下,首先在你的#imports
下面定义你的标签
#define kUsername 1
#define kSharedUser 2
然后将它们分配给您的视图
cell.Username.tag = kUsername
cell.SharedUser.tag = kSharedUser
然后在你的 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
}
}
通过这种方式,您可以轻松简单地确定点击,请注意,如果您有超过 1 个用户名和共享用户标签,这可能会产生不同的结果。那么您将需要更多#defines 或更改生成标签的方式。
您可以向 UILabel 添加 属性 以跟踪标签的类型。 (我使用了一个枚举,因为只有两种情况,但它可以是一个字符串等)
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 )
}
}
}
现在你可以这样做了:
let label = UILabel()
label.labelDest = .Username
之后:
switch label.labelDest
{
case .Some(.Username):
// handle user name
break
...
如果您想在标签上使用 .tag 字段,您可以使用不同的技术来查找与标签关联的 table 行:(再次使用 class 扩展名)
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
}
}
现在,根据您的手势识别器操作:
func goToProfil( sender:UIGestureRecognizer! )
{
guard let tappedRow = sender.view?.tableRow else { return }
// handle tap here...
}
我有两个 UILabels
和两个 UITapGestureRecognizers
在 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)
}
我正在使用 Segue
推送另一个 UIViewController
,我正在重写 PrepareSegue
函数以发送与 Sender
标签相对应的所需信息.
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
}
我的问题是我想知道按下了哪个 UILabel
,因为我已经在使用 tag
。
你的 GoToProfile:
函数应该写对了。参数不是 "sender",而是手势识别器。
func GoToProfil (gestureRecognizer: UITapGestureRecognizer) {
}
从那里,您可以使用手势识别器的 view
属性 来确定标签。
但是您似乎有两个相互矛盾的要求。您想知道点击了两个标签中的哪一个,并且您想知道标签在哪一行。
通常您会使用标签的 tag
来了解点击了两个标签中的哪一个。但是您正在使用他们的标签来跟踪行。
我推荐的解决方案是使用标签来区分这两个标签。然后就可以根据label的frame计算行数了。
有关将单元格子视图的框架转换为单元格 indexPath
的示例代码,请参阅
您可以访问发件人数据,并读取发送给您的对象的标签,就像在这个示例代码中一样。
要唯一标识每一行和每个标签,您可以使用如下内容:
cell.Username.tag = (indexPath.row*2)
cell.SharedUser.tag = (indexPath.row*2)+1
有了这个,如果你有一个偶数标签,它的用户名,奇数将是共享用户。除以 2 的底数,你可以得到该行。
@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)
}
做出以下假设:
- 您正在尝试使用
UIView.tag
来唯一标识标签
- 您希望 Username 和 SharedUser 有不同的行为
我推荐如下,首先在你的#imports
下面定义你的标签#define kUsername 1
#define kSharedUser 2
然后将它们分配给您的视图
cell.Username.tag = kUsername
cell.SharedUser.tag = kSharedUser
然后在你的 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
}
}
通过这种方式,您可以轻松简单地确定点击,请注意,如果您有超过 1 个用户名和共享用户标签,这可能会产生不同的结果。那么您将需要更多#defines 或更改生成标签的方式。
您可以向 UILabel 添加 属性 以跟踪标签的类型。 (我使用了一个枚举,因为只有两种情况,但它可以是一个字符串等)
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 )
}
}
}
现在你可以这样做了:
let label = UILabel()
label.labelDest = .Username
之后:
switch label.labelDest
{
case .Some(.Username):
// handle user name
break
...
如果您想在标签上使用 .tag 字段,您可以使用不同的技术来查找与标签关联的 table 行:(再次使用 class 扩展名)
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
}
}
现在,根据您的手势识别器操作:
func goToProfil( sender:UIGestureRecognizer! )
{
guard let tappedRow = sender.view?.tableRow else { return }
// handle tap here...
}