سؤال

I am very new to C4 so please be gentle...

If I want to link a slider value to a label this is done with NSString stringWithFormat... e.g.:

self.mylabel.text = [NSString stringWithFormat:@"%4.2f",slider.value];

I added a stepper object as well, and now it also updates mylabel:

self.mylabel.text = [NSString stringWithFormat:@"%4.2f",stepper.value];

But it would be intuitive if the slider position follows the label value when I'm using the stepper. but .value is not an available property in UILabel... so how do I take the mylabel.text property and push that into the slider.value property without getting a datatype mismatch error?

هل كانت مفيدة؟

المحلول

This question has 2 answers, how to do it using C4 objects and how to do it with Interface Builder / UIControls. I'll show both ways, UI first so that I can compare the C4 way afterwards.

UIControl


To do this with UIControls first set up your C4WorkSpace.h header so that it has the following methods and properties:

@property (assign, nonatomic) IBOutlet UILabel *myLabel;
@property (assign, nonatomic) IBOutlet UISlider *mySlider;
@property (assign, nonatomic) IBOutlet UIStepper *myStepper;

-(IBAction)sliderWasUpdated:(UISlider *)slider;
-(IBAction)stepperWasUpdated:(UIStepper *)stepper;

Then, in your drag all three components onto your projects XIB file (i.e. a UISlider, UILabel and UIStepper). Link the action sliderWasUpdated: to the slider using the valueChanged option, and the stepperWasUpdated: action to the stepper also using the valueChanged option. You do this step by selecting C4Canvas.xib from your project then right-clicking on the yellow cube, then dragging from the actions listed in the pop-up menu to each of the objects that you recently placed on the canvas.

Next, add the following code to your C4WorkSpace.m file:

@implementation C4WorkSpace

-(void)setup {
    self.myStepper.minimumValue = 0.0f;
    self.myStepper.maximumValue = 10.0f;

    self.mySlider.minimumValue = 0.0f;
    self.mySlider.maximumValue = 10.0f;
}

-(IBAction)sliderWasUpdated:(UISlider *)slider {
    slider.value = [C4Math round:slider.value];
    self.myLabel.text = [NSString stringWithFormat:@"%4.2f",slider.value];
    self.myStepper.value = slider.value;
    [self.myLabel sizeToFit];
}

-(IBAction)stepperWasUpdated:(UIStepper *)stepper {
    self.myLabel.text = [NSString stringWithFormat:@"%4.2f",stepper.value];
    self.mySlider.value = stepper.value;
    [self.myLabel sizeToFit];
}

@end

In the setup we make sure that the min/max values of both UI objects are the same (so that we can keep them matched up).

In the stepperWasChanged: method we do two things:

  1. We use the stepper's value to set the label's text
  2. We also use the stepper's value to set the slider's value!

In the sliderWasChanged: method we do the same thing, updating the stepper, but we also round the value of the slider so that it increments in steps (just to keep things tidy).

C4Control


To do the same with C4 objects, instead of native UI objects, we set things up a little differently. First, we don't add anything to our C4Canvas.xib, instead we'll set the objects up manually.

In your C4WorkSpace.h file, add the following lines of code:

@property (readwrite, nonatomic, strong) C4Label *myLabel;
@property (readwrite, nonatomic, strong) C4Slider *mySlider;
@property (readwrite, nonatomic, strong) C4Stepper *myStepper;

-(void)sliderWasUpdated:(C4Slider *)slider;
-(void)stepperWasUpdated:(C4Stepper *)stepper;

Notice that most of this is the same except we're using C4 instead of UI prefixes. Also, we call our methods -(void) instead of -(IBAction) because we're not using Interface Builder.

Next, add the following code to your C4WorkSpace.m:

@implementation C4WorkSpace

-(void)setup {
    [self createAddObjects];
    //calibrate the min/max values
    self.myStepper.minimumValue = 0.0f;
    self.myStepper.maximumValue = 10.0f;

    self.mySlider.minimumValue = 0.0f;
    self.mySlider.maximumValue = 10.0f;
}

-(void)sliderWasUpdated:(C4Slider *)slider {
    slider.value = [C4Math round:slider.value];
    self.myLabel.text = [NSString stringWithFormat:@"%4.2f",slider.value];
    self.myStepper.value = slider.value;
    [self.myLabel sizeToFit];
}

-(void)stepperWasUpdated:(C4Stepper *)stepper {
    self.myLabel.text = [NSString stringWithFormat:@"%4.2f",stepper.value];
    self.mySlider.value = stepper.value;
    [self.myLabel sizeToFit];
}

-(void)createAddObjects {
    //set up the objects
    self.myLabel = [C4Label labelWithText:@"values"];
    self.myStepper = [C4Stepper stepper];
    self.mySlider = [C4Slider slider:CGRectMake(0, 0, 192, 44)];

    //position them
    CGPoint centerPoint = CGPointMake(self.canvas.center.x,
                                      self.canvas.center.y - 100);
    self.myStepper.center = centerPoint;

    centerPoint.y += 100;
    self.myLabel.center = self.canvas.center;

    centerPoint.y += 100;
    self.mySlider.center = centerPoint;

    //set up action bindings
    [self.mySlider runMethod:@"sliderWasUpdated:"
                      target:self
                    forEvent:VALUECHANGED];
    [self.myStepper runMethod:@"stepperWasUpdated:"
                       target:self
                     forEvent:VALUECHANGED];

    [self.canvas addObjects:@[self.myStepper,self.myLabel,self.mySlider]];
}

@end

DIFFERENCES


The major difference between the two approaches is whether or not you use Interface Builder. In the C4 approach we need to add a method called createAddObjects to our project so that our slider, label and stepper all get added to the canvas.

This method also contains the methods for binding the actions of our C4UIElements to our code, which happens in the lines:

[self.mySlider runMethod:@"sliderWasUpdated:"
                  target:self
                forEvent:VALUECHANGED];
[self.myStepper runMethod:@"stepperWasUpdated:"
                   target:self
                 forEvent:VALUECHANGED];

Once these are set up the only difference is specifying the use of C4 objects instead of UI objects, like:

-(void)sliderWasUpdated:(C4Slider *)slider {...}

instead of

-(IBAction)sliderWasUpdated:(UISlider *)slider {...}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top