通用指针的好处
我自定义一个View,内部有一个subView,位置是固定的,但是我有时候想放UIButtton,有时候想放UILabel.我应该声明一个什么样的Property呢
@property (nonatomic, strong) UIView *subView;
使用UIView,因为父类型指针可以任意指向子类型,严格的说任何指针都可以指向任何一个类型,因为指向的仅仅是地址,OC本身是动态的,只认内存地址.类型只是帮助编译器审查和联想.
Example Code
这段代码是写了一个CustomView,里面有左中右三个subView,三个subView使用的还是AutoLayout,还可以动态更新约束.主要是用到的思想是
- 保留指向约束的指针
- 新的subView加入后,使用指针从View中移出旧约束,加入新约束,然后刷新
SharedView.h
//
// SharedView.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface SharedView : NSObject
@end
@interface SharedView : UIView
@property (nonatomic, strong) UIView *leftView;
@property (nonatomic, strong) UIView *middleView;
@property (nonatomic, strong) UIView *rightView;
@property (nonatomic, assign) CGFloat leftViewWidth;
@property (nonatomic, assign) CGFloat leftViewHeight;
@property (nonatomic, assign) CGFloat leftViewLeftSpace;
@property (nonatomic, assign) CGFloat leftViewRightSpace;
@property (nonatomic, assign) CGFloat rightViewWidth;
@property (nonatomic, assign) CGFloat rightViewHeight;
@property (nonatomic, assign) CGFloat rightViewLeftSpace;
@property (nonatomic, assign) CGFloat rightViewRightSpace;
- (void)setTopLineHidden:(BOOL)hidden;
- (void)setButtomLineHidden:(BOOL)hidden;
- (void)setLeftLabelWithTitle:(NSString *)title;
- (void)setLeftIconWithImage:(UIImage *)image;
@end
SharedView.m
//
// SharedView.m
#import "SharedView.h"
@interface SharedView ()
@property (nonatomic, strong) UIView *topLine;
@property (nonatomic, strong) UIView *buttomLine;
@property (nonatomic, strong) NSMutableArray *constraints;
@property (nonatomic, strong) NSMutableDictionary *views;
//
@property (nonatomic, strong) NSLayoutConstraint *leftViewWidthConstraint;
@property (nonatomic, strong) NSLayoutConstraint *leftViewHeightConstraint;
@property (nonatomic, strong) NSLayoutConstraint *leftViewLeftSpaceConstraint;
@property (nonatomic, strong) NSLayoutConstraint *leftViewRightSpaceConstraint;
//
@property (nonatomic, strong) NSLayoutConstraint *rightViewWidthConstraint;
@property (nonatomic, strong) NSLayoutConstraint *rightViewHeightConstraint;
@property (nonatomic, strong) NSLayoutConstraint *rightViewLeftSpaceConstraint;
@property (nonatomic, strong) NSLayoutConstraint *rightViewRightSpaceConstraint;
//
@property (nonatomic, strong) NSLayoutConstraint *middleViewLeftEdgeConstraint;
@property (nonatomic, strong) NSLayoutConstraint *middleViewRightEdgeConstraint;
@end
@implementation SharedView
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
_views = [NSMutableDictionary dictionary];
_constraints = [NSMutableArray array];
_leftViewWidth = 100;
_leftViewHeight = 44;
_leftViewLeftSpace = 0;
_leftViewRightSpace = 0;
_rightViewWidth = 100;
_rightViewHeight = 44;
_rightViewLeftSpace = 0;
_rightViewRightSpace = 0;
[self setButtomLineHidden:NO];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_views = [NSMutableDictionary dictionary];
_constraints = [NSMutableArray array];
_leftViewWidth = 100;
_leftViewHeight = 44;
_leftViewLeftSpace = 0;
_leftViewRightSpace = 0;
_rightViewWidth = 100;
_rightViewHeight = 44;
_rightViewLeftSpace = 0;
_rightViewRightSpace = 0;
[self setButtomLineHidden:NO];
}
return self;
}
#pragma mark - Set Line
- (void)setTopLineHidden:(BOOL)hidden {
if (_topLine) {
[_topLine setHidden:hidden];
}else{
_topLine = [[UIView alloc]init];
[self addSubview:_topLine];
NSMutableArray *newConstraints = [NSMutableArray array];
//
[_views setObject:_topLine forKey:@"_topLine"];
//Set autorizingMask
[_topLine setTranslatesAutoresizingMaskIntoConstraints:NO];
//AutoLayout VF
[newConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_topLine]|" options:0 metrics:nil views:_views]];
[newConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_topLine(0.5)]" options:0 metrics:nil views:_views]];
[self addConstraints:newConstraints];
[self layoutIfNeeded];
//
[_topLine setBackgroundColor:COLOR_LINE];
[_topLine setHidden:hidden];
}
[self bringLineToFront];
}
- (void)setButtomLineHidden:(BOOL)hidden {
if (_buttomLine) {
[_buttomLine setHidden:hidden];
}else {
_buttomLine = [[UIView alloc]init];
[self addSubview:_buttomLine];
NSMutableArray *newConstraints = [NSMutableArray array];
//
[_views setObject:_buttomLine forKey:@"_buttomLine"];
//Set autorizingMask
[_buttomLine setTranslatesAutoresizingMaskIntoConstraints:NO];
//AutoLayout VF
[newConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_buttomLine]|" options:0 metrics:nil views:_views]];
[newConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_buttomLine(0.5)]|" options:0 metrics:nil views:_views]];
[self addConstraints:newConstraints];
[self layoutIfNeeded];
//
[_buttomLine setBackgroundColor:COLOR_LINE];
[_buttomLine setHidden:hidden];
}
[self bringLineToFront];
}
- (void)bringLineToFront {
if (_buttomLine) {
[self bringSubviewToFront:_buttomLine];
}
if (_topLine) {
[self bringSubviewToFront:_topLine];
}
}
#pragma mark - Set View
- (void)setMiddleView:(UIView *)middleView {
_middleView = middleView;
[self addSubview:_middleView];
NSMutableArray *newConstraints = [_constraints mutableCopy];
//
[_views setObject:_middleView forKey:@"_middleView"];
//
[_middleView setTranslatesAutoresizingMaskIntoConstraints:NO];
_middleViewLeftEdgeConstraint = [NSLayoutConstraint constraintWithItem:_middleView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0];
_middleViewRightEdgeConstraint = [NSLayoutConstraint constraintWithItem:_middleView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0 constant:0];
[newConstraints addObject:_middleViewLeftEdgeConstraint];
[newConstraints addObject:_middleViewRightEdgeConstraint];
[newConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_middleView]|" options:0 metrics:nil views:_views]];
//
[self removeConstraints:_constraints];
_constraints = [newConstraints mutableCopy];
[self addConstraints:_constraints];
[self layoutIfNeeded];
[self bringLineToFront];
}
- (void)setLeftView:(UIView *)leftView {
if (!_middleView) {
return;
}else {
_leftView = leftView;
[self addSubview:_leftView];
NSMutableArray *newConstraints = [_constraints mutableCopy];
[_views setObject:_leftView forKey:@"_leftView"];
[_leftView setTranslatesAutoresizingMaskIntoConstraints:NO];
//
[newConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|->=0-[_leftView]->=0-[_middleView]" options:NSLayoutFormatAlignAllCenterY metrics:nil views:_views]];
[newConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|->=0-[_leftView]->=0-|" options:0 metrics:nil views:_views]];
_leftViewWidthConstraint = [NSLayoutConstraint constraintWithItem:_leftView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:_leftViewWidth];
_leftViewHeightConstraint = [NSLayoutConstraint constraintWithItem:_leftView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationLessThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:_leftViewHeight];
_leftViewLeftSpaceConstraint = [NSLayoutConstraint constraintWithItem:_leftView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:_leftViewLeftSpace];
_leftViewRightSpaceConstraint = [NSLayoutConstraint constraintWithItem:_leftView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:_middleView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:_leftViewRightSpace];
[newConstraints addObject:_leftViewHeightConstraint];
[newConstraints addObject:_leftViewWidthConstraint];
[newConstraints addObject:_leftViewLeftSpaceConstraint];
[newConstraints addObject:_leftViewRightSpaceConstraint];
[newConstraints removeObject:_middleViewLeftEdgeConstraint];//Remove old middleView
[self removeConstraints:_constraints];
_constraints = [newConstraints mutableCopy];
[self addConstraints:_constraints];
[self layoutIfNeeded];
}
[self bringLineToFront];
}
- (void)setRightView:(UIView *)rightView {
if (!_middleView) {
return;
}else {
_rightView = rightView;
[self addSubview:_rightView];
NSMutableArray *newConstraints = [_constraints mutableCopy];
[_views setObject:_rightView forKey:@"_rightView"];
[_rightView setTranslatesAutoresizingMaskIntoConstraints:NO];
//
[newConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[_middleView]->=0-[_rightView]->=0-|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:_views]];
[newConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|->=0-[_rightView]->=0-|" options:0 metrics:nil views:_views]];
_rightViewWidthConstraint =[NSLayoutConstraint constraintWithItem:_rightView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:_rightViewWidth];
_rightViewHeightConstraint = [NSLayoutConstraint constraintWithItem:_rightView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationLessThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:_rightViewHeight];
_rightViewLeftSpaceConstraint = [NSLayoutConstraint constraintWithItem:_rightView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:_middleView attribute:NSLayoutAttributeRight multiplier:1.0 constant: _rightViewLeftSpace];
_rightViewRightSpaceConstraint = [NSLayoutConstraint constraintWithItem:_rightView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0 constant:_rightViewRightSpace];
//
[newConstraints addObject:_rightViewWidthConstraint];
[newConstraints addObject:_rightViewHeightConstraint];
[newConstraints addObject:_rightViewLeftSpaceConstraint];
[newConstraints addObject:_rightViewRightSpaceConstraint];
[newConstraints removeObject:_middleViewRightEdgeConstraint];//Remove old middleView
[self removeConstraints:_constraints];
_constraints = [newConstraints mutableCopy];
[self addConstraints:_constraints];
[self layoutIfNeeded];
}
[self bringLineToFront];
}
- (void)setLeftIconWithImage:(UIImage *)image {
UIImageView *leftImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
[leftImage setImage:image];
_leftViewWidth = image.size.width;
_leftViewHeight = image.size.height;
_leftViewLeftSpace = 10;
_leftViewRightSpace = -10;
[self setLeftView:leftImage];
}
- (void)setLeftLabelWithTitle:(NSString *)title {
UILabel *leftLabel = [[UILabel alloc]init];
[leftLabel setText:title];
[leftLabel setTextAlignment:NSTextAlignmentLeft];
[leftLabel setFont:[UIFont systemFontOfSize:16]];
_leftViewWidth = 60;
_leftViewHeight = 44;
[self setLeftView:leftLabel];
}
#pragma mark - Set Left View Frame
- (void)setLeftViewWidth:(CGFloat)leftViewWidth {
_leftViewWidth = leftViewWidth;
_leftViewWidthConstraint.constant = _leftViewWidth;
[self layoutIfNeeded];
}
- (void)setLeftViewHeight:(CGFloat)leftViewHeight {
_leftViewHeight = leftViewHeight;
NSLayoutConstraint *newConstraint = [NSLayoutConstraint constraintWithItem:_leftView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:_leftViewHeight];
//
[self removeConstraint:_leftViewHeightConstraint];
[_constraints removeObject:_leftViewHeightConstraint];
_rightViewHeightConstraint = newConstraint;
[_constraints addObject:_leftViewHeightConstraint];
[self addConstraint:_leftViewHeightConstraint];
[self layoutIfNeeded];
}
- (void)setLeftViewLeftSpace:(CGFloat)leftViewLeftSpace {
_leftViewLeftSpace = leftViewLeftSpace;
_leftViewLeftSpaceConstraint.constant = _leftViewLeftSpace;
[self layoutIfNeeded];
}
- (void)setLeftViewRightSpace:(CGFloat)leftViewRightSpace {
_leftViewRightSpace = leftViewRightSpace;
_leftViewRightSpaceConstraint.constant = -_leftViewRightSpace;
[self layoutIfNeeded];
}
#pragma mark - Set Right View Frame
- (void)setRightViewWidth:(CGFloat)rightViewWidth {
_rightViewWidth = rightViewWidth;
_rightViewWidthConstraint.constant = _rightViewWidth;
[self layoutIfNeeded];
}
- (void)setRightViewHeight:(CGFloat)rightViewHeight {
_rightViewHeight = rightViewHeight;
NSLayoutConstraint *newConstraint = [NSLayoutConstraint constraintWithItem:_rightView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:_rightViewHeight];
//
[self removeConstraint:_rightViewHeightConstraint];
[_constraints removeObject:_rightViewHeightConstraint];
_rightViewHeightConstraint = newConstraint;
[_constraints addObject:_rightViewHeightConstraint];
[self addConstraint:_rightViewHeightConstraint];
[self layoutIfNeeded];
}
- (void)setRightViewLeftSpace:(CGFloat)rightViewLeftSpace {
_rightViewLeftSpace = rightViewLeftSpace;
_rightViewLeftSpaceConstraint.constant = _rightViewLeftSpace;
[self layoutIfNeeded];
}
- (void)setRightViewRightSpace:(CGFloat)rightViewRightSpace {
_rightViewRightSpace = rightViewRightSpace;
_rightViewRightSpaceConstraint.constant = -_rightViewRightSpace;
[self layoutIfNeeded];
}
@end
还可以该进的地方
不知道是不是可以用ViewContainer代替整个View,毕竟目前View和middleView功能重复,争取改的和TextField一样,可以左边右边加View