便利的初始化view以及设置tag值

效果

源码

https://github.com/YouXianMing/iOS-Project-Examples 中的 SetRect

//
//  AccessViewTagProtocol.h
//  Animations
//
//  Created by YouXianMing on 16/6/17.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

typedef void(^ViewSetupBlock)(UIView * view);

@protocol AccessViewTagProtocol <NSObject>

@required

/**
 *  Set the view whose tag matches the specified value.
 *
 *  @param view View.
 *  @param tag  tag.
 */
- (void)setView:(UIView *)view withTag:(NSInteger)tag;

/**
 *  Remove the tag.
 *
 *  @param tag View‘s tag.
 */
- (void)removeReferenceWithTag:(NSInteger)tag;

/**
 *  Get the view from the tag.
 *
 *  @param tag.
 *
 *  @return view‘s object.
 */
- (id)viewWithTag:(NSInteger)tag;

@end
//
//  UIView+FrameAndTag.h
//  SetRect
//
//  Created by YouXianMing on 16/6/19.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "AccessViewTagProtocol.h"

@interface UIView (FrameAndTag) <AccessViewTagProtocol>

#pragma mark - Set tags.

/**
 *  Support AccessViewTagProtocol.
 */
- (void)supportAccessViewTagProtocol;

/**
 *  Get the view with specified tag from CustomViewController type‘s controller.
 *
 *  @param tag    View‘s tag.
 *  @param object AccessViewTagProtocol‘s object.
 *
 *  @return The view.
 */
+ (instancetype)viewWithTag:(NSInteger)tag from:(id <AccessViewTagProtocol>)object;

/**
 *  Set the view‘s tag.
 *
 *  @param tag    View‘s tag.
 *  @param object AccessViewTagProtocol‘s object.
 */
- (void)setTag:(NSInteger)tag attachedTo:(id <AccessViewTagProtocol>)object;

#pragma mark - Init frames.

/**
 *  设置尺寸以及设置tag值
 */
+ (instancetype)viewWithFrame:(CGRect)frame insertIntoView:(UIView *)view tag:(NSInteger)tag
                   attachedTo:(id <AccessViewTagProtocol>)object setupBlock:(ViewSetupBlock)block;

/**
 *  设置尺寸
 */
+ (instancetype)viewWithFrame:(CGRect)frame insertIntoView:(UIView *)view setupBlock:(ViewSetupBlock)block;

#pragma mark - Init line view.

/**
 *  水平线条
 */
+ (instancetype)lineViewInsertIntoView:(UIView *)view positionY:(CGFloat)positionY thick:(CGFloat)thick
                               leftGap:(CGFloat)leftGap rightGap:(CGFloat)rightGap color:(UIColor *)color;

/**
 *  垂直线条
 */
+ (instancetype)lineViewInsertIntoView:(UIView *)view positionX:(CGFloat)positionX thick:(CGFloat)thick
                                topGap:(CGFloat)topGap bottomGap:(CGFloat)bottomGap color:(UIColor *)color;

@end

NS_INLINE id viewFrom(id <AccessViewTagProtocol> object, NSInteger tag) {

    return [UIView viewWithTag:tag from:object];
}
//
//  UIView+FrameAndTag.m
//  SetRect
//
//  Created by YouXianMing on 16/6/19.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

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

@interface UIView ()

@property (nonatomic, strong) NSNumber  *tagNumberValue;
@property (nonatomic, strong) NSMapTable <NSString *, UIView *> *viewsWeakMap;

@end

@implementation UIView (FrameAndTag)

- (void)supportAccessViewTagProtocol {

    self.viewsWeakMap = [NSMapTable strongToWeakObjectsMapTable];
}

+ (instancetype)viewWithTag:(NSInteger)tag from:(id <AccessViewTagProtocol>)object {

    return [object viewWithTag:tag];
}

- (void)setTag:(NSInteger)tag attachedTo:(id <AccessViewTagProtocol>)object {

    self.tagNumberValue ? [object removeReferenceWithTag:self.tagNumberValue.integerValue] : 0;
    self.tag            = tag;
    self.tagNumberValue = @(tag);
    [object setView:self withTag:tag];
}

