2013-12-10 235 views
0

我读过,当你想找出被点击一个按钮,你可以简单地使用识别与字符串

button.tag = 10作为一个例子按钮。我现在遇到的问题是,我需要使用字符串作为标识符,因为id来自服务器,它使用标识符中的单词和数字来使其唯一。我现在遇到的问题是,我现在不知道该如何识别按钮,因为标签只用于整数。我不能只是迭代它,因为它必须是完全动态的。将要走什么路?

我读过这个链接在这里 How to pass a string as a tag of UIButton

和它说子类的东西,但我是相当新的Objective-C的,所以我不知道,如果这对haard初学者!从用户@格雷格建议后

编辑代码

//Class: CustomButton.h 
@interface CustomButton : UIButton 
@property (nonatomic, retain) NSString *stringTag; 
@end 

//Class: MainViewController.m 
#import "CustomButton.h" 
//code 
CustomButton *testButton = [CustomButton buttonWithType:UIButtonTypeRoundedRect]; 
testButton.frame   = CGRectMake(15.0f, _counterForLists, 250.0f, 30.0f ); 

[testButton addTarget   :self action:@selector(deleteListItem:) forControlEvents:UIControlEventTouchUpInside]; 
[testButton setBackgroundColor :[UIColor blackColor]]; 
[testButton setTitleColor  :[UIColor whiteColor] forState:UIControlStateNormal]; 
[testButton setTitle   :[projectData description] forState:UIControlStateNormal]; 

testButton.stringTag = @"TEST"; 
_counterForLists += 30; 
[self.view addSubview:testButton  ]; 

//Method deleteListItem (When I press the button it crashes) 

- (void)deleteListItem:(CustomButton *)sender{ 
    NSLog(@"Button clicked with ID: %@", sender.stringTag); 

} 
+0

'NSDictionary'? – 2013-12-10 10:58:39

回答

0

您可以创建的UIButton的子类,并添加标识属性:

@interface MyButton : UIButton 
@property (nonatomic, strong) NSString *tagAsString; 
@end 

而且每一个地方,你使用的UIButton与myButton的更换,比如时间: 旧代码

UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    [btn setFrame:CGRectMake(0.0f, 0.0f, 50, 30)]; 
    [btn setTitle:@"Your title" forState:UIControlStateNormal]; 
    btn.tag = 1; 
    [btn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; 
    [self.view btn]; 

有:

 MyButton *btn = [MyButton buttonWithType:UIButtonTypeRoundedRect]; 
     [btn setFrame:CGRectMake(0.0f, 0.0f, 50, 30)]; 
     [btn setTitle:@"Your title" forState:UIControlStateNormal]; 
     btn.tagAsString = @"string as a identifier"; 
     [btn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; 
     [self.view btn]; 

而且你仍然可以使用标签属性。

//扩展

您不能使用标准的方法,像viewWithTag :,你应该创建自己的,例如:

-(MyButton*)buttonForTag:(NSString*)tagAsString 
{ 
    for (UIView *v in self.view.subviews) 
    { 
     if ([v isKindOfClass:[MyButton class]]) 
     { 
      MyButton *btn = (MyButton*)v; 
      if ([btn.tagAsString isEqualToString:tagAsString]) 
       return btn; 
     } 
    } 
} 

希望这有助于。

+0

嗨。谢谢。这似乎很容易!我现在已经完成了。但现在,当我有另一个按钮,删除一个依赖于ID的按钮。我会怎么做?只需使用我正在搜索的tagAsString搜索按钮?或者究竟是什么?那我该如何比较呢? – NewToObjectiveC

+0

要读取标识符,您可以使用btn.tagAsString。您可以将其作为NSString进行比较,如果需要,您可以根据比较结果删除按钮。 – Greg

+0

嗯,很奇怪。我照你说的做了。将该属性添加到我也在ViewController.m中导入的接口中,并使用CustomButton而不是UIButton,但它给了我一个例外。原因是什么? 由于未捕获的异常'NSInvalidArgumentException',原因:' - [UIButton setStringTag:]:无法识别的选择器发送到实例0xa7e2ee0' 终止应用程序是否因为我的标识符以'-'开头?如果是的话,我该如何逃避? – NewToObjectiveC

0

标签只能是一个整数,如果你需要使用的NSString作为标识你的子类的UIButton,添加一个新的NSString属性称为buttonID(例如)并使用该按钮。

2

无需创建子类UIButton如果我们只是通过执行以下操作将我们只要创建一个新的类别的新属性为UIButton一个全新的类:

的UIButton + properties_cat.h

#import <UIKit/UIButton.h> 
#import <objc/runtime.h> 

@interface UIButton (properties_cat) 

@property (nonatomic, strong) NSString *nameTag; 

@end 

UIButton + properties_cat。^ h

#import "UIButton+properties_cat.h" 

@implementation UIButton (properties_cat) 

// We can't use synthesize with categories so we have to use dynamic. 
@dynamic nameTag;  

#pragma mark - Setters and Getters for nameTag Property 
- (void)setNameTag:(NSString *)nameTag 
{ 
    objc_setAssociatedObject(self, @"nameTag", nameTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
} 

- (NSString *)nameTag 
{ 
    return objc_getAssociatedObject(self, @"nameTag"); 
} 

@end 

然后确保通过做#import "UIButton+properties_cat.h"

导入新的类到您的代码一旦我们有#imported它,我们现在可以在课堂上使用它像这样

UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
[btn setNameTag:@"my button name"]; 

注意我们仍在使用UIButton而不是创建一个毫无意义的新课程,如MyButton我们刚刚将新属性(nameTag)添加到现有的UIButton课程中。

UPDATE

这是基于另一个答案评论的更新。

因此,您希望能够访问您在另一种方法中完成的按钮?

好吧,让我们改进上面的代码。我们可以将nameTag应用于UIButton,而不是将其应用于UIButton继承的UIView。于是,这将允许我们申请nameTag任何东西,从UIView继承 - UILabelUIButton

我们也想实现一个名为viewWithName:新方法,这将工作方式相同viewWithTag:除了它会检查nameTag代替tag

所以请尝试使用下面的代码:

的UIView + cat.h

#import <UIKit/UIView.h> 
#import <objc/runtime.h> 

@interface UIView (cat) 

@property (nonatomic, strong) NSString *nameTag; 

- (UIView *)viewWithName:(NSString *)name; 

@end 

的UIView + cat.m

#import "UIView+cat.h" 

@implementation UIView (cat) 

@dynamic nameTag; 

#pragma mark - viewWithName: method 

- (UIView *)viewWithName:(NSString *)name 
{ 
    for(id view in [self subviews]) { 
     // This if statement checks that the view is an instance of UIView class 
     // or inherits from it, so it should return true if like UILabel. 
     if([view isKindOfClass:[UIView class]]) { 
      if([[view nameTag] isEqualToString:name]) { 
       // This will return the first view that it comes across with the nameTag that equals name 
       return view; 
      } 
     } 
    } 
    return nil; 
} 

#pragma mark - Setters and Getters for nameTag Property 
- (void)setNameTag:(NSString *)nameTag 
{ 
    objc_setAssociatedObject(self, @"nameTag", nameTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
} 

- (NSString *)nameTag 
{ 
    return objc_getAssociatedObject(self, @"nameTag"); 
} 

@end 

现在,而不是导入UIButton+properties_cat.h我们需要导入UIView+cat.h这是因为我们不需要创建UIButton+properties_cat.h,因为UIButton继承自UIView所以它不会我选择新的属性和方法。

所以一旦我们导入UIView+cat.h我们就可以设置我们UIButtonnameTag像:

UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
[btn setNameTag:@"my button name"]; 

然后在另一种方法,我们希望访问按钮,我们可以做

UIButton *btn = (UIButton *)[[self view] viewWithName:@"my button name"]; 

我们增加因为viewWithName:将会返回一个UIView我们想确保它是UIButton的一个实例。在Customizing Classes with Categories

如果您需要任何更多的只是问

更多信息。

+0

+1。但我已经用格雷格的回答解决了它。无论如何,你的看起来非常好,合乎逻辑,因为我不需要创建子类。但是我甚至不知道你用'UIButton + properties_cat.h'表示你的意思,但是谢谢! – NewToObjectiveC

+0

这只是命名文件的惯例。 'UIButton'因为你添加到'UIButton'和'properties_cat',因为'properties_cat'是你的新类别的名字,所以文件名会变成'UIButton + properties_cat.h',你可以任意命名它,会这样做。 – Popeye

+0

嗨,是的,这是我理解的部分。我不明白的部分是,我在哪里创建这些文件,以及如何创建它们,或者我在哪里编写这些文件。我只是创建一个新文件并将其命名为UIButton + properties_cat.h?这是我不明白的部分!我是新来的。对不起! – NewToObjectiveC