Mac OS X Какао, переключение координат Y в глобальном пространстве координат экрана
Как мне перевернуть значение y NSPoint в перевернутое координатное пространство.
У меня есть два источника точек, оба в глобальном пространстве экрана, но один перевернут:
один из координатного пространства экрана с 0,0 = верхний левый.
один из координатного пространства экрана с 0,0 = внизу слева.
Мне нужно перевернуть второй (внизу слева), чтобы он находился в том же месте, что и первый, вверху слева. Как я могу сделать это на NSPoint или CGPoint?
4 ответа
Для Mac OSX Какао, вы можете перевернуть y
Координировать для представления, просто переопределить isFlipped
возвращать YES
для каждого просмотра:
- (BOOL)isFlipped {
return YES;
}
Если у вас несколько мониторов, общая высота глобального координатного пространства может быть больше, чем вертикальная высота на любом отдельном дисплее. Я нашел необходимым использовать следующий код (учитывая 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)
Допустим, у вас есть точка в левом нижнем координатном пространстве, которая называется "оригинальная точка". Чтобы переместить эту точку в верхнее левое координатное пространство, вы можете использовать следующий код:
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
Я думаю, что другие ответы не совсем правильные и при некоторых обстоятельствах не сработают.
См. этот пост для того, что я считаю правильным ответом.
Вот моя реализация для копирования и вставки:
#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;
}