Drawing with drawRect method - Cocoa

774 views Asked by At

I've been looking for solutions but can't figure out if it is possible to do the following:

I have a drawRect method, what i want to do is to add a graphic element (such as rects and lines) to the current view without refreshing it. I used to call setNeedsDisplay but this method is actually deleting myView an re-drawing it from 0.. Any suggestion to keep the old one and add new content ?

Thank

6

There are 6 answers

0
Abizern On

That's what drawRect: does - it redraws the rect in the view.

If you want lines and rects drawn on top, try doing it on a different layer.

1
Vervious On

Every time an update is made in a view the entirety of it is redrawn; so -drawRect needs to redraw the entire view. You have to 'refresh' your view - it's the norm - there's nothing wrong with it. Just draw the old content again.

Or, you could call setNeedsDisplayInRect: if you do want to just redraw a specific section of your view.

0
IluTov On

I guess it's better if you work with layers. You can make CALayer subclasses for your shapes, and then save them in an array.

0
user1709076 On

You can 'get around' this by making the view you want to draw in separate from your view with the original iboutlets. Then make your main view background transparent (but do not make the iboutlets transparent). So for this example, I will prevent that the IBOutlets you want to keep (not draw over) are a UITextField, a UILabel and a UIButton. So you Interface Builder will look like this:

UIVIewController
  UIView2 (view with drawRect defined)
  UIView  (main)
    UITextField
    UILabel
    UIButton

So as you see, when you call 'drawRect' it will still blank out your UIView2 completely, but it won't matter because 'drawRect' won't delete any of the UILabel, UIButton, UITextField or whatever else you want to keep in your UIView1. Hope this helps.

0
monjer On

By default , the drawRect method will clear the whole content , if your want to dynamic draw some new graphics contents to the view ,you should abstract these graphics element's data structure , for example , you add a line ,this line will have

       a start point 
       a end point
       line color
       line width
       is has a shadow
       a line join

so you can put all these property into a struct and define a new Data Class named LineStruct and define a method called

   -(void)drawLine:(CGContextRef)ctx withLineStruct:(LineStruct*)lineStruct

to your custom UIView , define a

@property (nonatomic) LineStruct *lineStruct ;

and invoke in it's drawRect method

   -(void)drawRect:(CGContextRef)ctx{
      CGContextRef ctx = UIGraphicsGetCurrentContext() ;
      [self drawLine:ctx withLineStruct:self.lineStruct];
   }

so if your have other graphic contents , you can do the draw like that . If you have lots of contents , you must add a buffer to your UIView ,such as add a NSArray , and in the drawRect method ,you add a for(;;)to draw all the graphics elements

0
tim k On

I think maybe you need something like an NSBezierPath to store all your shapes and add new shapes. It's easy to add new shapes to an existing NSBezierPath, see the documentation: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSBezierPath_Class/Reference/Reference.html Then in your drawrect, you will only have to stroke or fill the NSBezierPath.

This will only work if all your shapes have the same fill color and stroke. Otherwise you could keep some kind of list of multiple NSBezierPaths and stroke/fill them in different ways.