NSView의 드래그로 창 드래그

개요


  • 지정된 커스텀 뷰로 드래그하면 윈도우의 위치를 ​​이동합니다.



    GitHub



    구현



    맞춤 보기(DraggingView)


  • 전체 코드
  • #import "DraggingView.h"
    
    @interface DraggingView()
    @property NSPoint currentPoint;
    @end
    
    @implementation DraggingView
    
    - (void)drawRect:(NSRect)dirtyRect {
        [super drawRect:dirtyRect];
        // Drawing code here.
        // 分かりやすいようにビューに色を付ける
        NSRect bounds = [self bounds];
        [[[NSColor blueColor] colorWithAlphaComponent:0.1] set];
        [NSBezierPath fillRect:bounds];
    }
    
    #pragma mark Events
    - (void)mouseDown:(NSEvent *)event {
        NSPoint p = [event locationInWindow];
        _currentPoint = [self convertPoint:p fromView:nil]; // viewの座標系に変換
        [self setNeedsDisplay:YES];
    }
    
    - (void)mouseDragged:(NSEvent *)event {
        NSPoint previousPoint = _currentPoint;
        NSPoint p = [event locationInWindow];
        _currentPoint = [self convertPoint:p fromView:nil]; // viewの座標系に変換
    
        // 移動したマウスの距離だけウィンドウの位置を移動させる
        double  distance_x   = _currentPoint.x - previousPoint.x;
        double  distance_y   = _currentPoint.y - previousPoint.y;
        NSRect  windowFrame  = self.window.frame;
        NSPoint windowOrigin = windowFrame.origin; // 現在のウィンドウ位置
        windowOrigin.x  += distance_x;
        windowOrigin.y  += distance_y;
        _currentPoint.x -= distance_x;             // ウィンドウの位置が変わったので、次のマウス移動の計算のために補正を行う
        _currentPoint.y -= distance_y;
        [self.window setFrameOrigin:windowOrigin]; // ウィンドウの位置を移動
        [self setNeedsDisplay:YES];
    }
    
    - (void)mouseUp:(NSEvent *)event {
        NSPoint p = [event locationInWindow];
        _currentPoint = [self convertPoint:p fromView:nil]; // viewの座標系に変換
        [self setNeedsDisplay:YES];
    }
    
    @end
    
  • NSViewNSResponder 를 상속하고 있으며, 이는 이벤트를 처리하는 메소드를 정의합니다.
  • 이번에는 그 중의 mouseDown mouseDragged mouseUp 를 사용합니다.
  • mouseDragged(with:)

  • - (void)mouseDown:(NSEvent *)event {
        NSPoint p = [event locationInWindow];
        _currentPoint = [self convertPoint:p fromView:nil]; // viewの座標系に変換
        [self setNeedsDisplay:YES];
    }
    
  • 마우스를 눌렀을 때 호출되는 메서드
  • 인수의 NSEvent 객체로부터 작성할 수 있는 좌표 정보는 윈도우의 것이므로, 이번은 필요 없지만, 편리성을 위해 NSView 의 좌표계로 변환하는 경우가 많다.
  • _currentPoint에 눌려진 위치를 기록하십시오
  • - (void)mouseDragged:(NSEvent *)event {
        NSPoint previousPoint = _currentPoint;
        NSPoint p = [event locationInWindow];
        _currentPoint = [self convertPoint:p fromView:nil]; // viewの座標系に変換
    
        // 移動したマウスの距離だけウィンドウの位置を移動させる
        double  distance_x   = _currentPoint.x - previousPoint.x;
        double  distance_y   = _currentPoint.y - previousPoint.y;
    
  • 드래그 전 마우스 위치는 previousPoint 에 저장
  • 드래그 후 마우스 위치를 _currentPoint 에 저장
  • 이 두 점에서 드래그 한 거리를 계산합니다.
    NSRect  windowFrame  = self.window.frame;
    NSPoint windowOrigin = windowFrame.origin; // 現在のウィンドウ位置
    windowOrigin.x  += distance_x;
    windowOrigin.y  += distance_y;
    _currentPoint.x -= distance_x;             // ウィンドウの位置が変わったので、次のマウス移動の計算のために補正を行う
    _currentPoint.y -= distance_y;
    [self.window setFrameOrigin:windowOrigin]; // ウィンドウの位置を移動
    [self setNeedsDisplay:YES];
    
  • 이동 된 거리만큼 창의 위치를 ​​변경합니다

  • 이때 _currentPoint 를 갱신해 두는 것을 잊지 않게.
  • 윈도우 위치가 변경되었기 때문에 _currentPoint 를 보완하지 않으면 다음 드래그 거리 계산 시에 어긋남이 발생한다.

  • - (void)mouseUp:(NSEvent *)event {
        NSPoint p = [event locationInWindow];
        _currentPoint = [self convertPoint:p fromView:nil]; // viewの座標系に変換
        [self setNeedsDisplay:YES];
    }
    
  • 드래그가 종료했을 때에 불리는 메소드.
  • 이번에는 필요 없음.

  • 참고


  • 힐레가스 책 18장
  • NSView 를 투명도를 바꾸어 채우는 방법
  • Change opacity for pre-defined color?

  • 좋은 웹페이지 즐겨찾기