+ (instancetype)viewWithFrame:(CGRect)frame
               insertIntoView:(UIView *)view
                          tag:(NSInteger)tag
                   attachedTo:(id <AccessViewTagProtocol>)object
                   setupBlock:(ViewSetupBlock)block {

    UIView *tmpView = [[[self class] alloc] initWithFrame:frame];
    [tmpView supportAccessViewTagProtocol];

    view   && [view isKindOfClass:[UIView class]]                     ? ([view addSubview:tmpView])              : 0;
    object && [object respondsToSelector:@selector(setView:withTag:)] ? ([tmpView setTag:tag attachedTo:object]) : 0;

    if (block) {

        block(tmpView);
    }

    return tmpView;
}

+ (instancetype)viewWithFrame:(CGRect)frame
               insertIntoView:(UIView *)view
                   setupBlock:(ViewSetupBlock)block {

    UIView *tmpView = [[[self class] alloc] initWithFrame:frame];
    [tmpView supportAccessViewTagProtocol];

    view && [view isKindOfClass:[UIView class]] ? ([view addSubview:tmpView]) : 0;

    if (block) {

        block(tmpView);
    }

    return tmpView;
}

+ (instancetype)lineViewInsertIntoView:(UIView *)view positionY:(CGFloat)positionY thick:(CGFloat)thick
                               leftGap:(CGFloat)leftGap rightGap:(CGFloat)rightGap color:(UIColor *)color {

    UIView *tmpView = [[[self class] alloc] initWithFrame:CGRectMake(leftGap, positionY, view.frame.size.width - leftGap - rightGap, thick)];
    color ? tmpView.backgroundColor = color : 0;
    [view addSubview:tmpView];

    return tmpView;
}

+ (instancetype)lineViewInsertIntoView:(UIView *)view positionX:(CGFloat)positionX thick:(CGFloat)thick
                                topGap:(CGFloat)topGap bottomGap:(CGFloat)bottomGap color:(UIColor *)color {

    UIView *tmpView = [[[self class] alloc] initWithFrame:CGRectMake(positionX, topGap, thick, view.frame.size.height - topGap - bottomGap)];
    color ? tmpView.backgroundColor = color : 0;
    [view addSubview:tmpView];

    return tmpView;
}

#pragma mark - Runtime property.

