Why create the view with IB, and does it change the context?


#1

I went through the TouchTracker project and understood it. I wanted to incorporate the basic idea into a little app that would draw rectangles, so I started a new Window-based project. I created a simple UIView that draws rectangles with the current touch start and end coordinates.

To my surprise it didn’t work. Whatever I would draw would stay on the screen as part of the view, so every new rectangle simple added another one. I downgraded to lines, thinking maybe I was doing something wrong with the Core Graphics functions. Now I had several lines that would stay on the screen; it seemed like there were about 10 most recent at any one time. Not the “rubberband” look I expected at all.

I reviewed the book and realized that the TouchDrawView was added through IB. I retooled my mini app to add my custom view via IB in this same fashion (as on pg 236), and suddenly it worked! (Good thing, because it was driving me crazy. :confused: )

So do views instantiated from NIBs have some different behavior or settings when it comes to Core Graphics functions? And is that why you opted to create the view as part of the NIB in this example?


#2

The only behavior that is different between views instantiated from a NIB and views instantiated from code is the message they are sent when they are initialized.

Views instantiated from a NIB are sent initWithCoder: and views in code are sent initWithFrame:.

It is possible that you had some initialization code written in initWithCoder: that wasn’t being called because you were instantiated the view in code. Once a view (or any object, for that matter) is instantiated, it behaves exactly the same as any other object of the same type, regardless of how created.


#3

Drat, there goes my hope for an obvious/easy answer. :slight_smile:

I just took the view that was working when created via IB, went back to creation in code, and it has the bad drawing behavior again.

On a hunch, I took the TouchDrawView app and moved the view creation into code – and it exhibits the same bad drawing behavior! :bulb: I gave it an initWithFrame: by copying the content of initWithCoder:, and created it in the delegate. Drawing behavior is identical to my app.

EDIT: I figured out how to avoid the problem I describe, but I don’t understand why. With manual view creation, if I also call setBackgroundColor: (I did this in the delegate after creating the view) then I don’t experience the problem. This must do something that is missing in a default view, that affects the graphics context.


#4

Ah, now I understand why, thanks to one of the Apple engineers hanging out at the Apple forums: UIView defaults to a background color of nil. If the view property clearsContextBeforeDrawing is set, then backgroundColor must not be nil or the behavior of drawing will be unpredictable. This is documented in UIView clearsContextBeforeDrawing.