0

I draw an sine wave on an UIView by using drawrect and it is linked to an UIViewController. It can draw one time when i first load the viewcontroller. I want that when I change the value of a UISlider in the ViewController,it change the frequency of sine wave. I use the setNeedsDisplay function in the IBAction but it doesn't work. Here is my code

//CROO.m
#import "CROO.h"

@implementation CROO
@synthesize frequency;
CGFloat fffff;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.frequency = fffff;
        [self setNeedsDisplay];
        // 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)setFrequency:(CGFloat)f
{
    frequency = f;
    [self hello];
    NSLog(@"fre = %f",fffff);
}
-(void)hello
{
    fffff = frequency;
    [self setNeedsDisplay];
}
@end
//CosViewController.m
#import "CosViewController.h"
@interface CosViewController ()
@end

@implementation CosViewController
@synthesize frequency,currfrelab;
@synthesize cro;
float tempfreq;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    //cro = [[CROO alloc]initWithFrame:cro.frame];
    cro = [[CROO alloc]initWithFrame:cro.frame];

    //[self.view addSubview:cro];
    [cro setFrequency:frequency.value];
    //[self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:YES];
    NSLog(@"freq = %f",cro.frequency);
    currfrelab.text = [NSString stringWithFormat:@"Frequency = %f",frequency.value];
    //[self.view setNeedsDisplayInRect:cro.frame];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
-(IBAction)updatefreq:(id)sender
{
   // cro = [[CROO alloc]init];
    CGFloat freq = [(UISlider *)sender value];
   // [self.view addSubview:cro];
    [cro setNeedsDisplay];
    //[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];
    currfrelab.text = [NSString stringWithFormat:@"Frequency = %f",freq];
    //[self.view performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:YES];

}
@end
Vineet Singh
  • 4,009
  • 1
  • 28
  • 39
IvyBB
  • 60
  • 7
  • PS it can use the data of initial slider value to gene the wave.So that the CROO class can get the value. – IvyBB Apr 23 '13 at 16:02

2 Answers2

0

Init is only called once on well, init. Call setNeedsDisplay from the other controller to pop the drawRect again.

Mark McCorkle
  • 9,349
  • 2
  • 32
  • 42
  • Then what should I change? – IvyBB Apr 23 '13 at 15:57
  • I have add a function to test setNeedsDisplay but it still no work. -(IBAction)testing:(id)sender { [cro setFrequency:10]; [cro setNeedsDisplay]; } I click a button and call this function – IvyBB Apr 23 '13 at 16:07
  • Are you trying to call setNeedsDisplay from the same view? You need to be calling it from your viewController. Something like [otherView setNeedsDisplay]; – Mark McCorkle Apr 23 '13 at 16:42
  • If that doesn't work then the problem lyes in how you created the instance of the UIView you are trying to redraw. Create a property for it then call setNeedsDisplay on that property. – Mark McCorkle Apr 23 '13 at 16:44
  • how to create a property for it? – IvyBB Apr 23 '13 at 18:30
0
-(IBAction)updatefreq:(id)sender
{
   // cro = [[CROO alloc]init];
    CGFloat freq = [(UISlider *)sender value];
    **[cro setFrequency:freq];**
   // [self.view addSubview:cro];
    [cro setNeedsDisplay];
    //[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];
    currfrelab.text = [NSString stringWithFormat:@"Frequency = %f",freq];
    //[self.view performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:YES];

}
BhushanVU
  • 3,455
  • 1
  • 24
  • 33
  • is value of frequency coming correctly inside drawrect...cause only then you will see sine wave changing... – BhushanVU Apr 24 '13 at 05:07
  • I have checked that the value frequency and fffff is changed in the class UIView.But it cannot go into drawrect... what can i do? – IvyBB Apr 24 '13 at 05:25
  • cro = [[CROO alloc]initWithFrame:cro.frame]; here your cro object is not initialized still you are providing cro.frame... make it like below cro = [[CROO alloc]initWithFrame:CGRectMake(rect you want)]; – BhushanVU Apr 24 '13 at 06:07
  • (rect you want) should be the size of the cro uiview? btw it still doesn't work when I use cro = [[CROO alloc]init]; – IvyBB Apr 24 '13 at 06:46