- (void)setTagNumberValue:(NSNumber *)tagNumberValue {

    objc_setAssociatedObject(self, @selector(tagNumberValue), tagNumberValue, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSNumber *)tagNumberValue {

    return objc_getAssociatedObject(self, _cmd);
}

- (void)setViewsWeakMap:(NSMapTable<NSString *,UIView *> *)viewsWeakMap {

    objc_setAssociatedObject(self, @selector(viewsWeakMap), viewsWeakMap, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSMapTable<NSString *,UIView *> *)viewsWeakMap {

    return objc_getAssociatedObject(self, _cmd);
}

#pragma mark - AccessViewTagProtocol.

- (void)setView:(UIView *)view withTag:(NSInteger)tag {

    [self.viewsWeakMap setObject:view forKey:@(tag).stringValue];
}

- (id)viewWithTag:(NSInteger)tag {

    return [self.viewsWeakMap objectForKey:@(tag).stringValue];
}

- (void)removeReferenceWithTag:(NSInteger)tag {

    [self.viewsWeakMap removeObjectForKey:@(tag).stringValue];
}

@end

细节

需要实现协议(用NSMapTable的strongToWeakObjectsMapTable来作为存储string - view)

获取tag更为便利,不依赖于从哪一个view中获取view,而是直接从NSMapTable中获取

时间: 2024-10-16 02:28:37

便利的初始化view以及设置tag值的相关文章

view 边框颜色 tag值设定等

//添加边框和提示 CGRect frameRect = CGRectMake(20, 90, self.window.frame.size.width-40, self.window.frame.size.height-180); UIView   *frameView = [[UIView alloc] initWithFrame:frameRect] ; frameView.layer.borderWidth = 1; frameView.layer.borderColor = [[UIC

android中如何正确的设置view的多个tag值

在android开发过程中,我们经常会用到view.setTag(object)这个方法,特别是在ListView的自定义的adapter中复用view的时候.同时,view还提供了设置多个tag数据的方法,即view.setTag(int,Object),其中这个int值需要设置正确,不然这个方法会报错了.让我们来看看怎么设置这个值.先看结果: 从eclipse打印的log可以看出,我设置了gridview的4种不同类型的tag值.再来看看代码. package com.androidtest

OC03-继承,便利构造器,初始化方法

继承 继承 继承的主要作用就是保证类的完整以及简化代码. 使用时把公共的方法和实例变量写在父类里,子类只需要写自己独有的实例变量和方法就行 特点: 只允许单继承 OC中的根类是NSObject 继承的内容:是所有实例变量和方法 如果子类中不想用父类方法的实现,可以重写方法 注意: 继承的上层是父类,下层是子类 继承是单向的,不能相互继承 继承是有传递性的,即如果A继承于B,B继承于C,A就具有B和C的特征和行为 子类可以继承父类全部的特征和行为 继承的实现 #import <Foundation

Android通过注解初始化View

一.引言 Android中通过findViewById在布局文件中找到需要的View,加入一个Activity里面有许多的View需要初始化,那将是一件很繁琐的事情.当然Google一下你会发现有很多Android Annotations框架.比如比较有名的"Android Annotations",这样的框架很复杂,用起来也比较麻烦,还有一些BUG,第一次使用也花费了不少时间研究.也许你在项目中只希望用到 Inject View这个功能,又或者你想知道这个实现的原理是怎样的.本文主要

bootstrap-select 使用笔记 设置选中值及手动刷新

直接笔记: 1.页面刚加载完填充select选项数据时,需要手动刷新一下组件,否则没有选项值.(组件初始化时,li 与 option 分离的,需要刷新一下(据说)) $.post('/cpms/todo/getProjectList', data).done(function(result) { if(typeof(result) == "string"){ result = JSON.parse(result.data); } if(result.data.rows){ viewMo

GridView列添加下拉框,绑定数据源并设置默认值

添加下拉框:   注意:默认值只能在界面初始化直接中设置 DataGridViewComboBoxColumn dataGridViewComboBoxColumn = new DataGridViewComboBoxColumn(); dataGridViewComboBoxColumn.Name = "dgvcbcSeatType"; dataGridViewComboBoxColumn.DataPropertyName = "SeatType"; dataGr

Browser设置UA值

SWE Browser中的OptionMenu是Controller通过onKeyDown监听KEYCODE_MENU来显示的 public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU && event.getRepeatCount() == 0) { // Hardware menu key mAppMenuHandler.showAppMenu(mActivi

查看特定View的默认属性值

当我在分析focus.touch事件处理代码时发现,有些属性对代码的逻辑有非常重要的影响,比如clickable.focusable 这些属性.这时我们自然而然的想到,那么这些属性的默认值是什么呢?在工作中我也很多次有同样的疑问.当初我也不是 很清楚,基本都是手动在xml里面设置下.相信和我一样的人还有很多,今天我就告诉大家怎么通过Android源码来快速查看这些默认值. 比如我们经常用到的TextView,感觉上来说,它应该是不能点击的,也就是clickable默认应该是false.接下来,我

Android 设置alpha值来制作透明与渐变效果的实例

Android系统支持的颜色是由4个值组成的,前3个为RGB,也就是我们常说的三原色(红.绿.蓝),最后一个值是A,也就是Alpha.这4个值都在0~255之间.颜色值越小,表示该颜色越淡,颜色值越大,表示该颜色越深.如果RGB都是0,就是黑色,如果都为255,就是白色.Alpha也需要在0~255之间变化.Alpha的值越小,颜色就越透明,Alpha的值越大,颜色就不透明.当Alpha的值为0时,颜色完全透明,完全透明的位图或者图形从View上消失.当Alpha的值为255时,颜色不透明.从A