0

I have an NSSegmentedControl within a draggable view (This is a much simplified test case to demonstrate the problem).

When first created everything looks ok as in this image:

Initial View

The view with the light green background is draggable. If I drag it slightly, the text in the lower NSSegmentedControl becomes "muddy", as in this image:

Control with muddy text

Also, while the view is being dragged, the text in the NSSegmentedControl flickers.

All views and controls are created in a nib, and there is no unusual code. The wantsLayer property of the view is set to YES, so that a border and background color can be displayed. This is just to make it easier to see the issue, but the problem occurs even if wantsLayer is set to NO.

The problem occurs only when the view is dragged. Dragging the main application window does not cause this effect.

This is on MacOS High Sierra 10.13.6, XCode 10.1

This is driving me crazy, so any help appreciated!

Edit: Here is the dragging code:

//
//  DraggableView.h
//

#import <Cocoa/Cocoa.h>

@interface DraggableView : NSView

@property(assign,nonatomic) NSPoint dragStart;
@property(assign,nonatomic) NSPoint startOrigin;

@end



//
//  DraggableView.m
//

#import "DraggableView.h"

@implementation DraggableView

// mouseDown - start dragging

- (void) mouseDown:(NSEvent *)theEvent {

    _dragStart = [[self superview] convertPoint:[theEvent locationInWindow] fromView:nil];
    _startOrigin = [self frame].origin;
}

// mouseDragged - move the view

- (void) mouseDragged:(NSEvent *)theEvent {

    CGPoint currentDrag = [[self superview] convertPoint:[theEvent locationInWindow] fromView:nil];

    CGPoint newOrigin = self.startOrigin;
    newOrigin.x += (currentDrag.x - _dragStart.x);
    newOrigin.y += (currentDrag.y - _dragStart.y);

    [self setFrameOrigin:newOrigin];
}

@end

All other code is standard Cocoa boilerplate for a document-based application.

The nib file defines the draggable view as an instance of the DraggableView class.

northernman
  • 1,446
  • 16
  • 19
  • You do have some dragging code, right? Would you like to share it with us? (It sounds to me like you could even post the demo project.) – matt May 27 '20 at 16:38
  • I edited the original post to include the dragging code. – northernman May 27 '20 at 21:27
  • I’m curious whether telling the superview to setNeedsDisplayInRect helps at all. – matt May 27 '20 at 21:44
  • Also make sure you end on an integral point. – matt May 27 '20 at 22:11
  • Why would setNeedsDisplayInRect have any effect, and what would I set the invalidRect to anyway? As far as I can tell, I am doing an absolutely basic drag operation that Cocoa should handle flawlessly. There is nothing fancy going on at all. Also, why should I care whether I end on an integral point? It's Cocoa's problem to deal with mapping to display coordinates - not mine. – northernman May 28 '20 at 02:35
  • Ok so no willingness even to try a suggestion? I mean it’s only an idea, it won’t blow up the computer. – matt May 28 '20 at 02:36
  • No - completely willing to try anything :-) What should I set the invalidRect to? – northernman May 28 '20 at 02:37
  • Interestingly, if I comment out mouseDragged, and just move the window a bit whenever mouseDown happens, the text remains clear even though the view is moved. So it appears to be specifically related to the mouseDragged method. – northernman May 28 '20 at 03:14

1 Answers1

0

I resolved this by changing my drag code as follows:

// mouseDragged - move the view

- (void) mouseDragged:(NSEvent *)theEvent {

    CGPoint newOrigin = self.startOrigin;
    newOrigin.x += theEvent.deltaX;
    newOrigin.y -= theEvent.deltaY;

    [self setFrameOrigin:newOrigin];

    _startOrigin = newOrigin;
}

The underlying cause of this problem was that the draggable view origin had non-integer coordinates. Thanks to Matt for pointing me in the right direction.

northernman
  • 1,446
  • 16
  • 19