i try to set a value to a slider after a button click,
but it does not work - the slider does not move. the code runs fine without mistakes.
It should be pretty simple but I can't figure it out.
xCode Version 4.5.2
Thanks!
here my code:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *debugLabel;
#property (weak, nonatomic) IBOutlet UISlider *slider;
- (IBAction)slider:(id)sender;
- (IBAction)ButtonChangeValue:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize slider;
...
- (IBAction)slider:(UISlider *)sender {
float value = [sender value];
self.debugLabel.text = [NSString stringWithFormat:#"Value: %f",value];
}
- (IBAction)ButtonChangeValue:(id)sender {
slider.value = 90;
}
I think your problem is that the slider accepts values between 0.0 and 1.0 (default values, change them with _slider.maximumValue and _slider.minimumValue). Try setting the value to 0.9 instead of setting 90 (if you mean 90%).
If the slider updates but is not animated, use :
[_slider setValue:0.9 animated:YES];
Note that given your code, you may need to use self.slider instead of _slider.
try using
self.slider.value = 90;
instead of
slider.value = 90;
Check My Answer
- (void)viewDidLoad
{
UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(sliderTapped:)];
[slider addGestureRecognizer:gr];
}
- (void)sliderTapped:(UIGestureRecognizer *)g
{
UISlider* s = (UISlider*)g.view;
if (s.highlighted)
return; // tap on thumb, let slider deal with it
CGPoint pt = [g locationInView: s];
CGFloat percentage = pt.x / s.bounds.size.width;
CGFloat delta = percentage * (s.maximumValue - s.minimumValue);
CGFloat value = s.minimumValue + delta;
[s setValue:value animated:YES];
NSString *str=[NSString stringWithFormat:#"%.f",[self.slider value]];
self.lbl.text=str;
}
To use slider.value = 90;
Your ViewController.h should be:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
{
UISlider *slider;
}
#property (weak, nonatomic) IBOutlet UILabel *debugLabel;
#property (weak, nonatomic) IBOutlet UISlider *slider;
- (IBAction)slider:(id)sender;
- (IBAction)ButtonChangeValue:(id)sender;
#end
And don't forget #synthesize slider; in your ViewController.m as well.
Otherwise, use self.slider.value = 90; or _slider.value = 90;
For Swift, you can use:
slider.setValue(5.0, animated: true)
Since you are using interface builder first thing to look at would be: are the UI components (slider, button) connected to the IBOutlets in File's owner. This is the most common source of problems like this.
Then check the min and max of the slider (default is 0;1 - as rdurand mentioned).
And spider1983 is correct also: since slider is a property, you can address it as self.slider (or _slider, but you shouldn't use the last one in this case).
i think . as you have not mentioned maximum and minimum value of slider ,it is taking default max and min values that are 0 to 1. So it is not possible to set value =90. First change its max and min like this :
Slider.minimumValue = 1;
Slider.maximumValue = 100;
now try your thing ,
Slider.value =90;
Within view
#State private var value1: Double = 0.9
Then make reference
Slider(value: $value1)
Related
I tried to control the num variable through UIStepper, but when I pressed the increase button,
It always start count from 0 not 10,
I am curious what did I miss in my code,
Thank you in advance for any comments
#import "ViewController.h"
int num = 10;
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UILabel *myLabel;
- (IBAction)myStepper:(UIStepper *)sender;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_myLabel.text = [NSString stringWithFormat:#"%i", num];
}
- (IBAction)myStepper:(UIStepper *)sender {
num = [sender value];
_myLabel.text = [NSString stringWithFormat:#"%i", num];
}
#end
You're never setting the value of the stepper to num. Either set it in Interface Builder's Attributes Inspector, or create an outlet to your stepper:
#property (weak, nonatomic) IBOutlet UIStepper myStepper;
And then in -viewDidLoad, set it like this:
self.myStepper.value = num
As an aside, I would recommend against using a global variable. I would make a property for num instead.
I am not sure is this even possible, but I will ask anyway.
This is my ViewController.h
#interface TBL_GameViewController : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *roundText;
#property (strong, nonatomic) IBOutlet UILabel *roundNumber;
#property (strong, nonatomic) IBOutlet UILabel *playerText;
#property (strong, nonatomic) IBOutlet UILabel *playerScore;
#property (strong, nonatomic) IBOutlet UILabel *computerText;
#property (strong, nonatomic) IBOutlet UILabel *computerScore;
#end
And this is one method from .m file
- (void) lablesHiden:(BOOL)on
{
self.roundText.hidden = on;
self.roundNumber.hidden = on;
self.playerText.hidden = on;
self.playerScore.hidden = on;
self.computerText.hidden = on;
self.computerScore.hidden = on;
}
All this is working file.
Question
is the some way to a access all available labels in my view controller programmatically ?
Reason why I am asking this is:
I will have around 10 methods that will need access these labels, to change various properties (color, text, ...).
If tomorrow I add more label, I will also need add new label to all those methods and I would like to avoid that ?
UPDATE
I the end I used this approach
- (NSArray*) getAllLabels
{
NSArray *labels = [[NSArray alloc] initWithObjects:self.roundText, self.roundNumber, self.playerText, self.playerScore, self.computerText, self.computerScore, nil];
return labels;
}
- (void) appear:(BOOL)on
{
for (UILabel *label in [self getAllLabels]) {
label.alpha = 0.0;
}
// more code
}
There absolutely is a way:
for (id label in self.view.subviews) {
if ([label isKindOfClass:[UILabel class]]) {
// do your stuff...
}
}
You get more granular control about which labels to address by using tags. This is also cleaner than doing class introspection.
For example:
#define kPlayer 100
#define kRound 200
#define kComputer 300
#define kText 10
#define kNumber 20
You assign tags e.g. in viewDidLoad like this:
roundText.tag = kRound + kText;
Now there is no need to iterate through all subviews (you just have one iteration per transaction).
for (int x = 100; x < 400; x += 100) {
for (int y = 10; y < 30; y += 10) {
UILabel *label = (UILabel*) [self.view viewWithTag:x+y];
// do something with label
}
}
You can see that you can very conveniently exclude certain labels if you need to.
Also, via KVC, all labels can be accessed like this:
[self.view.subviews filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:#"tag > 99"]];
I'm very new to Objective-C and iOS development in general. This week I managed to get a small app running correctly in the simulator after large efforts.
I've pickup basics of the programming language by reading in "iOS 7 Programming Fundamentals" by Matt Neuburg, instructions from tutorials online and from suggestions on this website.
I've written code that works (apparently), but I do not fully understand why I needed to make several adjustments in my code to make it work.
The app is a basic one which solves a "wind triangle" for your information. All it needs to do, is putting some user defined variables in the correct formula, and display the outcome.
I've copied the .h and .m file. Simply said: the .h declares 7 variables; 5 user inputs in a textfield; 2 labels to display 2 calculated outcomes; one button which initiates the action to calculate.
With following code, I do not understand:
why I was forced to state my variables preceded by a underscore to use in the implementation
why I was forced to declare .delegate to 'self' for the variables after loading the view
Any suggestions to make this 'app' more logical and easier to understand (by myself) ?
//
// ViewController.h
// WindTriangle
//
#import <UIKit/UIKit.h>
#define M_PI 3.14159265358979323846264338327950288 /* pi */
float windDegreesFloat;
float windSpeedFloat;
float courseDesiredFloat;
float trueAirSpeedFloat;
float magneticVariationFloat;
float headingCalculatedFloat;
float groundSpeedCalculatedFloat;
#interface ViewController : UIViewController<UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextView *instructionsText;
#property (weak, nonatomic) IBOutlet UITextField *windDegrees;
#property (weak, nonatomic) IBOutlet UITextField *windSpeed;
#property (weak, nonatomic) IBOutlet UITextField *courseDesired;
#property (weak, nonatomic) IBOutlet UITextField *trueAirSpeed;
#property (weak, nonatomic) IBOutlet UITextField *magneticVariation;
#property (weak, nonatomic) IBOutlet UILabel *headingCalculated;
#property (weak, nonatomic) IBOutlet UILabel *groundSpeedCalculated;
- (IBAction)calculatePressed:(id)sender;
#end
And
//
// ViewController.m
// WindTriangle
//
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.windDegrees.delegate = self;
self.windSpeed.delegate = self;
self.courseDesired.delegate = self;
self.trueAirSpeed.delegate = self;
self.magneticVariation.delegate = self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)calculatePressed:(id)sender {
windDegreesFloat = [_windDegrees.text floatValue];
windSpeedFloat = [_windSpeed.text floatValue];
courseDesiredFloat = [_courseDesired.text floatValue];
trueAirSpeedFloat = [_trueAirSpeed.text floatValue];
magneticVariationFloat = [_magneticVariation.text floatValue];
headingCalculatedFloat = ( courseDesiredFloat - magneticVariationFloat ) + ( 180 / M_PI ) * asin(( windSpeedFloat / trueAirSpeedFloat) * sin(( M_PI * ( windDegreesFloat - ( courseDesiredFloat - magneticVariationFloat))) / 180));
NSString * headingCalculatedString = [NSString stringWithFormat:#"%.1f", headingCalculatedFloat];
_headingCalculated.text = headingCalculatedString;
groundSpeedCalculatedFloat = sqrt(pow( trueAirSpeedFloat , 2) + pow(windSpeedFloat , 2) - (2 * trueAirSpeedFloat *windSpeedFloat * cos((M_PI * ( courseDesiredFloat - windDegreesFloat + ((180 / M_PI) * asin(( windSpeedFloat / trueAirSpeedFloat ) * sin((M_PI * ( windDegreesFloat - courseDesiredFloat )) / 180))))) / 180)));
NSString * groundSpeedCalculatedString = [NSString stringWithFormat:#"%.1f", groundSpeedCalculatedFloat];
_groundSpeedCalculated.text = groundSpeedCalculatedString;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
return [textField resignFirstResponder];
}
#end
I'm brandnew to StackOverflow as well. Your comments will be much appreciated.
Hey so for your first question, the underscore indicates instance variables. Sometime back, you couldn't do this in objective c. If you declared a property, you had to call it through self.property after synthesizing it. So the underscore is just calling an instance.
As for the second question when you set the delegate in this case you're actually setting the delegate of the IBOutlet for the UITextField as the viewcontroller you're typing the code in. A delegate is responsible for the interaction between the controller and the view. This allows the view controller to manage certain methods of the UITextFieldDelegate
When you declare #property, for example:
#property (weak, nonatomic) UITextField *property;
Compiler create public variable, which you can access by self.property and private variable, which you access with underscore _property.
In your implementation you read private variable by adding underscore.
The delegate is a way for object to inform another object about something. In your example:
self.windDegrees.delegate = self;
self.windDegrees is a text field and this instruction means that this text field (windDegrees) will inform current class (ViewController) that something happened, for example method:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
return [textField resignFirstResponder];
}
will be called every time your text fields should return.
You have several things wrong here. Your .h file should be:
//
// ViewController.h
// WindTriangle
//
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextView *instructionsText;
#property (weak, nonatomic) IBOutlet UITextField *windDegrees;
#property (weak, nonatomic) IBOutlet UITextField *windSpeed;
#property (weak, nonatomic) IBOutlet UITextField *courseDesired;
#property (weak, nonatomic) IBOutlet UITextField *trueAirSpeed;
#property (weak, nonatomic) IBOutlet UITextField *magneticVariation;
#property (weak, nonatomic) IBOutlet UILabel *headingCalculated;
#property (weak, nonatomic) IBOutlet UILabel *groundSpeedCalculated;
- (IBAction)calculatePressed:(id)sender;
#end
You do not want to declare all of those unnecessary global variables. You do not need to redefine the standard M_PI macro. And you do not need to tell the world that your class conforms to the UITextField protocol.
In your .m file you should replace this:
#interface ViewController ()
#end
with:
#interface ViewController () <UITextViewDelegate, UITextFieldDelegate>
#end
Also, everywhere you reference one of the generated instance variables for one of your properties, you should change the reference to use the property instead. Example:
Change:
windDegreesFloat = [_windDegrees.text floatValue];
to:
windDegreesFloat = [self.windDegrees.text floatValue];
Do this everywhere you use the underscored variable instead of the property.
The use of self.windDegrees.delegate = self;, for example, is to tell the text field that your view controller (self) will be handling events from the text field.
Thanks for all the feedback. I changed the code with your feedback to following code.
As it worked before, it still does, but with correct(er) coding.
I'm starting to understand why I had to remove the global variables in .h, where to put correct protocol declarations, and also where the _ really stands for. Additional comments or thoughts are welcome. thx all !
//
// ViewController.h
// WindTriangle
//
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextView *instructionsText;
#property (weak, nonatomic) IBOutlet UITextField *windDegrees;
#property (weak, nonatomic) IBOutlet UITextField *windSpeed;
#property (weak, nonatomic) IBOutlet UITextField *courseDesired;
#property (weak, nonatomic) IBOutlet UITextField *trueAirSpeed;
#property (weak, nonatomic) IBOutlet UITextField *magneticVariation;
#property (weak, nonatomic) IBOutlet UILabel *headingCalculated;
#property (weak, nonatomic) IBOutlet UILabel *groundSpeedCalculated;
- (IBAction)calculatePressed:(id)sender;
#end
And
//
// ViewController.m
// WindTriangle
//
#import "ViewController.h"
#interface ViewController () <UITextViewDelegate, UITextFieldDelegate>
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.windDegrees.delegate = self;
self.windSpeed.delegate = self;
self.courseDesired.delegate = self;
self.trueAirSpeed.delegate = self;
self.magneticVariation.delegate = self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)calculatePressed:(id)sender {
float windDegreesFloat = [self.windDegrees.text floatValue];
float windSpeedFloat = [self.windSpeed.text floatValue];
float courseDesiredFloat = [self.courseDesired.text floatValue];
float trueAirSpeedFloat = [self.trueAirSpeed.text floatValue];
float magneticVariationFloat = [self.magneticVariation.text floatValue];
float headingCalculatedFloat = ( courseDesiredFloat - magneticVariationFloat ) + ( 180 / M_PI ) * asin(( windSpeedFloat / trueAirSpeedFloat) * sin(( M_PI * ( windDegreesFloat - ( courseDesiredFloat - magneticVariationFloat))) / 180));
NSString * headingCalculatedString = [NSString stringWithFormat:#"%.1f", headingCalculatedFloat];
_headingCalculated.text = headingCalculatedString;
float groundSpeedCalculatedFloat = sqrt(pow( trueAirSpeedFloat , 2) + pow(windSpeedFloat , 2) - (2 * trueAirSpeedFloat *windSpeedFloat * cos((M_PI * ( courseDesiredFloat - windDegreesFloat + ((180 / M_PI) * asin(( windSpeedFloat / trueAirSpeedFloat ) * sin((M_PI * ( windDegreesFloat - courseDesiredFloat )) / 180))))) / 180)));
NSString * groundSpeedCalculatedString = [NSString stringWithFormat:#"%.1f", groundSpeedCalculatedFloat];
_groundSpeedCalculated.text = groundSpeedCalculatedString;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
return [textField resignFirstResponder];
}
#end
I created a method to calculate a simple calculation.
I want the method to return an int and take 2 int parameters.
I created a class called calculation. I imported calculation into the viewController.m and created an action 2 textFields and a text Label. I am using this view for testing the method.
My method return 0 in the calculation. What am I doing wrong? It's so simple but I can't seem to figure out where I'm making my mistake. Here is the code.
Calculation.h
#import <Foundation/Foundation.h>
#interface Calculation : NSObject
#property (nonatomic) int odometerStart;
#property (nonatomic) int odometerEnd;
#property (nonatomic) int odometerTotal;
- (int)mileageStart:(int)start mileageEnd: (int)end;
#end
Calculation.m
#import "Calculation.h"
#implementation Calculation
#synthesize odometerEnd, odometerStart, odometerTotal;
- (int)mileageStart:(int)start mileageEnd:(int)end
{
odometerStart = start;
odometerEnd = end;
odometerTotal = end - start;
return odometerTotal;
}
#end
viewController.h
#import <UIKit/UIKit.h>
#interface MileageViewController : UIViewController
- (IBAction)calculateMileage:(id)sender;
#property (strong, nonatomic) IBOutlet UITextField *startLabel;
#property (strong, nonatomic) IBOutlet UITextField *endLabel;
#property (strong, nonatomic) IBOutlet UILabel *displayLabel;
#end
viewController.m
#import "MileageViewController.h"
#import "Calculation.h"
#implementation MileageViewController
#synthesize startLabel;
#synthesize endLabel;
#synthesize displayLabel;
- (void)viewDidUnload
{
[self setStartLabel:nil];
[self setEndLabel:nil];
[self setDisplayLabel:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (IBAction)calculateMileage:(id)sender {
Calculation *mileage = [[Calculation alloc] init];
int odomStart = [[startLabel text] intValue];
int odomEnd = [[endLabel text ] intValue];
[mileage mileageStart:odomStart mileageEnd:odomEnd];
mileage.odometerTotal = displayLabel.text.intValue;
NSLog(#"THe total is %d", mileage.odometerTotal);
My total keeps equaling 0. The calculation isn't being calculated.
Your statement is backwards. You're trying to set the value of odometerTotal to the value of your label, but you want it the other way around. It should be:
displayLabel.text = [NSString stringWithFormat:#"%d",mileage.odometerTotal];
However, mileage returns an int value, so you don't really need the odometerTotal property in your Calculation class . You could do it like this:
displayLabel.text = [NSString stringWithFormat:#"%d",[mileage mileageStart:odomStart mileageEnd:odomEnd]];
I saw the whole program, and the assignment you did seemed wrong,
the bold pointed was as below:
mileage.odometerTotal = displayLabel.text.intValue;
you want to use the calculate class to calculate the total value. while the order should be opposite.
How about this:
displayLabel.text.iniValue = mileage.odometerTotal;
then use the NSLog method to print your expected result.
I am using a UIslider to move a UIImage left and right on the screen. When the UISlider is totally on the left the image will be to a certain position on the X atis on the left of the screen, and when the slider is totally to the right, the image is on the right of the screen. If for example I want to give the image flexibility movement of 600px, how can I do that?
-(IBAction)sliderValueChanged:(UISlider *)sender
{
if (sender.value >= 0.5) {
int value;
value = sender.value * 6;
[photoView setFrame:CGRectMake(photoView.frame.origin.x + value,
PhotoView.frame.origin.y,photoView.frame.size.width,photoView.frame.size.height)];
}else{
int value;
value = sender.value * -6;
[photoView setFrame:CGRectMake(photoView.frame.origin.x + value,
photoView.frame.origin.y,photoView.frame.size.width,photoView.frame.size.height)];
}
...this was my guess
I recently had to do the same thing you're trying to do for use in a full scale aircraft where the iPad/iPhone acts as a instrument gauge.
Here is the code I used to move an image for the aircraft's instrument readout: Also, you should round the float value to an int because we are dealing with whole pixel points. (The image will still move fine with a float value, but I like using an int when dealing with pixel points.)
#import "ViewController.h"
#import <math.h>
#interface ViewController()
#property (nonatomic, strong) IBOutlet UIImageView *XAxis;
#property (nonatomic, strong) IBOutlet UISlider *XSlider;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.XSlider.minimumValue = 0.0f;
self.XSlider.maximumValue = 600.0f;
}
- (IBAction)XValueChanged:(UISlider *)XSlider;
{
int XResult = (int)floorf(XSlider.value);
self.XAxis.center = CGPointMake(self.XAxis.center.x, XResult);
NSLog(#"X Value: %d", XResult);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
How about something like this,
slider.minimumValue = 0.0f;
slider.maximumValue = 600.0f;
-(IBAction)sliderValueChanged:(UISlider *)sender
{
[photoView setFrame:CGRectMake(sender.value, PhotoView.frame.origin.y,photoView.frame.size.width,photoView.frame.size.height)];
}
You can also do this by changing photoView.frame.origin.x + value to floatValue + value where floatValue is some fixed number based on where you want to set the photoView. Also calculate value as value = sender.value * constant where constant again depends on how much you need to move it for each slider movement.
Check documentation for more details on properties