【问题标题】:setNeedsDisplay will not call drawRectsetNeedsDisplay 不会调用 drawRect
【发布时间】:2012-07-15 22:59:47
【问题描述】:

重要:

我发现了问题,但版主出于某种原因删除了它:

我尝试直接从按钮调用该函数,而不是在视图控制器中使用该函数。

我仍然不完全明白为什么它不起作用,所以我会接受这个问题的任何答案。

主帖

我想在按下 UIButton 后做一些绘图。我的绘图是在 UIView 的子类中完成的。我的 ViewController 中有这个子类的实例。我的 ViewController 中还有一个 UIButton 调用子类的函数。在我调用的那个函数中

[self setNeedsDisplay];

当我加载我的应用程序时,drawRect 会在视图加载时调用一次,但不会再次调用,尽管每次按下按钮时都会调用 setNeedsDisplay。看了很多类似的问题,都没有找到解决办法。

我将在这里发布我的所有代码:

AEViewController.h

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

@interface AEViewController : UIViewController{

IBOutlet AEGraphView *theView;

}
-(IBAction)updateAEGraphView:(id)sender;
@end

AEViewController.m

#import "AEViewController.h"

@interface AEViewController ()

@end

@implementation AEViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    theView = [[AEGraphView alloc] init];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    } 
    else {
        return YES;
    }
}
-(IBAction)updateAEGraphView:(id)sender{
    [theView UpdateView];
}

@end

AEGraphView.h

#import <UIKit/UIKit.h>

@interface AEGraphView : UIView{
    
    
    CGContextRef mainContext;
    int power;
    int multiplier;
    
    
}
-(void)prepareGraphics;
- (void) drawLineFrom:(CGPoint)p1 To:(CGPoint)p2;
-(void)UpdateView;
@end

AEGraphView.m

#import "AEGraphView.h"

@implementation AEGraphView

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


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    [self prepareGraphics];
    // Drawing code
    NSLog(@"called");
    if (power == 0) {
        [self drawLineFrom:CGPointMake(100,100) To:CGPointMake(-50, -2)];
    }
    else {
        [self drawLineFrom:CGPointMake(0, 0) To:CGPointMake(150, 150)];
    }
    [super drawRect:rect];
    
}

-(void)prepareGraphics{
    mainContext = UIGraphicsGetCurrentContext();
    CGContextSetShouldAntialias(mainContext, TRUE);
    CGContextSetLineWidth(mainContext, 2);
    CGContextSetLineCap(mainContext, kCGLineCapRound);
    
}
- (void) drawLineFrom:(CGPoint)p1 To:(CGPoint)p2{
    NSLog(@"%f,%f  to %f,%f", p1.x,p1.y,p2.x,p2.y);
    // Begin a path.
    CGContextBeginPath(mainContext);
    
    // Add a line to the path.
    CGContextMoveToPoint(mainContext, p1.x, p1.y);
    CGContextAddLineToPoint(mainContext, p2.x, p2.y);
    
    // Stroke and reset the path.
    CGContextStrokePath(mainContext);
}
-(void)UpdateView{
    if (power == 0) {
        power = 1;
    }
    else {
        power = 0;
    }
    [self setNeedsDisplay];
}
@end

【问题讨论】:

  • 请确保您的视图可见,因为-drawRect 不可见时不会触发。
  • 这不是基本的,比如不可见、未设置插座、错字等。如果以调用 setNeedsDisplay 结束的 IBAction 函数从不同的位置调用,drawRect 将不会被调用类,即使调用了 setNeedsDisplay。现在的问题是为什么需要将IBAction直接发送到AEGraphView?
  • 那么 IBAction 必须并且应该每次都以相同的方式工作(它等效于 void 类型函数)。仔细检查 nielsbot 的答案,因为 theView = [[AEGraphView alloc] init]; 看起来很可疑(如果 IBOutlet 连接正确,它应该已经被初始化/存在)并且会将视图引用替换为对不可见且不会调用 drawRect 的新引用的引用。试试NSLog("%@", self),看看你是否触发了 UIView 类的正确实例上的方法,因为它看起来不像。
  • 删除了我在我的程序中拥有的所有 [[Object alloc] init],因为它们都在界面生成器中连接并且它工作!谢谢!

标签: iphone objective-c drawrect setneedsdisplay


【解决方案1】:

解决方案是从按钮调用函数,而不是从按钮调用的视图控制器中的函数调用。

【讨论】:

    【解决方案2】:

    您确定指向自定义 UIView 的插座已连接吗?检查它是否是nil。另外,您是否确认正在调用您的函数?

    【讨论】:

    • 视图已设置好,我让它在第一次调用时绘制一些东西,如果再次调用它应该绘制其他东西。
    • 我在调用 setNeedsDisplay 的函数中有一个 NSLog,在 setNeedsDisplay 本身中有一个 NSLog,在 drawRect 中有一个 NSLog。 drawRect 中的 NSLog 被调用一次,每次按下按钮时都会调用所有其他 NSLog。
    • 您在-setNeedsDisplay-drawRect 中都调用super 吗?
    • 是的,我两个都叫 super。
    猜你喜欢
    • 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
    相关资源
    最近更新 更多