【问题标题】:setNeedsDisplay not calling drawRect:(CGRect)rectsetNeedsDisplay 不调用 drawRect:(CGRect)rect
【发布时间】:2012-09-17 23:10:03
【问题描述】:

我正在尝试遵循有关如何在屏幕上绘制一些形状的指南,但在应用程序启动时它工作正常,但我无法使用 setNeedsDisplay“重新绘制”这些形状我已经尝试了很多像在主线程上执行一样漂浮的东西,但它不起作用。

我的应用是由这个组成的:

我的 UIView 有它自己的类,DrawView。这是我的代码:

DrawView.h

#import <UIKit/UIKit.h>

NSInteger drawType;

@interface DrawView : UIView

-(void)drawRect:(CGRect)rect;
-(void)drawNow:(NSInteger)type;

@end

DrawView.m

#import "DrawView.h"

@implementation DrawView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)drawRect:(CGRect)rect {

    CGContextRef context = UIGraphicsGetCurrentContext();
    UIColor *color = [UIColor orangeColor];
    CGContextSetStrokeColorWithColor(context, color.CGColor);
    CGContextSetFillColorWithColor(context, color.CGColor);

    NSLog(@"Type: %i",drawType);

    switch (drawType) {
            case 0:
                CGContextMoveToPoint(context, 10, 100);
                CGContextAddLineToPoint(context, 300, 300);
                CGContextSetLineWidth(context, 2.0);
                CGContextStrokePath(context);
                break;
            case 1:
                CGContextAddEllipseInRect(context,CGRectMake(10, 100, 300,440));
                CGContextDrawPath(context, kCGPathFillStroke);
                break;
            case 2:
                CGContextAddRect(context, CGRectMake(10, 100,300,300));
                CGContextDrawPath(context, kCGPathFillStroke);
                break;
            default:
                break;
    }

}


-(void)drawNow:(NSInteger)type {
    drawType = type;
    NSLog(@"Draw Now! %i",drawType);

    //[self setNeedsDisplay]; // Not working...
    //[self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:YES]; // Not Working
}

@end

ViewController.h

#import <UIKit/UIKit.h>
#import "DrawView.h"

DrawView *mydraw;

@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UISegmentedControl *drawTypeSW;

- (IBAction)drawNow:(id)sender;
@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize drawTypeSW;

- (void)viewDidLoad
{
    [super viewDidLoad];
    mydraw = [[DrawView alloc] init];
}

- (void)viewDidUnload
{
    [self setDrawTypeSW:nil];
    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (IBAction)drawNow:(id)sender {
    [mydraw drawNow:drawTypeSW.selectedSegmentIndex];
}
@end

当我打开应用程序时,会画一条线,但是当我尝试使用按钮 Draw Now 绘制其他内容时,它不起作用,没有任何反应,并且不会调用 - (void)drawRect:(CGRect)rect。为什么?我错过了什么?

谢谢;)

【问题讨论】:

    标签: ios quartz-graphics quartz-2d cgrect


    【解决方案1】:

    进一步编辑,最终解决方案:在 viewDidLoad 中创建的 DrawView 没有作为子视图添加到 ViewController。添加以下行应使其正确显示(除了下面的其他修复):

    [self.view addSubview:mydraw];
    

    编辑:我的答案的扩展(它仍然存在,但我认为不再是问题的核心)。你声明了接口的myDraw outside(并且在 DrawView 的头文件中做类似的事情)。而不是

    DrawView *mydraw;
    
    @interface ViewController : UIViewController
    //snip
    @end
    

    尝试:

    @interface ViewController : UIViewController
    {
    DrawView *mydraw;
    }
    //snip
    @end
    

    原答案: 变量myDraw 尚未正确初始化 - UIViews 需要使用 initWithFrame(用于编程创建)或 initWithCoder(在 nib 或情节提要中)进行初始化。使用 init 创建它意味着它的框架位置/大小为 0(并且其他 UIView 功能可能未正确初始化),这反过来意味着它不会正确绘制。

    尝试 a) 在您的 nib/storyboard 中创建一个 UIView,将其转换为 DrawView,并使您的 ViewController 定义中的 drawView 字段成为该视图的出口。或者 b) 将其从您的 nib 中移除,使用 initWithFrame 创建您的 DrawView,并为其指定屏幕上的位置和大小。

    【讨论】:

    • 我将myDraw 更改为界面内部,但它仍然无法正常工作......“UIViews 需要使用 initWithFrame 初始化”是什么意思。我在 DrawView.h 的 - (id)initWithFrame:(CGRect)frame 中需要什么?谢谢;)
    • 没什么,如果你不需要任何自定义初始化。我指的是您在 ViewController.m 中实例化它的位置:mydraw = [[DrawView alloc] init]; 应该更类似于myDraw = [[DrawView alloc] initWithFrame:CGRectMake(20, 100, 200, 200)];(例如;CGRectMake 的参数确定视图出现的位置)。鉴于你说它一开始确实划清界限,我怀疑这不是问题 - 尽管它仍然是一个应该解决的问题。
    • 我已经进行了更改;)问题仍然存在。
    • 好的,在我的系统上重建你的项目,有几个问题: 1. 你截图中的淡绿色区域是用来作为 DrawView 的吗?如果是这样,是否在 Interface Builder 中指定为 DrawView 而不是 UIView? 2. 如果它在 IB 中并且应该是视图,请将 ViewController.h 中mydraw 的声明更改为名为 mydraw 的 IBOutlet 属性,并将 IB 中的视图链接到它。 3. 如果不是,那么 a) 它是什么? b) 要使您在 viewDidLoad 中创建的视图出现,您必须添加行 [self.view addSubview:mydraw];。
    • 我猜你实际上有两种观点:一种是在 IB 中创建的,另一种是你在viewDidLoad 中创建的。 IB 中的那个没有正确连接(我只能假设仍然没有,因为 2. 否则应该可以工作),所以它绘制了它的初始状态但没有响应输入。 viewDidLoad 中的那个没有被添加为子视图,所以根本没有绘制。由于我们已经更新了后一个 atm,因此您应该能够删除 IB 中的一个,并根据需要使用参数将另一个重新定位为 CGRectMake。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多