Разрешить щелчок и перетащить представление, чтобы перетащить само окно?
Я использую текстурированное окно, в котором есть панель вкладок вверху, чуть ниже строки заголовка.
Я использовал -setContentBorderThickness:forEdge:
в окне, чтобы градиент выглядел правильно, и чтобы листы выходили из правильной позиции.
Однако, что не работает, перетаскивание окна. Он работает, если я нажимаю и перетаскиваю область, которая на самом деле является строкой заголовка, но поскольку градиент полосы заголовка разливается в панель вкладок (потенциально/часто пустой), очень легко щелкнуть слишком низко, и это кажется очень расстраивающим, когда вы пытаетесь перетащить и убедитесь, что окно не двигается.
Я замечаю NSToolbar, занимая примерно такое же пространство ниже строки заголовка, что позволяет перетаскивать окно, когда курсор над ним. Как это реализовать?
Спасибо.
![Tab Bar]()
Ответы
Ответ 1
Я нашел здесь здесь:
-(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];
}
Это прекрасно работает, хотя я не уверен на 100%, что я делаю это правильно. Там есть одна ошибка, которую я нашел до сих пор, и что если перетаскивание начинается внутри подвью (сама вкладка), а затем вводится супервизор (панель вкладок). Окно прыгает. Некоторые -hitTest: магия или, возможно, даже просто недействительность initialLocation на mouseUp, вероятно, исправить это.
Ответ 2
Я попробовал решение mouseDownCanMoveWindow
(fooobar.com/questions/341618/...), но это не сработало для меня. Я избавился от этого метода и вместо этого добавил его в мой подкласс окна:
- (BOOL)isMovableByWindowBackground {
return YES;
}
который работал как шарм.
Ответ 3
Вы пытались переопределить метод NSView mouseDownCanMoveWindow
, чтобы вернуть YES
?
Ответ 4
Он работает для меня после двух шагов:
- Подкласс NSView, переопределите
mouseDownCanMoveWindow
, чтобы вернуть YES.
- Подкласс NSWindow, переопределите
isMovableByWindowBackground
, чтобы вернуть YES.
Ответ 5
Как и в macOS 10.11, самый простой способ сделать это - использовать новый метод -[NSWindow performWindowDragWithEvent:]
:
@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
Здесь -performWindowDragWithEvent:
будет обрабатывать правильное поведение, не перекрывая строку меню, а также будет привязываться к краям на macOS 10.12 и новее. Обязательно включите переменную экземпляра BOOL movingWindow
с вашим личным интерфейсом просмотра, чтобы избежать событий -mouseDragged:
после того, как вы определили, что не хотите их обрабатывать.
Здесь мы также проверяем, что для параметра -[NSWindow movableByWindowBackground]
установлено значение YES
, чтобы это представление можно было использовать в окнах без перемещения по окну, но это необязательно.
Ответ 6
Это довольно просто:
переопределить свойство mouseDownCanMoveWindow
override var mouseDownCanMoveWindow:Bool {
return false
}