绘制渐变 Objective-C 的最有效方法(当前 NSColorWell 在移动颜色滑块时滞后)[关闭]

问题描述 投票:0回答:1

你好,我有一个 NSGradient,我希望使用以下代码将其绘制到矩形:

 [g drawInRect:[self bounds] angle:90];

但是问题是使用下面的方法获取 PDF 数据会产生黑色而不是渐变。

[myView dataWithPDFInsideRect:myView.bounds];

我目前的解决方案是从矩形上绘制的渐变创建一个 NSImage - 并绘制图像 - 但显然绘制的性能很差 - 特别是在更改颜色时。

我正在尝试使用渐变作为背景,您可以通过在顶部绘制的对象来更改颜色。

有没有更好的方法来绘制与 dataWithPDFInsideRect 一起使用的渐变?

我确信一定有一种有效的方法,但我显然找错了方向!

objective-c drawing core-graphics core-image nsgradient
1个回答
0
投票

很难说,没有看到更多的代码,但是,这是一个简单的例子......

启动一个新的 MacOS 应用程序项目

添加一个新的

NSView
类,名为“SimpleGradientView`:

SimpleGradientView.h

#import <Cocoa/Cocoa.h>

NS_ASSUME_NONNULL_BEGIN
@interface SimpleGradientView : NSView
@end
NS_ASSUME_NONNULL_END

SimpleGradientView.m

#import "SimpleGradientView.h"

@implementation SimpleGradientView

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];
    NSGradient *bg = [[NSGradient alloc] initWithColors:@[NSColor.redColor, NSColor.yellowColor]];
    [bg drawInRect:self.bounds angle:90.0];
}

@end

ViewController.h

#import <Cocoa/Cocoa.h>

@interface ViewController : NSViewController
@end

ViewController.m

#import "ViewController.h"
#import "SimpleGradientView.h"

@interface ViewController ()
{
    SimpleGradientView *gradView;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.preferredContentSize = NSMakeSize(600.0, 480.0);
    
    gradView = [SimpleGradientView new];
    
    // Create a button
    NSButton *button = [[NSButton alloc] initWithFrame:NSMakeRect(150, 125, 100, 50)];
    [button setTitle:@"Save as PDF"];
    [button setButtonType:NSButtonTypeMomentaryPushIn];
    [button setBezelStyle:NSBezelStyleRounded];
    [button setTarget:self];
    [button setAction:@selector(saveAsPDF:)];
    
    // Create a label
    NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(40, 20, 200, 45)];
    [label setStringValue:@"Hello, PDF!"];
    [label setBezeled:NO];
    [label setDrawsBackground:NO];
    [label setEditable:NO];
    [label setSelectable:NO];
    
    NSFontManager *fontManager = [NSFontManager sharedFontManager];
    NSFont *boldItalic = [fontManager fontWithFamily:@"Verdana"
                                              traits:NSBoldFontMask|NSItalicFontMask
                                              weight:0 size:48];
    
    // create an image view with image
    NSImage *img = [NSImage imageWithSystemSymbolName:@"apple.logo" accessibilityDescription:@""];
    NSImageView *iv = [NSImageView new];
    iv.image = img;
    iv.imageScaling = NSImageScaleProportionallyUpOrDown;
    iv.contentTintColor = NSColor.cyanColor;
    
    [label setFont:boldItalic];
    [label setTextColor:NSColor.blueColor];
    
    button.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:button];
    
    gradView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:gradView];
    
    label.translatesAutoresizingMaskIntoConstraints = NO;
    [gradView addSubview:label];
    
    iv.translatesAutoresizingMaskIntoConstraints = NO;
    [gradView addSubview:iv];
    
    [NSLayoutConstraint activateConstraints:@[
        
        [button.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:20.0],
        [button.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
        
        [gradView.topAnchor constraintEqualToAnchor:button.bottomAnchor constant:20.0],
        [gradView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:40.0],
        [gradView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-40.0],
        [gradView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor constant:-40.0],
        
        [label.topAnchor constraintEqualToAnchor:gradView.topAnchor constant:20.0],
        [label.centerXAnchor constraintEqualToAnchor:gradView.centerXAnchor],
        
        [iv.topAnchor constraintEqualToAnchor:label.bottomAnchor constant:20.0],
        [iv.centerXAnchor constraintEqualToAnchor:gradView.centerXAnchor],
        [iv.bottomAnchor constraintEqualToAnchor:gradView.bottomAnchor constant:-20.0],
        [iv.widthAnchor constraintEqualToAnchor:iv.heightAnchor],
        
    ]];
    
}

- (void)saveAsPDF:(id)sender {
    NSData *pdfData = [gradView dataWithPDFInsideRect:[gradView bounds]];
    NSSavePanel *savePanel = [NSSavePanel savePanel];
    [savePanel setAllowedFileTypes:@[@"pdf"]];
    [savePanel setNameFieldStringValue:@"MyView.pdf"];
    
    [savePanel beginWithCompletionHandler:^(NSModalResponse result) {
        if (result == NSModalResponseOK) {
            NSURL *fileURL = [savePanel URL];
            [pdfData writeToURL:fileURL atomically:YES];
            NSLog(@"PDF saved to %@", fileURL);
        }
    }];
}

- (void)setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];
}

@end

运行时,它应该看起来像这样:

enter image description here

单击该按钮会将渐变视图及其子视图保存为 PDF 文件。示例:https://github.com/DonMag/SavePDFMacApp/blob/main/MyView.pdf

我在这里发布了完整的项目:https://github.com/DonMag/SavePDFMacApp


编辑

好奇......这要么是一个错误,要么是文图拉和索诺玛之间有我找不到的变化

使用

dataWithPDFInsideRect
似乎不会渲染渐变——无论是使用
drawRect
还是 使用
CAGradientLayer

生成渐变图像看起来是一种可靠的方法。

我用一个示例更新了我的 GitHub 存储库。

© www.soinside.com 2019 - 2024. All rights reserved.