之前的文章介绍过如何使用UIView
的tag
属性保存额外的信息,并且根据这些信息处理它的点击事件。这个方案有很多缺陷和限制,遂将其改造为使用associatedObject
的方式,从根本上解决了这些限制和缺陷。完整代码如下:
//
// UIView+ExtraTag.h
// YiShop
//
// Created by 宗仁 on 16/6/8.
// Copyright © 2016年 宗仁 All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIView (ExtraTag)
/**
* viewType为view的类别,例如商品、店铺等
*/
- (void)setViewTypeForTag:(NSInteger)viewType;
/**
* position一般为view在列表中的row number
*/
- (void)setPositionForTag:(NSInteger)position;
/**
* section一般为view在列表中section number
*/
- (void)setSectionForTag:(NSInteger)section;
/**
* extraInfo一般用view在嵌套列表中的row number
*/
- (void)setExtraInfoForTag:(NSInteger)extraInfo;
- (NSInteger)getViewTypeOfTag;
- (NSInteger)getPositionOfTag;
- (NSInteger)getSectionOfTag;
- (NSInteger)getExtraInfoOfTag;
@end
//
// UIView+ExtraTag.m
// YiShop
//
// Created by 宗仁 on 16/6/8.
// Copyright © 2016年 宗仁 All rights reserved.
//
#import "UIView+ExtraTag.h"
#import <objc/runtime.h>
static void * KEY_VIEW_TYPE = &KEY_VIEW_TYPE;
static void * KEY_POSITION = &KEY_POSITION;
static void * KEY_SECTION = &KEY_SECTION;
static void * KEY_EXTRA_INFO = &KEY_EXTRA_INFO;
@implementation UIView (ExtraTag)
- (void)setViewTypeForTag:(NSInteger)viewType {
objc_setAssociatedObject(self, KEY_VIEW_TYPE, [NSNumber numberWithInteger:viewType], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)setPositionForTag:(NSInteger)position {
objc_setAssociatedObject(self, KEY_POSITION, [NSNumber numberWithInteger:position], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)setSectionForTag:(NSInteger)section {
objc_setAssociatedObject(self, KEY_SECTION, [NSNumber numberWithInteger:section], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)setExtraInfoForTag:(NSInteger)extraInfo {
objc_setAssociatedObject(self, KEY_EXTRA_INFO, [NSNumber numberWithInteger:extraInfo], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSInteger)getViewTypeOfTag {
return [objc_getAssociatedObject(self, KEY_VIEW_TYPE) integerValue];
}
- (NSInteger)getPositionOfTag {
return [objc_getAssociatedObject(self, KEY_POSITION) integerValue];
}
- (NSInteger)getSectionOfTag {
return [objc_getAssociatedObject(self, KEY_SECTION) integerValue];
}
- (NSInteger)getExtraInfoOfTag {
return [objc_getAssociatedObject(self, KEY_EXTRA_INFO) integerValue];
}
@end
而Android下的处理方法更简单,使用id设置tag即可,首先创建res/values/ids.xml
文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="tag_view_type" type="id"/>
<item name="tag_position" type="id"/>
<item name="tag_extra_info" type="id"/>
</resources>
然后改造原来的方法,完整代码如下
/**
* Get the view's extra info.
* @param view The view.
* @return The extra info.
*/
public static int getExtraInfoOfTag(View view) {
int tag;
if (view.getTag(R.id.tag_extra_info) == null) {
tag = 0;
} else {
tag = (int) view.getTag(R.id.tag_extra_info);
}
return tag;
}
/**
* Get the view's position of tag.
* @param view The view.
* @return The position.
*/
public static int getPositionOfTag(View view) {
int tag;
if (view.getTag(R.id.tag_position) == null) {
tag = 0;
} else {
tag = (int) view.getTag(R.id.tag_position);
}
return tag;
}
/**
* Get the type of view.
* @param view The view.
* @return The view type.
*/
public static ViewType getViewTypeOfTag(View view) {
int tag;
if (view.getTag(R.id.tag_view_type) == null) {
tag = 0;
} else {
tag = (int) view.getTag(R.id.tag_view_type);
}
return ViewType.valueOf(tag);
}
/**
* Add extra info to the view's tag.
*
* @param view The view.
* @param extraInfo The extra info.
*/
public static void setExtraInfoForTag(View view, int extraInfo) {
view.setTag(R.id.tag_extra_info, extraInfo);
}
/**
* Add position info to the view's tag.
*
* @param view The view.
* @param position The position.
*/
public static void setPositionForTag(View view, int position) {
view.setTag(R.id.tag_position, position);
}
/**
* Set the type of view.
*
* @param view The view.
* @param viewType The view type {@link ViewType}.
*/
public static void setViewTypeForTag(View view, ViewType viewType) {
view.setTag(R.id.tag_view_type, viewType.ordinal());
}