Mac OS X Cocoa,将全局屏幕坐标系中的Y坐标翻转

3
如何将NSPoint的y值翻转到翻转的坐标空间?
我有两个点的来源,都在全局屏幕空间中,但其中一个被翻转了:
1. 一个来自于以左上角为0,0的屏幕坐标空间。 2. 一个来自以左下角为0,0的屏幕坐标空间。
我需要将第二个(左下角)翻转,使其与第一个(左上角)处于相同的空间中。如何在NSPoint或CGPoint上进行操作?
4个回答

4

对于Mac OSX Cocoa,您可以翻转视图的y坐标,只需覆盖isFlipped方法,使每个视图返回YES

- (BOOL)isFlipped {
    return YES;
}

3

如果你有多个显示器,全局坐标空间的总高度可能大于任何单个显示器的垂直高度。我发现需要使用以下代码(给定 originalPoint)来找到:

let globalHeight = screens.map {$0.frame.origin.y + $0.frame.height}.max()!
let flippedY = globalHeight - originalPoint.y
let convertedPoint = NSPoint(x: originalPoint.x, y: flippedY)

1
我认为这是错误的。据我所知,你只需要使用 zeroScreen (NSScreen.screens[0]) 进行翻转。我认为在某些情况下,这段代码会出错。 - Noah Nuebling

1
我认为其他答案并不完全正确,在某些情况下会失败。
请参见此帖子,了解我认为是正确答案的内容。
这是我用于复制粘贴的实现:
#pragma mark - Coordinate conversion

/// The *cocoa*  global "display" coordinate system starts at the bottom left of the zero screen, while the *quartz* coordinate system starts at the top left
/// We sometimes need to convert between them

/// Convenience wrappers

+ (CGPoint)flipPoint:(CGPoint)point {
    return [self cocoaToQuartzScreenSpace:NSMakeRect(point.x, point.y, 0, 0)].origin;
}

+ (CGRect)flipRect:(CGRect)rect {
    return [self cocoaToQuartzScreenSpaceConversionWithOriginFrame:rect];
}

/// Base function

+ (CGRect)cocoaToQuartzScreenSpaceConversionWithOriginFrame:(CGRect)originFrame {
    
    /// Get zero screen height
    NSScreen *zeroScreen = NSScreen.screens[0];
    CGFloat screenHeight = zeroScreen.frame.size.height;
    
    /// Extract values
    CGFloat originY = originFrame.origin.y;
    CGFloat frameHeight = originFrame.size.height;
    
    /// Get new y
    CGFloat destinationY = screenHeight - (originY + frameHeight);
    
    /// Get new frame
    CGRect destinationFrame = originFrame;
    destinationFrame.origin.y = destinationY;
    
    /// return
    return destinationFrame;
}

1
我曾经为此苦恼了一段时间。我不知道为什么苹果要把这件事搞得神秘化.. 它能用,谢谢! - soundflix

1

假设您有一个在左下坐标空间中的点,称为“originalPoint”。要将此点翻转到左上坐标空间,可以使用以下代码:

let screenFrame = (NSScreen.main()?.frame)!
let flippedY = screenFrame.size.height - originalPoint.y
let convertedPoint = NSPoint(x: originalPoint.x, y: flippedY)

我们还可以制作一个扩展程序:
extension NSPoint {

    var flipped: NSPoint {

        let screenFrame = (NSScreen.main()?.frame)!
        let screenY = screenFrame.size.height - self.y
        return NSPoint(x: self.x, y: screenY)  
    }
}

使用:

let flippedPoint = originalPoint.flipped

1
这几乎正确,但我认为应该是 NSScreen.screens [0] .frame 而不是 NSScreen.main()?.frame - Noah Nuebling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接