前言: setNeedsDisplay异步执行的。它会自动调用drawRect方法,这样可以拿到 UIGraphicsGetCurrentContext,就可以绘制了。 一、着手 我定义了一个UIView的子类,用于演示使用setNeedsDisplay,这个CircleView子类会在draw(_ rect: CGRect)方法内简单绘制一个圆,它有一个颜色属性,这是我们将要设置用来改变圆的颜色 我不会详细介绍如何配置storyboard,因为重点是了解setNeedsDisplay @IBOutlet weak var stepper: UIStepper! 所以我们需要调用setNeedsDisplay,明确地告诉系统必须重新绘制,从而显示新的颜色 由此,我们需要考虑三个重要的原则: 1、在iOS中,视图很明显会被缓存。 因为drawRect不能被手动调用,所以您需要使用setNeedsDisplay方法告诉系统完成绘图, 四、添加setNeedsDisplay 所以接下来,我们需要添加setNeedsDisplay
:self]; } return self; } /** * 监听文字改变 */ -(void)textDidChange { //重绘 [self setNeedsDisplay ]; } -(void)setPlaceholder:(NSString *)placeholder { _placeholder = placeholder; // setNeedsDisplay 会在下一个消息循环时刻,调用drawRect: [self setNeedsDisplay]; } -(void)setText:(NSString *)text { [super setText :text]; // setNeedsDisplay会在下一个消息循环时刻,调用drawRect: [self setNeedsDisplay]; } -(void)setFont:( UIFont *)font { [super setFont:font]; // setNeedsDisplay会在下一个消息循环时刻,调用drawRect: [self setNeedsDisplay
:rect withAttributes:attrs]; } - (void)layoutSubviews { [super layoutSubviews]; [self setNeedsDisplay ]; } - (void)setFont:(UIFont *)font { [super setFont:font]; [self setNeedsDisplay]; } - (void)setText:(NSString *)text { [super setText:text]; [self setNeedsDisplay]; } - (void ]; } - (void)setFont:(UIFont *)font { [super setFont:font]; [self setNeedsDisplay]; } self.placeholder = @""; } [self setNeedsDisplay]; } - (void)setAttributedText:(NSAttributedString
苹果要求我们调用UIView类中的setNeedsDisplay方法,则程序会自动调用drawRect方法进行重绘。 drawRect方法一般情况下只会被掉用一次.当某些情况下想要手动重画这个View,只需要掉用[self setNeedsDisplay]方法即可. 4.直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0. drawRect:方法不能手动显示调用,必须通过调用setNeedsDisplay或者setNeedsDisplayInRect,让系统自动调该方法。 3、若要实时画图,不能使用gestureRecognizer,只能使用touchbegan等方法来掉用setNeedsDisplay实时刷新屏幕。
UIView的setNeedsDisplay和setNeedsLayout方法。 首先两个方法都是异步执行的。 setNeedsDisplay会调用 drawRect方法,这样可以拿到UIGraphicsGetCurrentContext,就可以画画。 4、直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0。 **drawRect:方法不能手动显示调用,必须通过调用setNeedsDisplay 或 者 setNeedsDisplayInRect,让系统自动调该方法。强行调用也不会起作用的。 ** setNeedsDisplay和setNeedsLayout 详解
首先 UIView 调用 setNeedsDisplay 方法 其实是调用其 layer 属性的同名方法(view.layer setNeedsDisplay) 这时 layer 并不会立刻调用 display 面试考点 ---- ▐ 我们调用 [UIView setNeedsDisplay] 方法的时候,不会立马发送对应视图的绘制工作,为什么? 调用 [UIView setNeedsDisplay] 后, 然后会调用系统的同名方法 [view.layer setNeedsDisplay] 方法并在当前 view 上面打上一个脏标记 当前 Runloop ; label.font = [UIFont systemFontOfSize:16]; [self.view addSubview:label]; [label.layer setNeedsDisplay
然后系统自动调用drawRect:方法; 通过设置contentMode属性值为UIViewContentModeRedraw,那么将在每次设置或更改frame的时候自动调用drawRect:; 直接调用setNeedsDisplay 触发drawRect:,但是有个前提条件是rect不能为0; drawRect重绘方法定义 - (void)drawRect:(CGRect)rect;:重写此方法,执行重绘任务; - (void)setNeedsDisplay 在其他方法中获取的contextRef都是不生效的; drawRect:方法不能手动调用,需要调用实例方法setNeedsDisplay或者setNeedsDisplayInRect,让系统自动调用该方法 绘制,或者在delegate方法中进行绘制,然后调用setNeedDisplay方法实现最终的绘制; 若要实时画图,不能使用gestureRecognizer,只能使用touchbegan等方法来掉用setNeedsDisplay Apple官方文档描述 小结一下 上面的几个问题说的有些啰嗦了,总结一下需要掌握一下几点: 了解drawRect使用场景; 哪些方法可以调用; 了解何时进行重绘; 参考文献 drawRect参考 setNeedsDisplay
前言 实现了一款时下比较流行的环状进度动图,以下是源码解析 使用 Core Graphics 和 定时器 实现环形进度动图 圆环进度.gif 核心源码 # 使用 [self setNeedsDisplay invalidate]; timer = nil; } //如果为0则直接刷新 if (_progress == 0.0) { [self setNeedsDisplay || fakeProgress >= 1.0f) { #最后一次赋准确值 并移除定时器 fakeProgress = _progress; [self setNeedsDisplay invalidate]; timer = nil; } return; } else { #进度条动画 [self setNeedsDisplay
相关方法 layoutSubviews layoutIfNeeded setNeedsLayout setNeedsDisplay drawRect sizeThatFits sizeToFit 大概常用的上面几个 4、直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0。 drawRect:方法不能手动显示调用,必须通过调用setNeedsDisplay 或者 setNeedsDisplayInRect,让系统自动调该方法。 同样也是调用setNeedDisplay等间接调用以上方法 3、若要实时画图,不能使用gestureRecognizer,只能使用touchbegan等方法来掉用setNeedsDisplay实时刷新屏幕
4、直接调用setNeedsDisplay,或者setNeedsDisplayInRect PS: 重绘操作在drawRect方法中完成,不建议直接调用drawRect方法,当然调用此方法,结果没有任何效果的 我们调用UIView类中的setNeedsDisplay方法,则程序会自动调用drawRect方法进行重绘。
绘图过程中除了使用了drawRect:方法,还有setNeedsDisplay和setNeedsDisplayInRect:。 setNeedsDisplay和setNeedsDisplayInRect:方法是设置视图或者视图部分区域是否需要重新绘制,setNeedsDisplay是重新绘制整个视图,setNeedsDisplayInRect 触发视图重新绘制的动作有如下几种: 当遮挡你的视图的其他视图被移动或删除操作的时候; 将视图的hidden属性声明设置为NO,使其从隐藏状态变为可见; 将视图滚出屏幕,然后再重新回到屏幕上; 显式调用视图的setNeedsDisplay
学习了一下UIView的setNeedsDisplay和setNeedsLayout方法。首先两个方法都是异步执行的。 而setNeedsDisplay会调用自动调用drawRect方法,这样可以拿到UIGraphicsGetCurrentContext,就可以画画了。 宗上所诉,setNeedsDisplay方便绘图,而layoutSubViews方便出来数据。
//路径起点 currentPointArray.append(point) self.setNeedsDisplay() } override func //路径 currentPointArray.append(point) //刷新视图 self.setNeedsDisplay() } 由于我们的点都是存在数组中 allLineArray.removeAll() currentPointArray.removeAll() allPointWidth.removeAll() self.setNeedsDisplay
public func setNeedsLayout()
public func layoutSubviews()
public func layoutIfNeeded()
public func setNeedsDisplay code>、alpha 等属性
-调用 setNeedsLayout 方法以标记该视图(或者它的子视图)为需要进行布局更新
-调用 setNeedsDisplay ----
setNeedsDisplay 补充
setNeedsLayout 的使用场景之前已经提过了(iPad App),下面举个栗子说一下 setNeedsDisplayInRect 那么如果我想要这个直线一直根据两个点同步变化的话,就需要在 dotView 的位置发生改变时,执行:
lineView.setNeedsDisplay() // 重绘 lineView
[self.paths addObject:path]; //将路径记录到数组中 36 self.currentPath = path; 37 38 [self setNeedsDisplay 追踪每次路径的移动过程 44 [self.currentPath addLineToPoint:[self currentPoint:touches]]; 45 46 [self setNeedsDisplay locationInView:self]; 53 } 54 55 //次方法是UIView的分类@interface UIView(UIViewRendering)中添加的方法 56 //setNeedsDisplay //撤销 67 - (void)cancelPainting{ 68 [self.paths removeLastObject]; //移除最后一个路径对象 69 [self setNeedsDisplay 74 [self.paths removeAllObjects]; //移除所有路径 75 self.lineColor = nil; //颜色赋空 76 [self setNeedsDisplay
### `setNeedsDisplay` 对`CALayer`实例调用`setNeedsDisplay`方法之后`CALayer`的`display`方法就会被调用。 重写`layoutSubviews`方法添加对layer的`setNeedsDisplay`方法的调用。 这样一个调用链就形成了:用户操作->[view layoutSubviews]->[view.layer setNeedsDisplay]->[layer display]->[layer _displayAsync selector:@selector(contentsNeedUpdated) commit]; } (void)contentsNeedUpdated { // do update [self.layer setNeedsDisplay 这个任务是从[layer setNeedsDisplay]开始的。
sizeToFit ——————- – (void)layoutSubviews – (void)layoutIfNeeded – (void)setNeedsLayout ——————– – (void)setNeedsDisplay 实现布局 在视图第一次显示之前,标记总是“须要刷新”的,能够直接调用[view layoutIfNeeded] 重绘 -drawRect:(CGRect)rect方法:重写此方法,运行重绘任务 -setNeedsDisplay
orangeColor].CGColor); CGContextFillPath(context); } 3、UIView+drawLayer: inContext: 注意要显式调用[view.layer setNeedsDisplay setFill]; [p fill]; UIGraphicsPopContext(); } 4、CALayer+drawInContext 插入Layer层,注意插入Layer层时,要显式调用setNeedsDisplay drawInContext DrawLayer *layer = [[DrawLayer alloc]init]; layer.frame = self.view.bounds; [layer setNeedsDisplay
UIView会在第一次显示或需要重绘时自动调用drawRect,而CALayer不会,需要显示调用setNeedsDisplay。
index]]; 9 10 [self.allLine removeObjectAtIndex:index]; 11 12 [self setNeedsDisplay self.cancleArray[index]]; [self.cancleArray removeObjectAtIndex:index]; [self setNeedsDisplay locationInView:self]; 5 6 [self.bezier addLineToPoint:point]; 7 8 //重绘界面 9 [self setNeedsDisplay