如何将适用于UIView的视图转换应用于NSView?

时间:2013-04-14 20:09:18

标签: objective-c cocoa nsview transformation cgaffinetransform

我有一个视图转换,使任何UIView对象都遵循cocos2d节点。适用于iOS,在本例中,UIButton遵循其Box2D正文:

enter image description here

现在对于Mac我首先验证我是否正确设置了覆盖NSWindow,以便在cocos2d OpenGL视图之上绘制NSView对象。这是有效的,就像在这种情况下使用NSButton:

enter image description here

但后来我了解到NSViews没有[NSView setTransform:..]方法。我不确定这是否适用于Mac,但这就是我所做的:

// sometime after initializing the view
[nsView setWantsLayer:YES];

// every time I update transform:
nsView.layer.affineTransform = transform;

我确认该图层是非零的。我还重新验证了在启用setWantsLayer后绘制的NSView。结果令人失望,按钮在整个窗口上无处可见,它甚至看起来都没有略微偏移或镜像,它就不再存在了:

enter image description here

这将我带到转换代码。正如我所说,这是与iOS相同的代码(除了最后指定转换)。它在iOS上也是完美的(在任何方向),但在Mac OS X上没有NSView对象,我根本看不到NSView对象。

我不确定这里可能出现什么问题,也许CALayer的工作方式不同,也许我只是犯了一个非常愚蠢和明显的错误。我什么都找不到。

KKAppDelegate* ad = (KKAppDelegate*)[KTApplication sharedApplication].delegate;
float windowHeight = ad.window.frame.size.height;

float x = _position.x - _contentSize.width * _anchorPoint.x;
float y = windowHeight - (_position.y + _contentSize.height * _anchorPoint.y);

if (_ignoreAnchorPointForPosition)
{
    x += _anchorPointInPoints.x;
    y += _anchorPointInPoints.y;
}

float cx = 1, sx = 0, cy = 1, sy = 0;
if (_rotationX || _rotationY)
{
    float radiansX = CC_DEGREES_TO_RADIANS(_rotationX);
    float radiansY = CC_DEGREES_TO_RADIANS(_rotationY);
    cx = cosf(radiansX);
    sx = sinf(radiansX);
    cy = cosf(radiansY);
    sy = sinf(radiansY);
}

CGAffineTransform transform = 
    CGAffineTransformMake(cy * _scaleX, sy * _scaleX,
                          -sx * _scaleY, cx * _scaleY, x, y);

#if KK_PLATFORM_IOS
    _cocoaView.transform = transform;
#elif KK_PLATFORM_MAC
    _cocoaView.layer.affineTransform = transform;
#endif

我验证了代码运行并且x / y值是可以预期的(即没有负面位置或疯狂值)。在第一步中甚至没有执行旋转,但在第一帧的变换后仍然没有看到NSView。绘制。

我对CALayer总计n00b并将转换应用于NSView。我很感激,如果没有解决方案,那么一些关于如何调试这个的提示。谢谢!

更新

我开始尝试用小值改变图层的变换,看看会发生什么。

CGAffineTransform transform = _cocoaView.layer.affineTransform;
transform = CGAffineTransformTranslate(transform, 0.1, 0.1);
_cocoaView.layer.affineTransform = transform;

这是一个缓慢移动的NSButton。它一直向上移动到右边,但它在视图框架的边界处消失:

enter image description here

所以我认为我的问题是视图不会被转换,只是图层 - 当我转换图层时,它会快速绘制图层边界之外的视图内容,因此不再显示任何内容。 / p>

我是否正确地假设我必须直接更改视图的属性?文档也强调了这一点。我现在还不知道如何将变换应用到视图中(即我回到原点)。我尝试手动设置旋转和帧原点,但这样我就无法将旋转中心与cocos2d节点的中心(anchorPoint)对齐。

1 个答案:

答案 0 :(得分:3)

UIButtonNSButton之间存在重要差异。即使NSButton最后是NSView的子类,NSButton的渲染也是由其单元格NSButtonCell完成的。细胞被创建为NSView的“较轻”版本。正如Apple的文档所述:

  

NSCell类提供了一种显示文本或图像的机制   一个NSView对象,没有完整NSView子类的开销。它的   大多数NSControl类都大量使用它们来实现它们   内部运作。

虽然这在Mac OS X早期很有用,但现在已经不再适用了,希望Apple会在某个阶段在AppKit中改变它。

你发生的事情是细胞被旋转,然后被视图剪切,在你的情况下是按钮本身。

要解决这个问题,请将NSButton的superview图层支持,我相信剪辑会消失:

[nsView.superview setWantsLayer:YES];