Allow click and dragging a view to drag the window itself?

后端 未结 8 1657
醉梦人生
醉梦人生 2020-12-29 06:06

I\'m using a textured window that has a tab bar along the top of it, just below the title bar.

I\'ve used -setContentBorderThickness:forEdge: on the window to make t

相关标签:
8条回答
  • 2020-12-29 06:31

    Have you tried overriding the NSView method mouseDownCanMoveWindow to return YES?

    0 讨论(0)
  • 2020-12-29 06:33

    When you set property isMovableByWindowBackground in viewDidLoad, it may not work because the window property of the view is not yet set. In that case, try this:

    override func viewDidAppear() {
        self.view.window?.isMovableByWindowBackground = true
    }
    
    0 讨论(0)
  • 2020-12-29 06:36

    As of macOS 10.11, the simplest way to do this is to utilize the new -[NSWindow performWindowDragWithEvent:] method:

    @interface MyView () {
        BOOL movingWindow;
    }
    @end
    
    @implementation MyView
    
    ...
    
    - (BOOL)mouseDownCanMoveWindow
    {
        return NO;
    }
    
    - (void)mouseDown:(NSEvent *)event
    {
        movingWindow = NO;
    
        CGPoint point = [self convertPoint:event.locationInWindow
                                  fromView:nil];
    
        // The area in your view where you want the window to move:
        CGRect movableRect = CGRectMake(0, 0, 100, 100);
    
        if (self.window.movableByWindowBackground &&
            CGRectContainsPoint(movableRect, point)) {
    
            [self.window performWindowDragWithEvent:event];
            movingWindow = YES;
            return;
        }
    
        // Handle the -mouseDown: as usual
    }
    
    - (void)mouseDragged:(NSEvent *)event
    {
        if (movingWindow) return;
    
        // Handle the -mouseDragged: as usual
    }
    
    @end
    

    Here, -performWindowDragWithEvent: will handle the correct behavior of not overlapping the menu bar, and will also snap to edges on macOS 10.12 and later. Be sure to include a BOOL movingWindow instance variable with your view's private interface so you can avoid -mouseDragged: events once you determined you don't want to process them.

    Here, we are also checking that -[NSWindow movableByWindowBackground] is set to YES so that this view can be used in non-movable-by-window-background windows, but that is optional.

    0 讨论(0)
  • 2020-12-29 06:37

    It's quite easy:

    override mouseDownCanMoveWindow property

    override var mouseDownCanMoveWindow:Bool {
        return false
    }
    
    0 讨论(0)
  • 2020-12-29 06:46

    I tried the mouseDownCanMoveWindow solution (https://stackoverflow.com/a/4564146/901641) but it didn't work for me. I got rid of that method and instead added this to my window subclass:

    - (BOOL)isMovableByWindowBackground {
        return YES;
    }
    

    which worked like a charm.

    0 讨论(0)
  • 2020-12-29 06:47

    I found this here:

    -(void)mouseDown:(NSEvent *)theEvent {    
        NSRect  windowFrame = [[self window] frame];
    
        initialLocation = [NSEvent mouseLocation];
    
        initialLocation.x -= windowFrame.origin.x;
        initialLocation.y -= windowFrame.origin.y;
    }
    
    - (void)mouseDragged:(NSEvent *)theEvent {
        NSPoint currentLocation;
        NSPoint newOrigin;
    
        NSRect  screenFrame = [[NSScreen mainScreen] frame];
        NSRect  windowFrame = [self frame];
    
        currentLocation = [NSEvent mouseLocation];
        newOrigin.x = currentLocation.x - initialLocation.x;
        newOrigin.y = currentLocation.y - initialLocation.y;
    
        // Don't let window get dragged up under the menu bar
        if( (newOrigin.y+windowFrame.size.height) > (screenFrame.origin.y+screenFrame.size.height) ){
            newOrigin.y=screenFrame.origin.y + (screenFrame.size.height-windowFrame.size.height);
        }
    
        //go ahead and move the window to the new location
        [[self window] setFrameOrigin:newOrigin];
    }
    

    It works fine, though I'm not 100% sure I'm doing it correctly. There's one bug I've found so far, and that's if the drag begins inside a subview (a tab itself) and then enters the superview (the tab bar). The window jumps around. Some -hitTest: magic, or possibly even just invalidating initialLocation on mouseUp should probably fix that.

    0 讨论(0)
提交回复
热议问题