首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将NSAffineTransform应用于NSView

将NSAffineTransform应用于NSView
EN

Stack Overflow用户
提问于 2019-02-03 09:21:59
回答 2查看 512关注 0票数 2

我想对一个NSView子类做几个简单的转换,把它翻转到X轴、Y轴或者两者兼而有之。我是一个经验丰富的iOS开发人员,但我不知道如何在macOS中实现这一点。我已经创建了一个具有所需翻译和缩放的NSAffineTransform,但无法确定如何将其实际应用于NSView。唯一可以接受任何类型转换的属性是[[NSView layer] transform],但这需要一个CATransform3D。

我唯一的成功是使用转换来翻转图像,如果是一个NSImageView,方法是在一个新的空NSImage上调用lockFocus,创建转换,然后在锁定的图像中绘制未翻转的图像。然而,这远不能令人满意,因为它不处理任何子视图,而且可能比直接将转换应用到NSView/NSImageView要花费更多。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-03 10:38:12

这就是解决办法:

代码语言:javascript
复制
- (void)setXScaleFactor:(CGFloat)xScaleFactor {
    _xScaleFactor = xScaleFactor;
    [self setNeedsDisplay];
}

- (void)setYScaleFactor:(CGFloat)yScaleFactor {
    _yScaleFactor = yScaleFactor;
    [self setNeedsDisplay];
}

- (void)drawRect:(NSRect)dirtyRect {
    NSAffineTransform *transform = [[NSAffineTransform alloc] init];
    [transform scaleXBy:self.xScaleFactor yBy:self.yScaleFactor];
    [transform set];

    [super drawRect:dirtyRect];
}

感谢L‘l关于使用NSGraphicsContext的提示。

票数 2
EN

Stack Overflow用户

发布于 2022-11-20 16:24:36

我不敢相信,在我能够在AppKit中水平翻转图像之前,我需要做多少个小时的搜索和实验。我不能再提这个问题和捣蛋鬼的答案了。

这里是我的解决方案的更新版本,用于横向翻转图像。此方法在NSImageView子类中实现。

代码语言:javascript
复制
override func draw(_ dirtyRect: NSRect) {
    // NSViews are not backed by CALayer by default in AppKit. Must request a layer
    self.wantsLayer = true
    if self.flippedHoriz {
        // If a horizontal flip is desired, first multiple every X coordinate by -1. This flips the image, but does it around the origin (lower left), not the center
        var trans = AffineTransform(scaledByX: -1, byY: 1)
        // Add a transform that moves the image by the width so that its lower left is at the origin
        trans.append(AffineTransform(translationByX: self.frame.size.width, byY: 0)
        // AffineTransform is bridged to NSAffineTransform, but it seems only NSAffineTransform has the set() and concat() methods, so convert it and add the transform to the current graphics context
        (trans as NSAffineTransform).concat()
    }

    // Don't be fooled by the Xcode placehoder. This must be *after* the above code
    super.draw(dirtyRect)
}

转换的行为也需要一些实验才能理解。NSAffineTransform.set()的帮助解释道:

代码语言:javascript
复制
it removes the existing transformation matrix, which is an accumulation of transformation matrices for the screen, window, and any superviews.

这很可能会破坏一些东西。由于我仍然希望尊重由窗口和超级视图应用的所有转换,所以concat()方法更合适。

concat()将现有的转换矩阵乘以自定义转换。不过,这并不完全是累积的。每次调用draw时,都会将转换应用到视图的原始转换中。所以反复调用绘图不能连续翻转图像。因此,为了不翻转图像,只需不应用转换。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54501504

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档