Cocoa 移动无边界窗口,完全覆盖Web视图

Cocoa 移动无边界窗口,完全覆盖Web视图,cocoa,webview,nswindow,macos,Cocoa,Webview,Nswindow,Macos,在我的COCOA应用程序中,我实现了一个自定义的无边界窗口。窗口的内容区域完全由网络视图覆盖。我希望当用户在内容区域中单击并拖动鼠标时,此无边界窗口可以移动。我试图重写isMovableByWindowBackground,但没有用。如何解决此问题?在WebView上调用-setMovableByWindowBackround:YES并使窗口具有纹理可能会起作用。我就是这样做的 #import "BorderlessWindow.h" @implementation BorderlessWi

在我的COCOA应用程序中,我实现了一个自定义的无边界窗口。窗口的内容区域完全由网络视图覆盖。我希望当用户在内容区域中单击并拖动鼠标时,此无边界窗口可以移动。我试图重写isMovableByWindowBackground,但没有用。如何解决此问题?

在WebView上调用-setMovableByWindowBackround:YES并使窗口具有纹理可能会起作用。

我就是这样做的

#import "BorderlessWindow.h"


@implementation BorderlessWindow

@synthesize initialLocation;

- (id)initWithContentRect:(NSRect)contentRect
            styleMask:(NSUInteger)windowStyle
              backing:(NSBackingStoreType)bufferingType
                defer:(BOOL)deferCreation
{
if((self = [super initWithContentRect:contentRect 
                                  styleMask:NSBorderlessWindowMask 
                              backing:NSBackingStoreBuffered 
                                defer:NO]))
{
    return self;
}

return nil;
}

- (BOOL) canBecomeKeyWindow
{
return YES;
}

- (BOOL) acceptsFirstResponder
{
return YES;
}

- (NSTimeInterval)animationResizeTime:(NSRect)newWindowFrame
{
return 0.1;
}

- (void)sendEvent:(NSEvent *)theEvent
{
if([theEvent type] == NSKeyDown)
{
    if([theEvent keyCode] == 36)
        return;
}

if([theEvent type] == NSLeftMouseDown)
    [self mouseDown:theEvent];
else if([theEvent type] == NSLeftMouseDragged)
    [self mouseDragged:theEvent];

[super sendEvent:theEvent];
}


- (void)mouseDown:(NSEvent *)theEvent
{    
self.initialLocation = [theEvent locationInWindow];
}

- (void)mouseDragged:(NSEvent *)theEvent 
{
NSRect screenVisibleFrame = [[NSScreen mainScreen] visibleFrame];
NSRect windowFrame = [self frame];
NSPoint newOrigin = windowFrame.origin;

NSPoint currentLocation = [theEvent locationInWindow];
if(initialLocation.y > windowFrame.size.height - 40)
{
    newOrigin.x += (currentLocation.x - initialLocation.x);
    newOrigin.y += (currentLocation.y - initialLocation.y);

    if ((newOrigin.y + windowFrame.size.height) > (screenVisibleFrame.origin.y + screenVisibleFrame.size.height))
    {
        newOrigin.y = screenVisibleFrame.origin.y + (screenVisibleFrame.size.height - windowFrame.size.height);
    }

    [self setFrameOrigin:newOrigin];
}
}


@end
和.h文件:

#import <Cocoa/Cocoa.h>
@interface BorderlessWindow : NSWindow {
NSPoint initialLocation;
}

- (id)initWithContentRect:(NSRect)contentRect
            styleMask:(NSUInteger)windowStyle
              backing:(NSBackingStoreType)bufferingType
                defer:(BOOL)deferCreation;

 @property (assign) NSPoint initialLocation;

 @end
#导入
@界面边界swindow:NSWindow{
点初始位置;
}
-(id)initWithContentRect:(NSRect)contentRect
styleMask:(整数)窗口样式
backing:(NSBackingStoreType)bufferingType
延迟:(BOOL)延迟创建;
@属性(分配)NSPoint初始位置;
@结束

由于这是Google上最热门的内容……提供的方法对我不起作用,因为WKWebView会在鼠标事件到达窗口之前拦截鼠标事件。我不得不创建WKWebView的一个子类,并在那里完成工作(例如h/t)

我使用Xamarin,但代码非常简单……以下是一些重要信息:

//您可以在离窗口顶部多远的地方抓取窗口
//开始拖动…标题栏的高度,基本上
公共Int32 DragableAreaHeight{get;set;}=28;
公共覆盖无效鼠标向下移动(NSEvent theEvent)
{
base.MouseDown(theEvent);
var clickLocation=theEvent.location在窗口中;
var windowHeight=Window.Frame.Height;
如果(单击location.Y>(窗口高度-可拖动区域高度))
_DragShouldRespositionWindow=true;
}
公共覆盖无效鼠标(NSEvent theEvent)
{
基本鼠标(theEvent);
_DragShouldRespositionWindow=false;
}
公共覆盖无效鼠标标记(NSEvent theEvent)
{
底部。鼠标标记(theEvent);
如果(_DragShouldWindow)
{
此.Window.performindowdrag(事件);
}
}

@starkos在下面给出了正确答案,这只是WKWebView子类中的ObjC实现:

BOOL _dragShouldRepositionWindow = NO;

- (void)mouseDown:(NSEvent *)event {
    [super mouseDown:event];
    NSPoint loc = event.locationInWindow;
    CGFloat height = self.window.frame.size.height;
    if (loc.y > height - 28) {
        _dragShouldRepositionWindow = YES;
    }
}

- (void)mouseUp:(NSEvent *)event {
    [super mouseUp:event];
    _dragShouldRepositionWindow = NO;
}

- (void)mouseDragged:(NSEvent *)event {
    [super mouseDragged:event];
    if (_dragShouldRepositionWindow) {
        [self.window performWindowDragWithEvent:event];
    }
}

有关如何操作标题栏的更多信息,请参见

谢谢您的帮助。通过覆盖NSWindow的sendEvent方法,我可以使窗口可移动。@fz300您能发布您的解决方案吗?哦,伙计,这非常有效!谢谢我还将为这个问题添加一个ObjC实现,但这是正确的答案。