2014-12-07 42 views
1

我想要實現的是:當我點擊一個特定的UIImageView時,UITapGesture會傳遞一個字符串到tap方法中。Objective-C:傳遞一個字符串參數來挑選@selector

我的代碼如下所示:想象一下,我有一個的UIImageView對象有不已,當我點擊這個圖片,就會打個電話,

UITapGestureRecognizer *tapFirstGuy = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(makeCallToThisPerson:@"1234567")]; 
[imageViewOne addGestureRecognizer:tapFirstGuy]; 

- (void)makeCallToThisPerson:(NSString *)phoneNumber 
{ 
    NSString *phoneNum = [NSString stringWithFormat:@"tel:%@", phoneNumber]; 
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNum]]; 
} 

不過,我得到以下編譯錯誤:@selector(makeCallToThisPerson:@"1234567");

我無法確定發生了什麼。爲什麼我不能將字符串傳遞給私有方法?

+3

唯一可以傳遞的是手勢識別器本身,就像其他目標動作方法一樣。 – rdelmar 2014-12-07 23:11:11

+0

因爲選擇器換句話說是指向方法的指針,而不是指向閉包或塊。 – Andy 2014-12-07 23:11:46

回答

0

行動應該只是其簽名必須是「方法,需要一個單一的ID參數和返回無效」的方法選擇。參數將(通常)是發送消息的對象。

目標(所述動作被髮送到的對象)可以使用發件人參數來提取附加的信息,如果需要的,但必須要問的該附加信息。它不是免費提供的。

也就是說,你的ImageView的子類可能有這樣的方法:

- (void)setPhoneNumber:(NSString *)phoneNumber; // set a phoneNumber property 

- (void)prepareToBeTapped 
{ 
    UITapGestureRecognizer *tapFirstGuy = [[UITapGestureRecognizer alloc] 
     initWithTarget:self action:@selector(makeCallToThisPerson:)]; 
    [self addGestureRecognizer:tapFirstGuy]; 
} 

- (void)makeCallToThisPerson:(id)sender 
{ 
    NSString *phoneURL = [NSString stringWithFormat:@"tel:%@", phoneNumber]; 
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneURL]]; 
} 

也就是說,它不是行動甚至也沒有一個知道的電話號碼UITapGestureRecognizer。目標必須以其他方式知道(或能夠獲取)電話號碼,也許將其作爲可設置的屬性。

2

這是錯的,它不是一個有效的選擇器。

UITapGestureRecognizer *tapFirstGuy = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(makeCallToThisPerson:@"1234567")]; 

你需要改變這樣的:

UITapGestureRecognizer *tapFirstGuy = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(makeCallToThisPerson:)]; 

在你的方法參數將是tapGesture,就是這樣:

- (void)makeCallToThisPerson:(UITapGestureRecognizer *)tapGesture 

你可以做幾件事情,以pas參數:

1.-使用imageView的de標籤,tapGesture知道視圖,而不是它的附件d您可以使用標記視圖:

UITapGestureRecognizer *tapFirstGuy = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(makeCallToThisPerson:)]; 
     imageViewOne.tag = 1234567 
     [imageViewOne addGestureRecognizer:tapFirstGuy]; 

- (void)makeCallToThisPerson:(UITapGestureRecognizer *)tapGesture 
{ 
NSString *phoneNum = [NSString stringWithFormat:@"tel:%ld",tapGesture.view.tag]; 
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNum]]; 
} 

其他選項,子類化以便將NSString附加到imageView作爲新屬性。

+1

我同意Onik的文章中的所有內容,除了有關創建類別的內容。您不能將存儲添加到具有類別的對象。 – 2014-12-07 23:44:20

+0

@DuncanC是賴特。通過類別,你不能添加一個新的屬性(或實例變量)到一個存在的類,(我的答案是迅速和錯誤在這一點毫無疑問)。我修復了它。謝謝。 – 2014-12-08 08:32:35

1

@如果你想傳遞的值是一個整數,OnikIV的使用標籤的建議可以正常工作。

如果你想傳遞一個字符串,但它不會工作得很好。

您可以將標記設置爲唯一值,然後在手勢識別器的操作方法中,將標記值轉換爲NSNumber,並將其用作鍵在電話號碼字典中查找值。

另一種選擇是使用關聯存儲將字符串附加到圖像視圖。關聯存儲是一種技術,可讓您將鍵/值對連接到任意任意的NSObject。

我在github上有一個名爲AssociativeStorageDemo的示例項目,它展示瞭如何使用它。你可以嘗試寫的UITapGestureRecognizer子象下面這樣

2

另一種方式: -

@interface customTapGestureRecognizer : UITapGestureRecognizer 

@property (nonatomic, strong) NSString * phoneNumber; 

@end 


// customTapGestureRecognizer.m 

@implementation customTapGestureRecognizer 

@end 


// ===================== 

.... 

customTapGestureRecognizer *singleTap = [[customTapGestureRecognizer alloc] initWithTarget:self action:@selector(makeCallToThisPerson:)]; 

singleTap.phoneNumber = @"1234567"; 


-(void) makeCallToThisPerson:(UITapGestureRecognizer *)tapRecognizer { 

customTapGestureRecognizer *tap = (customTapGestureRecognizer *)tapRecognizer; 

NSLog(@"phoneNumber : %@", tap.phoneNumber); 

} 

注: - 寫作子類的好處是,你可以在你的UITapGestureRecognizer容易傳遞更多數據的數量。