<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 臟矩形 ????有時候用`CAShapeLayer`或者其他矢量圖形圖層替代Core Graphics并不是那么切實可行。比如我們的繪圖應用:我們用線條完美地完成了矢量繪制。但是設想一下如果我們能進一步提高應用的性能,讓它就像一個黑板一樣工作,然后用『粉筆』來繪制線條。模擬粉筆最簡單的方法就是用一個『線刷』圖片然后將它粘貼到用戶手指碰觸的地方,但是這個方法用`CAShapeLayer`沒辦法實現。 ????我們可以給每個『線刷』創建一個獨立的圖層,但是實現起來有很大的問題。屏幕上允許同時出現圖層上線數量大約是幾百,那樣我們很快就會超出的。這種情況下我們沒什么辦法,就用Core Graphics吧(除非你想用OpenGL做一些更復雜的事情)。 ????我們的『黑板』應用的最初實現見清單13.3,我們更改了之前版本的`DrawingView`,用一個畫刷位置的數組代替`UIBezierPath`。圖13.2是運行結果 清單13.3 簡單的類似黑板的應用 ~~~ #import "DrawingView.h" #import #define BRUSH_SIZE 32 @interface DrawingView () @property (nonatomic, strong) NSMutableArray *strokes; @end @implementation DrawingView - (void)awakeFromNib { //create array self.strokes = [NSMutableArray array]; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { //get the starting point CGPoint point = [[touches anyObject] locationInView:self]; //add brush stroke [self addBrushStrokeAtPoint:point]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { //get the touch point CGPoint point = [[touches anyObject] locationInView:self]; //add brush stroke [self addBrushStrokeAtPoint:point]; } - (void)addBrushStrokeAtPoint:(CGPoint)point { //add brush stroke to array [self.strokes addObject:[NSValue valueWithCGPoint:point]]; //needs redraw [self setNeedsDisplay]; } - (void)drawRect:(CGRect)rect { //redraw strokes for (NSValue *value in self.strokes) { //get point CGPoint point = [value CGPointValue]; //get brush rect CGRect brushRect = CGRectMake(point.x - BRUSH_SIZE/2, point.y - BRUSH_SIZE/2, BRUSH_SIZE, BRUSH_SIZE); //draw brush stroke ? [[UIImage imageNamed:@"Chalk.png"] drawInRect:brushRect]; } } @end ~~~ ![圖13.2](https://zsisme.gitbooks.io/ios-/content/chapter15/13.2.png) 圖13.2 用程序繪制一個簡單的『素描』 ????這個實現在模擬器上表現還不錯,但是在真實設備上就沒那么好了。問題在于每次手指移動的時候我們就會重繪之前的線刷,即使場景的大部分并沒有改變。我們繪制地越多,就會越慢。隨著時間的增加每次重繪需要更多的時間,幀數也會下降(見圖13.3),如何提高性能呢? ![圖13.3](https://zsisme.gitbooks.io/ios-/content/chapter15/13.3.png) 圖13.3 幀率和線條質量會隨時間下降。 ????為了減少不必要的繪制,Mac OS和iOS設備將會把屏幕區分為需要重繪的區域和不需要重繪的區域。那些需要重繪的部分被稱作『臟區域』。在實際應用中,鑒于非矩形區域邊界裁剪和混合的復雜性,通常會區分出包含指定視圖的矩形位置,而這個位置就是『臟矩形』。 ????當一個視圖被改動過了,TA可能需要重繪。但是很多情況下,只是這個視圖的一部分被改變了,所以重繪整個寄宿圖就太浪費了。但是Core Animation通常并不了解你的自定義繪圖代碼,它也不能自己計算出臟區域的位置。然而,你的確可以提供這些信息。 ????當你檢測到指定視圖或圖層的指定部分需要被重繪,你直接調用`-setNeedsDisplayInRect:`來標記它,然后將影響到的矩形作為參數傳入。這樣就會在一次視圖刷新時調用視圖的`-drawRect:`(或圖層代理的`-drawLayer:inContext:`方法)。 ????傳入`-drawLayer:inContext:`的`CGContext`參數會自動被裁切以適應對應的矩形。為了確定矩形的尺寸大小,你可以用`CGContextGetClipBoundingBox()`方法來從上下文獲得大小。調用`-drawRect()`會更簡單,因為`CGRect`會作為參數直接傳入。 ????你應該將你的繪制工作限制在這個矩形中。任何在此區域之外的繪制都將被自動無視,但是這樣CPU花在計算和拋棄上的時間就浪費了,實在是太不值得了。 ????相比依賴于Core Graphics為你重繪,裁剪出自己的繪制區域可能會讓你避免不必要的操作。那就是說,如果你的裁剪邏輯相當復雜,那還是讓Core Graphics來代勞吧,記住:當你能高效完成的時候才這樣做。 ????清單13.4 展示了一個`-addBrushStrokeAtPoint:`方法的升級版,它只重繪當前線刷的附近區域。另外也會刷新之前線刷的附近區域,我們也可以用`CGRectIntersectsRect()`來避免重繪任何舊的線刷以不至于覆蓋已更新過的區域。這樣做會顯著地提高繪制效率(見圖13.4) ????清單13.4 用`-setNeedsDisplayInRect:`來減少不必要的繪制 ~~~ - (void)addBrushStrokeAtPoint:(CGPoint)point { //add brush stroke to array [self.strokes addObject:[NSValue valueWithCGPoint:point]]; //set dirty rect [self setNeedsDisplayInRect:[self brushRectForPoint:point]]; } - (CGRect)brushRectForPoint:(CGPoint)point { return CGRectMake(point.x - BRUSH_SIZE/2, point.y - BRUSH_SIZE/2, BRUSH_SIZE, BRUSH_SIZE); } - (void)drawRect:(CGRect)rect { //redraw strokes for (NSValue *value in self.strokes) { //get point CGPoint point = [value CGPointValue]; //get brush rect CGRect brushRect = [self brushRectForPoint:point]; ? //only draw brush stroke if it intersects dirty rect if (CGRectIntersectsRect(rect, brushRect)) { //draw brush stroke [[UIImage imageNamed:@"Chalk.png"] drawInRect:brushRect]; } } } ~~~ ![圖13.4](https://zsisme.gitbooks.io/ios-/content/chapter15/13.4.png) 圖13.4 更好的幀率和順滑線條
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看