Cách tốt nhất để tiếp cận vấn đề này là bắt đầu với sự hiểu biết vững chắc về không gian tọa độ.
Trước tiên, điều quan trọng là phải hiểu rằng khi chúng ta nói về "khung" của một cửa sổ, nó nằm trong không gian tọa độ của superview. Điều này có nghĩa là việc điều chỉnh tính lộn xộn của chính chế độ xem sẽ không thực sự tạo ra sự khác biệt, bởi vì chúng tôi đã không thay đổi bất kỳ thứ gì bên trong khung nhìn.
Nhưng trực giác của bạn rằng sự lộn xộn là quan trọng ở đây là chính xác.
Theo mặc định, mã của bạn, như được nhập, có vẻ như nó sẽ hoạt động; có lẽ giám sát của bạn đã bị lật (hoặc không bị lật), và nó nằm trong một không gian tọa độ khác với bạn mong đợi.
Thay vì chỉ lật và bỏ lượt xem một cách ngẫu nhiên, tốt nhất là chuyển đổi các điểm bạn đang xử lý thành không gian tọa độ đã biết.
Tôi đã chỉnh sửa mã trên của bạn để luôn chuyển đổi thành không gian tọa độ của người giám sát, bởi vì chúng tôi đang làm việc với nguồn gốc khung hình. Điều này sẽ hoạt động nếu chế độ xem có thể kéo của bạn được đặt trong trình giám sát lật hoặc không lật.
// -------------------- MOUSE EVENTS ------------------- \\
- (BOOL) acceptsFirstMouse:(NSEvent *)e {
return YES;
}
- (void)mouseDown:(NSEvent *) e {
// Convert to superview's coordinate space
self.lastDragLocation = [[self superview] convertPoint:[e locationInWindow] fromView:nil];
}
- (void)mouseDragged:(NSEvent *)theEvent {
// We're working only in the superview's coordinate space, so we always convert.
NSPoint newDragLocation = [[self superview] convertPoint:[theEvent locationInWindow] fromView:nil];
NSPoint thisOrigin = [self frame].origin;
thisOrigin.x += (-self.lastDragLocation.x + newDragLocation.x);
thisOrigin.y += (-self.lastDragLocation.y + newDragLocation.y);
[self setFrameOrigin:thisOrigin];
self.lastDragLocation = newDragLocation;
}
Thêm vào đó, tôi khuyên bạn nên refactoring mã của bạn chỉ đơn giản là đối phó với vị trí ban đầu chuột xuống, và vị trí hiện tại của con trỏ, hơn là đối phó với các vùng đồng bằng giữa các sự kiện mouseDragged. Điều này có thể dẫn đến kết quả bất ngờ xuống dòng. Thay vào đó, chỉ cần lưu trữ độ lệch giữa nguồn gốc của chế độ xem được kéo và con trỏ chuột (nơi con trỏ chuột nằm trong chế độ xem) và đặt nguồn gốc khung thành vị trí của con trỏ chuột, trừ giá trị bù trừ.
Dưới đây là một số bài đọc thêm:
Cocoa Drawing Guide
Cocoa Event Handling Guide