Search code examples
objective-cswiftuiviewnsstringviewwithtag

Can I customize existing viewWithTag:(NSInteger) method for stringTag?


Please help me, I have been customizing a UIView class to set NSString value as a tag, but how can I get that view from view hierarchy.In UIView class default method to get view is viewWithTag:(NSInteger).

Please see below code

#import <UIKit/UIKit.h>
@interface UIView (StringTag)
@property (nonatomic, copy) NSString *tagString;
@end

#import "UIView+StringTag.h"
#import <objc/runtime.h> 

static const void *tagKey = &tagKey;

@implementation UIView (StringTag)

- (void)setTagString:(NSString *)tagString
{
objc_setAssociatedObject(self, tagKey, tagString,OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (id)tagString
{
return objc_getAssociatedObject(self, tagKey);
}
@end

I want a method like viewWithStringTag:(NSString *)stringTag.

Thanks,


Solution

  • Use recursive search, includes self

    #import <UIKit/UIKit.h>    
    
    @interface UIView (StringTag)
    @property (nonatomic, copy) NSString *tagString;    
    
    - (UIView *)viewWithStringTag:(NSString *)strTag;    
    
    @end    
    
    #import "UIView+StringTag.h"
    #import <objc/runtime.h>     
    
    static const void *tagKey = &tagKey;    
    
    @implementation UIView (StringTag)    
    
    - (void)setTagString:(NSString *)tagString
    {
        objc_setAssociatedObject(self, tagKey, tagString,OBJC_ASSOCIATION_COPY_NONATOMIC);
    }    
    
    - (id)tagString
    {
        return objc_getAssociatedObject(self, tagKey);
    }    
    
    - (UIView *)viewWithStringTag:(NSString *)strTag{
        if ([self.tagString isEqual:strTag]){
            return self;
        }
        if (!self.subviews.count){
            return nil;
        }
        for (UIView *subview in self.subviews){
            UIView *targetView = [subview viewWithStringTag:strTag];
            if (targetView){
                return targetView;
            }
        }
        return nil;
    }    
    
    @end
    

    Here are my testing code

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        UIView *aView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
        aView.tagString = @"aView";
        UIView *bView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
        bView.tagString = @"bView";
        [self.view addSubview:aView];
        [aView addSubview:bView];
    
        UIView *targetView = [self.view viewWithStringTag:@"bView"];
    
        NSLog(@"%@", targetView);
        // <UIView: 0x7f933bc21e50; frame = (0 0; 100 100); layer = <CALayer: 0x7f933bc1c430>>
    }