On Jan 13, 2015, at 10:50 PM, Jens Alfke <j...@mooseyard.com> wrote:

> 
>> On Jan 13, 2015, at 9:25 PM, N!K <pu56ucl...@alumni.purdue.edu> wrote:
>> 
>> A breakpoint at the end of drawRect shows that it runs twice. After the 
>> second pass, the view appears, as it should.
>> Between passes, bounds is changed somehow, as shown by NSLog  at the start 
>> and end of drawRect. 
>> Since this will upset code that I will add later, I’d like to stop this. 
> 
> The view's being resized, probably as part of view layout. Ideally AppKit 
> shouldn't draw the view before it gets to its final size, but maybe this is 
> part of an animation, or maybe it's something that hasn't been optimized 100% 
> in AppKit.
> 
> In general, you should not make assumptions about when and how often 
> -drawRect: will be called. That's up to AppKit. Your job is just to draw the 
> view when you’re told to.

OK. Cause is unknown (probably unknowable?) but part of Cocoa. Just because 
there was only one pass in other projects, I can’t depend on it. drawRect can 
happen anytime.

> 
> You haven't said why the bounds change will upset your code; is the view 
> being changed to the wrong size? That would be an actual problem, but it 
> isn't related to being drawn multiple times. You'd need to look at the view 
> constraints in your window to diagnose that.
> 
> —Jens

“Why” takes a little explaining. Thank you for your patience.

I’m trying to learn more about drawing. One stumbling block was getting an 
NSBezierPath to change size proportional to the window size when the corner is 
dragged. Per Graham Cox’s suggestion, the view size change can be detected in 
subsequent passes of drawRect by comparing 
        ratioX = NSWidth ([_path bounds])/NSWidth(bounds);
        ratioY = NSHeight([_path bounds])/NSHeight(bounds);
with their initial values, which were established in the one pass of drawRect 
before the view appeared.

This worked perfectly. I used the ratios in 
-(void)resize{
    scaleX = ratioX0/ratioX;
    scaleY = ratioY0/ratioY;
        NSAffineTransform* tfm = [[NSAffineTransform alloc] init];
        [tfm scaleXBy:scaleX yBy:scaleY];
        temp  = [tfm transformBezierPath:_path];
}
The initial view was correct. Then dragging the window corner  induced 
drawRect’s, which detected the changes and scaled the original _path each time; 
no cumulative errors. The path size tracked the view size correctly. 



Next I wanted to learn how to scale the whole view in a new project, not just 
the NSBezierPath. I was  planning to  later include other objects with the 
NSBezierPath and wanted them to be scaled, too. I used the same initialization 
and failed because of the bounds change between two passes, which I failed to 
anticipate. The first pass set the initial values. The second pass detected the 
change and scaled the view before the view appeared.
-(void)resize{
    scaleX = ratioX0/ratioX;
    scaleY = ratioY0/ratioY;
    NSAffineTransform* tfm = [[NSAffineTransform alloc] init];
    [tfm scaleXBy:scaleX yBy:scaleY];
    temp  = [tfm transformBezierPath:_path];
}
Thus the path in the initial view was quite different from the initial path, 
and dragging the corner of the window caused wildly incorrect scaling.

My hope was that there might be a way of suppressing the second pass before 
display of the view. Now I know better and will figure out another way to 
initialize and track. Thank you for correcting me.

Nick








_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to