cocoa - NSImageViews 中的图像随机颠倒

标签 cocoa rotation nsimageview

所以,我的 Cocoa 应用程序中遇到了这个奇怪的问题。一个工具栏项,和一些 NSImageViews 只是渲染他们的图像颠倒,没有明显的原因。当我出于某种原因启动应用程序时,工具栏项目实际上是这样的(图标是在代码中分配的),然后,当我使用取景器缩放效果打开HUD时,其中包含的 ImageView 是颠倒的。

alt text

上面的图片是这种奇怪现象的屏幕截图。正如您所看到的,HUD 中的每个 NSImageView 中的“显示垃圾”项旋转得很奇怪,但 NSBrowser 中的 NSImageView 没有问题。

我该如何追踪导致此问题的原因,然后进行修复?

最佳答案

参见Mac OS X Developer Release Note - AppKit Release Notes (Snow Leopard) :

Flipped images in toolbars (New since January 2009 seed)

A common but incorrect practice is to call setFlipped:YES on an image that you plan to draw into a flipped graphics context. This is incorrect because if the image is later drawn into a normal unflipped context, the image will appear upside down. However, Leopard and earlier contained a bug in which images set on NSToolbarItem (via setImage:) would ignore their isFlipped property. SnowLeopard fixes this bug for apps compiled on SnowLeopard with the 10.6 SDK; as a result, some images which should have drawn upside down in Leopard, will begin doing so when your app is recompiled.

If you recompile your app on SnowLeopard and discover that your toolbar item images are drawing upside down, then it indicates that you are calling setFlipped:YES somewhere within your code. You should remove those calls and replace the image drawing with methods that correctly handle flipped contexts. See the discussion of setFlipped: in these Release Notes for more discussion.

回复:setFlipped:

NSImage: deprecating -[NSImage setFlipped:], adding a drawing method that respects context flippedness (New since WWDC 2008)

The flipped attribute of NSImage is widely misunderstood. We are deprecating it for SnowLeopard, and replacing its typical uses with less error-prone API.

The property describes the orientation of the internal coordinate system of the NSImage. Just as a superview never cares about the flippedness of its subviews, a user of an NSImage should not care about its flippedness.

The typical (flawed) use case is to try to call [image setFlipped:[[NSGraphicsContext currentContext] isFlipped]] just prior to drawing, but this does not accomplish the intended goal. If called before caching, then representations end up caching upside down, and the flip is absorbed into the cache. If called after caching, it has no effect-the cached representation is already supposed to incorporate any necessary flipping. In the former case, if the NSImage is drawn anywhere else later, it ends up upside down in that place, which is also confusing because the bug and the expression of the bug are far apart. Lack of understanding regarding flippedness is also frequently the source of poorly performing code, in which people make unnecessary intermediate buffers to work around perceived framework bugs. The framework behaves according to design, but contrary to expectation, and the semantics are not all that useful. It's also difficult to change the semantics of -[NSImage isFlipped], because a lot of code is very closely dependent on the current behavior. Rather than attempt this, we have deprecated the property.

We are providing a simple and correct way to draw images in a flipped or unflipped context, which is a draw method that can account for context flippedness. We are also adding a hints parameter matching the hints in -bestRepresentationForRect:context:hints:.

- (void)drawInRect:(NSRect)dstRect fromRect:(NSRect)srcRect operation:(NSCompositingOperation)op fraction:(CGFloat)alpha respectFlipped:(BOOL)respectContextIsFlipped hints:(NSDictionary *)hints;

Pass YES for respectFlipped to get the fancy new behavior. One note for those that understand the CTM and worry that this method has an odd interaction, where modifying the CTM could fail to have any effect on image drawing: This is not the case. This method branches behavior based on [[NSGraphicsContext currentContext] isFlipped]. Modifying the CTM might turn your axes upside down, but it will not alter the result of -[NSGraphicsContext isFlipped]. They're completely orthogonal.

A second valid use of -[NSImage setFlipped:] was to specify the flippedness of the context obtained via -[NSImage lockFocus]. There are cases, for example drawing directly via NSLayoutManager, that require a flipped context. To cover this case, we add

- (void)lockFocusFlipped:(BOOL)flipped;

This doesn't alter the state of the image itself, only the context on which focus is locked. It means that (0,0) is at the top left and positive along the Y-axis is down in the locked context.

关于cocoa - NSImageViews 中的图像随机颠倒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4754973/

相关文章:

cocoa - 窗口最小化后恢复 NSProgressIndicator 动画,然后恢复

java - 在java中旋转字符串中的单词

ios - 如何在旋转期间删除 UICollectionView 的淡入淡出动画?

javascript - 如何使用 atan2() 使该 div 从其一端而不是中心旋转

objective-c - 调整大小并保存 NSI​​mage?

objective-c - 使用 ImageView 快速连续显示多张图像

objective-c - cocoa 图片库窗口

c++ - Objective-C ID3 框架?

objective-c - 检查多个WebView是否已完成加载

iphone - 当应用程序卡住时跳过命令