所以,我在Cocoa应用程序中遇到了这个奇怪的问题。一个工具栏项和一些NSImageViews只是将它们的图像颠倒过来,没有明显的原因。当我因某种原因启动应用程序(图标在代码中分配)时,工具栏项实际上是这样的,然后,当我用取景器缩放效果打开我的HUD时,其中包含的imageViews是颠倒的。
上面的图片是这种奇怪现象的屏幕截图。你可以看到,“显示垃圾”项目奇怪地旋转,HUD中的每个NSImageView,但NSBrowser中的NSImageView都没问题。
我如何追踪造成这种情况的原因,然后修复它?
答案 0 :(得分:13)
请参阅Mac OS X Developer Release Note - AppKit Release Notes (Snow Leopard):
翻转工具栏中的图片(自此以后新增) 2009年1月种子)
常见但不正确的做法是 在图像上调用
setFlipped:YES
你计划画一个翻转 图形上下文。这是不正确的 因为如果稍后绘制图像 进入一个正常的不受约束的背景, 图像将颠倒显示。 但是,Leopard和早期包含 设置图像的错误NSToolbarItem
(通过setImage:
)会 忽略他们的isFlipped
财产。 SnowLeopard修复了应用程序的这个错误 使用10.6在SnowLeopard上编译 SDK;结果,一些图像 应该是颠倒过来的 豹子,你的时候会开始这样做 应用程序被重新编译。如果您重新编译应用程序 SnowLeopard并发现你的 工具栏项目图像正在向上绘制 向下,然后它表明你是 在某处调用
setFlipped:YES
在你的代码中。你应该删除 那些电话和替换图像 用正确的方法绘图 处理翻转的上下文。见 在这些讨论setFlipped:
发行说明以获得更多讨论。
回复:setFlipped:
NSImage:弃用 - [NSImage setFlipped:],添加绘图方法 尊重上下文翻转(新的 自WWDC 2008以来)
NSImage
的翻转属性是 被广泛误解。我们是 为SnowLeopard弃用它,和 用更少的替代它的典型用途 容易出错的API。该属性描述了方向 的内部坐标系
NSImage
。就像一个超级视图 从不关心翻转 它的子视图,NSImage
的用户 不应该关心它的翻转。典型(有缺陷的)用例是 尝试在之前致电
[image setFlipped:[[NSGraphicsContext currentContext] isFlipped]]
画画,但事实并非如此 实现预期目标。如果 然后在缓存之前调用 表示最终缓存上行 向下,翻转被吸收进去 缓存。如果在缓存后调用, 它没有效果 - 缓存 表示已经应该 包含任何必要的翻转。 在前一种情况下,如果NSImage
是 在其他地方以后绘制,它结束了 在那个的地方颠倒了,这是 因为虫子而且令人困惑 这个虫子的表达相距甚远。 对...缺乏了解 翻转也常常是 代码表现不佳的代码来源 哪些人不必要 中间缓冲区来解决 感知框架错误。该 框架根据设计行事, 但与期望相反,而且 语义并不是那么有用。 这也很难改变-[NSImage isFlipped]
的语义, 因为很多代码非常紧密 取决于当前的行为。 我们不是试图这样做 弃用了该财产。我们提供的是简单而正确的 在翻转或绘制图像的方式 不受限制的上下文,这是一个平局 可以解释上下文的方法 flippedness。我们还加了一个 提示参数匹配
-bestRepresentationForRect:context:hints:
中的提示。
- (void)drawInRect:(NSRect)dstRect fromRect:(NSRect)srcRect operation:(NSCompositingOperation)op fraction:(CGFloat)alpha respectFlipped:(BOOL)respectContextIsFlipped hints:(NSDictionary *)hints;
为
YES
传递respectFlipped
以获得奇特的新行为。一 请注意那些了解CTM的人 并担心这种方法有一个奇怪的 交互,修改CTM 可能不会对图像产生任何影响 绘图:事实并非如此。这个 方法分支行为基于[[NSGraphicsContext currentContext] isFlipped]
。修改CTM可能会 翻转你的轴,但它 不会改变结果-[NSGraphicsContext isFlipped]
。他们是完全正交的。
-[NSImage setFlipped:]
的第二个有效用途是指定 获得的上下文的翻转 通过-[NSImage lockFocus]
。有 例如,直接绘图 通过NSLayoutManager
,需要一个 翻转上下文。为了涵盖这种情况, 我们添加
- (void)lockFocusFlipped:(BOOL)flipped;
这不会改变状态 图像本身,只有上下文 哪个焦点被锁定。这意味着 (0,0)位于左上方且为正数 沿着Y轴向下锁定 上下文。
答案 1 :(得分:3)
我头脑中的猜测是,图片错误地调用了-setFlipped:YES
。