识别带有String的按钮

时间:2013-12-10 10:57:48

标签: objective-c

我读过,当你想要识别一个被点击的按钮时,你可以简单地使用

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

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

并且它说了一些子类,但我对Objective-C相当新,所以我不知道这是不是为了初学者呢!

在用户@Greg的建议

之后编辑代码
//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);

}

3 个答案:

答案 0 :(得分: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

更新

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

那么您希望能够访问您在其他方法中完成的按钮吗?

好吧,让我们改进上面的代码。不是将nameTag应用于UIButton,而是将其应用于UIView继承的UIButton。这样,我们就可以将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,我们就可以将UIButton nameTag设置为:

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

的更多信息

如果您还需要,请询问。

答案 1 :(得分:0)

标记只能是一个整数,如果你需要使用NSString作为标识符,你必须继承UIButton,添加一个名为buttonID的新NSString属性(例如)并使用该按钮。

答案 2 :(得分: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];

你仍然可以使用tag属性。

// EXTENDED

你不能使用像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;
        }
    }
}

希望得到这个帮助。