一,masonry当没有设置lablel右边距的时候, 那么它的宽度是根据字符串长度决定的,但是如果字符串长度过长,但是又不能直接设置右边距,所以给它一个最小的距离,告诉其如果超过的时候怎么显示:
make.right.mas_lessThanOrEqualTo(self.commodBgView.mas_right).offset(-ScaleForSize(20.0));
距离当前commodBgView的右边最小的距离必须为20。
二,masonry,设置其某个view的宽度为其相对view的数字比例,例如:
make.width.equal(superview.mas_width).multipy(1.0/3.0);
让view是父类view的三分之一宽度。
三,UITextFiled或者TextView增加ToolBar,悬停在键盘上方:
为其分配inputAccessoryView,让其跟随键盘显示和隐藏。如下图:
- (void)drawRect:(CGRect)rect { // Drawing code // if(nil != self.inputAccessoryView) return;; UIToolbar *toolBar =[[UIToolbar alloc]initWithFrame:CGRectMake(0.0, 0.0, ScreenWidth, ScaleForSize(80.0))]; UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc]initWithTitle:@"取消" style:UIBarButtonItemStyleDone target:self action:@selector(numberFieldCancle)]; cancelBtn.tintColor = HEXCOLOR(0X17abe3); UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc]initWithTitle:@"确定" style:UIBarButtonItemStyleDone target:self action:@selector(numberFieldEnter)]; doneBtn.tintColor = HEXCOLOR(0X17abe3); NSArray *items =@[flexSpace,cancelBtn,doneBtn]; toolBar.items = items; [toolBar sizeToFit]; self.inputAccessoryView = toolBar; }
四,两个数组,元素是Model,判断是否有相同的元素,一次循环加正则:
- (void)checkedOperate { __weak typeof(self) weakSelf = self; [self.checkedModels enumerateObjectsUsingBlock:^(SkyCorsPernModel *cpModel, NSUInteger idx, BOOL * _Nonnull stop) { NSPredicate *predicate = [NSPredicate predicateWithFormat:@"corsPern_id = %@",cpModel.corsPern_id]; NSArray *tempArr = [weakSelf.personTableView.datas filteredArrayUsingPredicate:predicate]; if(tempArr.count){ SkyCorsPernModel *tempCheckModel = tempArr.firstObject; tempCheckModel.checked = YES; } }]; }
五,block中地址传递,通过外接传递的地址内部进行一些判断。
@property (nonatomic,copy)void(^complateProgress)(bool *autoHid); // bool isHid = NO; if(self.complateProgress) self.complateProgress(&isHid); if(isHid){ [self displaySucLabel]; } // IMUploadProgress *progress = [IMUploadProgress uploadProgressViewBegin:^{ NSLog(@"begin handle"); } progressCpl:^(bool * _Nonnull autoHid) { NSLog(@"progress complate"); *autoHid = NO; } hiddenHandle:^{ NSLog(@"hiddenHandle"); }];
六,controller添加子控制器:
//增加子控制器到当前控制器
[self addChildViewController:childViewController];
//添加自控制器的view当当前控制器
[superview addSubview:childViewController.view];
//告诉自控制器,已经添加到父控制器上了,可在自控制器中重写此方法
[childViewController didMoveToParentViewController:self];
移除子控制器:
//告诉自控制器即将移除,并且父控制器置为空,自控制器中可重写次方法
[self willMoveToParentViewController:nil];
//将自控制器的view从其superview中移除
[self.view removeFromSuperview];
//从父控制器中移除
[self removeFromParentViewController];
七,xcode查看当前UI是否造成离屏渲染,渲染的部分会出现黄色:
八,取消执行延迟执行的方法:
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(selecter:) object:nil];
取消当前要延时操作的事件。
跟方法performSelector相对应,方法名和参数都一致才能够取消,属于类方法,所以直接NSObject进行调用。
九,layoutSubviews,一般用于:
当自定义 view的frame发生变化时,修改其子view的布局可重写view的layoutSubviews方法,调用时需调用其父类方法[super layoutSubviews];
一般用于输入框输入文字,改变其大小时并且改变textView的大小,例如:
- (void)layoutSubviews { [super layoutSubviews]; self.emojiButton.frame = ... self.moreButton.frame = ... [UIView animateWithDuration:0.25 animations:^{ self.textView.frame = ... }]; }
layoutSubviews的其他调用时机:
1,当view被添加到父视图中会延迟调用;
2,当view添加子控件时会被调用;
3,当view的frame发生变化时,会被调用;
4,当view子控件的frame发生变化时,会被调用;
5,ScrollView滚动时会触发layoutSubviews方法;
6,当旋转屏幕时会触发layoutSubviews方法;
7,当view直接调用layoutIfNeeded方法时,会立马调用,不会延迟。
十,简单的跑马灯效果:
场景:将UILabel加入到UIScrollView中,Label的text为二倍的字符串,然后设置Label的width和Scroll的ContentSize.width,然后:
CGFloat speed = 50.0; // 跑马灯速度 NSTimeInterval duration = (self.scrollView.contentSize.width - self.scrollView.width) / speed; CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.x"]; animation.duration = duration; animation.repeatCount = HUGE_VALF; animation.beginTime = CACurrentMediaTime(); animation.autoreverses = NO; animation.removedOnCompletion = NO; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; animation.toValue = @(0.0); animation.fromValue = @(self.notiLabel.size.width/2); [self.notiLabel.layer addAnimation:animation forKey:@"animationViewPosition"]; - (void)stopAnimation { [self.notiLabel.layer removeAnimationForKey:@"animationViewPosition"]; }
十一,以下2个方法,如果用方法2去创建对象,容易造成对象内存溢出,因为创建了两个对象。
/// method 1 + (instancetype)shared { return [[self.class alloc]init]; } /// method 2 - (instancetype)initWithOtherParams:(NSObject * _Nullable )params { return [self.class shared]; }
十二,通过宽度计算label的高度,通常用在聊天列表中。先计算出高度,然后重新分配宽高。
CGFloat maxContentWidth = self.tableViewWidth-BJPViewSpaceM*4 - userCoverImgViewSize - 66.0; CGSize messageLabelSize = [self.messageLabel sizeThatFits:CGSizeMake(maxContentWidth, 0)]; CGFloat messageWidth = MAX(nameLabelSize.width, messageLabelSize.width); [self.messageLabel bjl_updateConstraints:^(BJLConstraintMaker *make) { make.width.equalTo(@(messageLabelSize.width)).priorityHigh(); make.height.equalTo(@(messageLabelSize.height)).priorityHigh(); }];
十三,UITextView增加连接,及点击:
self.replyMsgText.dataDetectorTypes = (message.fromUser.isTeacherOrAssistant ? UIDataDetectorTypeLink : UIDataDetectorTypeNone); self.replyMsgText.linkTextAttributes = @{NSForegroundColorAttributeName: HEXCOLOR(0X2485FC)};
十四,updateViewConstraints方法,更新controller中self.view中子view的所有约束;
当[self.viewaddSubview subView]的时候自动调用一次;
当执行self.view.setNeedsUpdateConstraints();方法时手动调用一次;
当self.view中的某个view约束需要更新时,可以调用;
所以重写updateViewConstraints的时候必须调super.updateViewConstraints();方法;
自定View中,updateConstraints方法,更新其子view的约束:
1,当[self addSubView:subView]时候会自动调用一次;
2,当执行self.setNeedsUpdateConstraints();方法时,会手动调用一次;
当view中的某个子view约束需要进行更新时,可以重写该方法进行重新布局;
重新updateConstraints方法时,必须调用其父类view的方法,super.updateConstraints();
如下:
一般用于:当屏幕旋转的时候,需要重新布局UI,可调用setNeedsUpdateConstraints方法根据横竖屏重新进行布局。
controller中: override func updateViewConstraints() { v_1.snp.updateConstraints { make in make.width.height.equalTo(flag ? 300 : 100); make.center.equalToSuperview(); }; super.updateViewConstraints(); } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { flag = !flag; self.view.setNeedsUpdateConstraints(); } 自定义view中: @objc func singleTap(_ tap: UITapGestureRecognizer) -> Void { flag = !flag; self.setNeedsUpdateConstraints(); } override func updateConstraints() { print("++subview updateConstraints++"); subview_1.snp.updateConstraints { make in make.height.width.equalTo(flag ? 200.0 : 50.0); }; super.updateConstraints(); }