【问题标题】:How to draw on a UIView with core graphics?如何在具有核心图形的 UIView 上绘图?
【发布时间】:2020-10-02 17:56:55
【问题描述】:

我不知道为什么我不能在 UIView 层上绘图。这可能吗?

我正在使用的示例代码:

@implementation Menu
UIView *window;
UIWindow *mainWindow;
CGSize viewwidth;
    viewwidth=[[UIScreen mainScreen] bounds].size;
// viewwidth.width or viewwidth.height
//My UIView
window = [[UIView alloc]initWithFrame:CGRectMake(0, 0, viewwidth.width, viewwidth.height)];
    window.backgroundColor = [UIColor whiteColor];
    window.layer.opacity = 1.0f;
    [window setNeedsDisplay];
    [mainWindow addSubview: window];

我的绘图方法drawRect:

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    CGRect rectangle = CGRectMake(0, 0, 320, 100);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 0.0);   //this is the transparent color
    CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 0.5);
    CGContextFillRect(context, rectangle);
    CGContextStrokeRect(context, rectangle);    //this will draw the border
}

我是不是做错了什么,问题是我得到一个空白的屏幕?

【问题讨论】:

  • 当您调用 addSubview 时,mainWindow 是否有效?

标签: ios objective-c core-graphics


【解决方案1】:

当您创建项目并选择使用 Storyboards 时,您将在 Interface Builder 中将 ViewController 设置为您的 Main.storyboard

使用SceneDelegates 和不使用SceneDelegates 的iOS 应用程序之间存在差异(iOS 13.0 之前的版本)。但是,当加载应用程序时,您选择的 ViewController 将被分配在您的主窗口/场景中使用。在 AppDelegate.m(iOS 13 之前)或 SceneDelegate.m(从 iOS 13 开始)中,您可以直接访问甚至将其分配给 self.window.rootViewController 属性。

继承UIViewController,它带有一个基本的UIView,可以在self.view下使用(在这个例子中是在ViewController.m中)你可以使用[self.view addSubview:yourOtherView]将更多的子视图放置到该属性中。

-(void)drawRect:(CGRect)rect 是属于UIView 的方法,会在视图设置为更新或布局时调用。但重要的是要知道,这不是您可以放置​​绘图代码的唯一方法。当您不需要重复重绘图形时,可以避免UIView:drawRect 以降低应用程序消耗的能源影响和工作量。此外,当您能够降低 CGRect 大小以在内部绘制时,工作量也会受到很大影响。

一个词来命名值.. 当值以它们所属的内容命名时,您将减少混乱的代码。因此,当您的项目变得更复杂时,将实际上是 UIView 的属性命名为“窗口”会给您带来压力。因此,您创建了一个名为 mainWindow 的本地值,而 window 已经存在。这样做时,您必须自己将 mainWindow 分配给应用程序 UIWindow 以使其可用。而您命名为 window 的 UIView 可能会让您感到困惑,而 _windowself.window 已经作为 AppDelegate 或 SceneDelegate 的一部分存在。如上所述,您有一个属于您在 Storyboard 或代码中分配的 UIViewController 的 UIView。

您的绘图代码有效。由于您选择追求透明度,您可能看不到它。

下面是一些用于比较您的 ViewController 的代码。

#import "ViewController.h"
#import "MyGraphicView.h"

@interface ViewController ()
@property (nonatomic) MyGraphicView *graphicView;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    _graphicView = [[MyGraphicView alloc] initWithFrame:self.view.frame];
    [self.view addSubview:_graphicView];
}
@end

还有一个 MyGraphicView.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyGraphicView : UIView

@end

NS_ASSUME_NONNULL_END

和对应的MyGraphicView.h

#import "MyGraphicView.h"

@implementation MyGraphicView

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
// This method is called when a view is first displayed or when an event occurs that invalidates a visible part of the view.
- (void)drawRect:(CGRect)rect {
    CGRect rectangle = CGRectMake(0, 0, 320, 100);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 0.0);
    CGContextSetRGBStrokeColor(context, 0.0, 1.0, 0.0, 0.5);
    CGContextFillRect(context, rectangle);
    CGContextStrokeRect(context, rectangle);
}

@end

【讨论】:

  • 将 CGContextSetRGBStrokeColor 设为绿色,以便查看它是否正确绘制
猜你喜欢
  • 1970-01-01
  • 2013-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多