Question

Previously I asked a question in stackoverflow and that is about setNeedsDisplay cannot work. I am not a lazy guy and I have tried everything but it still cannot work. Maybe I cannot find where is the problem. Can anyone help me to find out the problem?

//viewcontroller.m
#import "ViewController.h"
@interface ViewController ()

@end

@implementation ViewController
@synthesize frequency;
- (void)viewDidLoad
{
    hi = [[cro alloc]init];
    [self.view addSubview:hi];
    CGFloat fu = frequency.value;
    [hi changefreq:fu];
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
-(IBAction)change:(id)sender
{
    CGFloat fu = frequency.value;
    [hi changefreq:fu];
}
@end
//cro.m
#import "cro.h"

@implementation cro
@synthesize fffff;
CGFloat freee;
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}
-(void)drawRect:(CGRect)rect
{

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetLineWidth(context, 1);
    CGContextSetLineJoin(context, kCGLineJoinRound);
    NSLog(@"hi i am here %f",fffff);
    const CGFloat amplitude = 200/2;
    for(CGFloat x = 0; x < 600; x += 0.5)
    {
        CGFloat y = amplitude * cosf(2 * M_PI * (x / 600) * freee) + 200;
        if(x == 0)
            CGContextMoveToPoint(context, x, y);
        else
            CGContextAddLineToPoint(context, x, y);
    }
    CGContextSetStrokeColorWithColor(context, [[UIColor greenColor] CGColor]);
    self.clearsContextBeforeDrawing = NO;
    CGContextStrokePath(context);
}
-(void)changefreq:(CGFloat)fre
{
    NSLog(@"fre= %f",fre);
    freee = fre;
    [self setNeedsDisplay];
}

@end

here is the project http://www.sendspace.com/file/lzt4b0

Was it helpful?

Solution

You initialize your view by calling [[cro alloc] init]. Since you're not calling initWithFrame: this will result in a view with zero width and height. Calling setNeedsDisplay on such a view has no effect because there is nothing to display.

Change your first line in viewDidLoad to something like

hi = [[cro alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];

(adjust the size as needed)

Alternatively, you might want to use the cro instance that you already have in your storyboard instead of instantiating a new one. The storyboard instance is the one you're seeing, the hi instance is actually invisible with your current code. (btw, if you expect other people to read your code, you might want to start using sensible variable and class names.)

OTHER TIPS

The following changes in ViewController.m ViewdidLoad method will do the fix

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    hi = [[cro alloc]initWithFrame:CGRectMake(201, 58, 414, 571)];
    [self.view addSubview:hi];
    CGFloat fu = frequency.value;
    [hi changefreq:fu];
}

If you do the following it works for me:

  • Use property instead of ivar
    • Now you access your cro instance through self.cro
    • Connect in your storyboard the view controller's outlet cro (there is already a property named like this in your uploaded project) with the subview
  • Remove in -[ViewController viewDidLoad:] the lines where you create a new cro instance and add it as a subview to self
  • Use in your cro-class the ivar fffff in -[cro changefreq:] and -[cro drawRect:]

(It's all copied from your uploaded project only with my changes)

@interface ViewController : UIViewController

@property (strong, nonatomic) IBOutlet cro *cro;
@property (strong, nonatomic) IBOutlet UISlider *frequency;
-(IBAction)change:(id)sender;
@end

@implementation ViewController
@synthesize frequency;
- (void)viewDidLoad
{
    CGFloat fu = frequency.value;
    [self.cro changefreq:fu];
    //NSLog(@"%f",hi.fffff);
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
-(IBAction)change:(id)sender
{
    CGFloat fu = frequency.value;
    [self.cro changefreq:fu];
    //[hi setNeedsDisplay];
}
@end

@interface cro : UIView
@property (nonatomic) CGFloat fffff;
-(void)changefreq:(CGFloat)fre;
@end

@implementation cro
@synthesize fffff;
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        fffff = 15;
        // Initialization code
    }
    return self;
}
-(void)drawRect:(CGRect)rect
{

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetLineWidth(context, 1);
    CGContextSetLineJoin(context, kCGLineJoinRound);
    NSLog(@"hi i am here %f",fffff);
    const CGFloat amplitude = 200/2;
    for(CGFloat x = 0; x < 600; x += 0.5)
    {
        CGFloat y = amplitude * cosf(2 * M_PI * (x / 600) * fffff) + 200;
        if(x == 0)
            CGContextMoveToPoint(context, x, y);
        else
            CGContextAddLineToPoint(context, x, y);
    }
    CGContextSetStrokeColorWithColor(context, [[UIColor greenColor] CGColor]);
    self.clearsContextBeforeDrawing = NO;
    CGContextStrokePath(context);
}
-(void)changefreq:(CGFloat)fre
{
    NSLog(@"fre= %f",fre);
    fffff = fre;
    [self setNeedsDisplay];
}

@end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top