便利的初始化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中获取