Re: Problem with Auto Layout and drawRect
Re: Problem with Auto Layout and drawRect
- Subject: Re: Problem with Auto Layout and drawRect
- From: Mike Abdullah <email@hidden>
- Date: Mon, 07 Sep 2015 19:24:19 +0100
> On 7 Sep 2015, at 18:34, Dave <email@hidden> wrote:
>
> Hi,
>
> I have a View subclass called LTWDrawFrameView that has been working since the dawn of time and would like to make it work with auto layout.
>
> All it does it optionally Draw a Frame Around an NSView and/or fill the view with a solid color.
>
> On the face of it, I can’t see the need to do anything special for auto layout in this subclass, but when I add this to an NSScrollView and NSStackView combo (see other thread), I get some lines are drawn where they shouldn’t be seemingly at random.
>
> translatesAutoresizingMaskIntoConstraints is set to no for these views.
>
> I’ve pasted the class below, can anyone see anything wrong with it in terms of not working in a Scroll/Stack View and auto layout?
>
> Thanks a lot
> Dave
>
> —————————————————————————————
>
> //
> // LTWDrawFrameView.h
> //
> #import <Cocoa/Cocoa.h>
>
> @interface LTWDrawFrameView : NSView
> {
> }
> @property (nonatomic,assign) BOOL pDrawFrameFlag;
> @property (nonatomic,assign) BOOL pDrawPaneFlag;
>
> @property (nonatomic,copy) NSColor* pFrameColor;
> @property (nonatomic,copy) NSColor* pPaneColor;
>
> @property (nonatomic,assign) CGFloat pFrameLineWidth;
> @property (nonatomic,assign) NSSize pFrameInsetSize;
>
> -(void) setDrawFrame:(BOOL) theFlag;
> -(void) setDrawPane:(BOOL) theFlag;
> -(void) setFrameColor:(NSColor*) theColor;
> -(void) setPaneColor:(NSColor*) theColor;
> -(void) setFrameLineWidth:(CGFloat) theLineWidth;
> -(void) setFrameInsetSize:(NSSize) theInsetSize;
>
> @end
>
> ———————————————————————————————————————————
>
> //
> // LTWDrawFrameView.m
> //
> #import "LTWDrawFrameView.h"
>
> @implementation LTWDrawFrameView
>
> -(void) setupView
> {
> self.translatesAutoresizingMaskIntoConstraints = YES;
>
> self.pDrawFrameFlag = YES;
> self.pDrawPaneFlag = YES;
>
> self.pFrameLineWidth = 1;
> self.pFrameInsetSize = NSMakeSize(0,0);
>
> self.pFrameColor = [NSColor blackColor];
> self.pPaneColor = [NSColor whiteColor];
> }
>
> -(instancetype) initWithFrame:(CGRect) theFrameRect
> {
> self = [super initWithFrame:theFrameRect];
> if (self == nil)
> return nil;
>
> [self setupView];
>
> return self;
> }
>
> //*********************************************************************************************************
> -(instancetype) initWithCoder:(NSCoder*) theDecoder
> {
> self = [super initWithCoder:theDecoder];
> if (self == nil)
> return nil;
>
> [self setupView];
>
> return self;
> }
>
> -(void) dealloc
> {
> self.pFrameColor = nil;
> self.pPaneColor = nil;
>
> [super dealloc];
> }
>
> -(void) awakeFromNib
> {
> }
>
> -(void) drawRect:(NSRect) theRect
> {
> CGRect myRect;
>
> myRect = CGRectInset(theRect,self.pFrameInsetSize.width,self.pFrameInsetSize.height);
>
> if (self.pDrawPaneFlag == YES)
> {
> [self.pPaneColor set];
> [NSBezierPath fillRect:myRect];
> }
>
> if (self.pDrawFrameFlag == YES)
> {
> [self.pFrameColor set];
> [NSBezierPath setDefaultLineWidth:self.pFrameLineWidth];
> [NSBezierPath strokeRect:myRect];
> }
> }
Looks to me like a classic misunderstanding here of what the rectangle passed into -drawRect: is for. It tells you the rectangle that is currently being drawn to. Often, this is the same as your view’s bounds, but not necessarily. If possible, the system can optimize the area being drawn to be just a subset of your view; focusing on just the area of the window of the window that’s been marked as dirty.
The correct fix in which case is likely to be to use self.bounds in your calculations, instead of theRect.
>
> -(void) setDrawPane:(BOOL) theFlag
> {
> self.pDrawPaneFlag = theFlag;
> [self setNeedsDisplay:YES];
> }
>
> -(void) setFrameColor:(NSColor*) theColor
> {
> self.pFrameColor = theColor;
> [self setNeedsDisplay:YES];
> }
>
> -(void) setPaneColor:(NSColor*) theColor
> {
> self.pPaneColor = theColor;
> [self setNeedsDisplay:YES];
> }
>
> -(void) setFrameLineWidth:(CGFloat) theLineWidth
> {
> self.pFrameLineWidth = theLineWidth;
> [self setNeedsDisplay:YES];
> }
>
> -(void) setFrameInsetSize:(NSSize) theInsetSize
> {
> self.pFrameInsetSize = theInsetSize;
> [self setNeedsDisplay:YES];
> }
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden