I am pretty new to objective c. I have looked through a ton of questions on stack overflow to try to find an answer but nothing has helped, so I appreciate any help anyone can offer.
I am trying to make an app that will have the picker view load from my array of 51 numbers. a random object will be generated from the array and if the user selects that object from the picker, an alert will show. I'm going to make a simple little guessing game, but for now I just have the picker that loads but is blank with no text. The alerts do work tho.
I have already assigned datasource and delegate to picker view on the view controller.
I need help figuring out why my picker view is not loading my array and what I can do to fix it. Thank you
here is my h file:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>
#property (strong, nonatomic) IBOutlet UIPickerView *picker;
#end
here is m file:
#import "ViewController.h"
#interface ViewController ()
#property NSArray *numbers;
#property NSString * selection;
#property NSString *randomObject;
#property NSInteger rnd;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor darkGrayColor];
[_numbers arrayByAddingObjectsFromArray:_numbers];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger)component{
return _numbers.count;
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
_numbers = #[#0,#1,#2,#3,#4,#5,#6,#7,#8,#9,#10,#11,#12,#13,#14,#15,#16,#17,#18,#19,#20,#21,#22,#23,#24,#25,#26,#27,#28,#29,#30,#31,#32,#33,#34,#35,#36,#37,#38,#39,#40,#41,#42,#43,#44,#45,#46,#47,#48,#49,#50];
//create random object from array
_rnd = arc4random() % ([_numbers count]);
_selection = [NSString stringWithFormat:#"%ld",(long)row];
_randomObject = [_numbers objectAtIndex:self.rnd];
NSLog(#"%#",self.randomObject);
//strings for alerts
NSString *right = [[NSString alloc]initWithFormat:#"You Guessed Right! Congratulations you've earned 3 points!"];
NSString *oneOff = [[NSString alloc]initWithFormat:#"You were so close! Only 1 off! The number was %lu. Congratulations you've earned 2 points!",(unsigned long)self.rnd];
NSString *twoOff = [[NSString alloc]initWithFormat:#"You were so close! Only 2 off! The number was %lu. Congratulations you've earned 1 point!",(unsigned long)self.rnd];
NSString *threeOff = [[NSString alloc]initWithFormat:#"Nice try! You were 3 off. The number was %lu. You earned -1 point.",(unsigned long)self.rnd];
NSString *fourOff = [[NSString alloc]initWithFormat:#"Good try! You were 2 off. The number was %lu. You earned -2 points.",(unsigned long)self.rnd];
NSString *fiveOff = [[NSString alloc]initWithFormat:#"You were no where close! The number was %lu. You earned -3 points!",(unsigned long)self.rnd];
//alerts for guesses
UIAlertView *rightAlert = [[UIAlertView alloc]initWithTitle:#"Spot On!" message:right delegate:nil cancelButtonTitle:#"Sweet!" otherButtonTitles:nil, nil];
UIAlertView *oneOffAlert = [[UIAlertView alloc]initWithTitle:#"Only one off!" message:oneOff delegate:nil cancelButtonTitle:#"Ok!" otherButtonTitles:nil, nil];
UIAlertView *twoOffAlert = [[UIAlertView alloc]initWithTitle:#"Only Two Off!" message:twoOff delegate:nil cancelButtonTitle:#"Ok!" otherButtonTitles:nil, nil];
UIAlertView *threeOffAlert = [[UIAlertView alloc]initWithTitle:#"Three Off" message:threeOff delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
UIAlertView *fourOffAlert = [[UIAlertView alloc]initWithTitle:#"Four Off" message:fourOff delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
UIAlertView *fiveOffAlert = [[UIAlertView alloc]initWithTitle:#"No Where Close!" message:fiveOff delegate:nil cancelButtonTitle:#"Ok!" otherButtonTitles:nil, nil];
NSInteger a = [_selection integerValue];
//guessed right
if (_selection == _randomObject)
{
[rightAlert show];
}
//one off
if (a == (_rnd + 1) || (a == (_rnd - 1)))
{
[oneOffAlert show];
}
//two off
if (a == (_rnd + 2) || (a == (_rnd - 2)))
{
[twoOffAlert show];
}
//three off
if (a == (_rnd + 3) || (a == (_rnd - 3)))
{
[threeOffAlert show];
}
//four off
if (a == (_rnd + 4) || (a == (_rnd - 4)))
{
[fourOffAlert show];
}
//five or more off
if ((_rnd + 5) >= a || (_rnd - 5) <= a ||(_rnd - 5) >= a || (_rnd + 5) <= a)
{
[fiveOffAlert show];
}
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return _numbers[row];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The problem is that this line
_numbers = #[#0,#1,#2,#3,#4,#5,#6,#7,#8,#9,#10,#11,#12,#13,#14,#15,#16,#17,#18,#19,#20,#21,#22,#23,#24,#25,#26,#27,#28,#29,#30,#31,#32,#33,#34,#35,#36,#37,#38,#39,#40,#41,#42,#43,#44,#45,#46,#47,#48,#49,#50];
appears in the wrong place. It is in the pickerView:didSelectRow:inComponent: method which is only called after the user has made a selection. Therefore, your _numbers array will always be empty.
Move it to the viewDidLoad method, replacing the following statement which currently hasn't any effect at all:
[_numbers arrayByAddingObjectsFromArray:_numbers];
Also, you need to change this method:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return [_numbers[row] stringValue];
}
because _numbers[row] is an NSNumber, not an NSString.
Related
I have found this solution to making the next buttons on the ui keyboard go to the next text field, however it is not working at all for me. Is there something I have to do in the storyboard as well? Also, how do I make the next button for the final textfield call the unwind segue? Thank you
//
// AddToDoItemViewController.m
// ToDoList
//
// Copyright (c) 2015 com.example. All rights reserved.
//
#import "AddToDoItemViewController.h"
#interface AddToDoItemViewController ()
#property (weak, nonatomic) IBOutlet UITextField *textField;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *saveButton;
#property (weak, nonatomic) IBOutlet UITextField *totalTextField;
#property (weak, nonatomic) IBOutlet UITextField *tipTextField;
#property (weak, nonatomic) IBOutlet UIView *singleTableView;
#property (weak, nonatomic) IBOutlet UISwitch *ccSwitch;
#end
#implementation AddToDoItemViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == self.textField) {
[self.totalTextField becomeFirstResponder];
}
else if (textField == self.totalTextField ) {
[self.tipTextField becomeFirstResponder];
}
else{
[textField resignFirstResponder];
}
return YES;
}
/*- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
if (theTextField == self.textField) {
[theTextField resignFirstResponder];
} else if (theTextField == self.totalTextField) {
[self.tipTextField becomeFirstResponder];
}
return YES;
}
*/
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
NSLog(#"sender = %#",sender);
if (sender != self.saveButton) return YES;
NSNumberFormatter *formatter1 = [[NSNumberFormatter alloc] init];
NSNumber *totalOrder = [formatter1 numberFromString:self.totalTextField.text];
NSNumber *tipOrder = [formatter1 numberFromString:self.tipTextField.text];
double tot = totalOrder.doubleValue;
double totalOrderWithTip = tipOrder.doubleValue;
if(self.textField.text.length <= 0)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Field not entered"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return NO;
}
if(self.totalTextField.text.length <= 0)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Field not entered"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return NO;
}
if(self.tipTextField.text.length <= 0)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Field not entered"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return NO;
}
if(totalOrder == nil)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Invalid Order Total"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return NO;
}
if(tipOrder == nil)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Invalid Amount Recieved"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return NO;
}
if(totalOrderWithTip < tot)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"The amount recieved must be equal to or greater than the order total."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return NO;
}
return YES;
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if (sender != self.saveButton) return;
if (self.textField.text.length > 0) {
NSNumberFormatter *formatter1 = [[NSNumberFormatter alloc] init];
// NSNumber *tipPercent = [[NSNumber alloc] initWithFloat:0.0];
NSNumber *totalOrder = [formatter1 numberFromString:self.totalTextField.text];
NSNumber *tipOrder = [formatter1 numberFromString:self.tipTextField.text];
NSNumber *actualTip = [[NSNumber alloc] initWithFloat:tipOrder.doubleValue - totalOrder.doubleValue];
double tot = totalOrder.doubleValue;
double tip1 = tipOrder.doubleValue - tot;
self.toDoItem = [[ToDoItem alloc] init];
self.toDoItem.location = self.textField.text;
NSNumber *percent1 = [[NSNumber alloc] initWithDouble:(tip1/tot)*100.0];
if(self.ccSwitch.isOn)
self.toDoItem.isCreditCard = YES;
else
self.toDoItem.isCreditCard = NO;
self.toDoItem.total = totalOrder;
self.toDoItem.tip = actualTip;
self.toDoItem.percentage = percent1;
self.toDoItem.completed = NO;
}
}
#end
In the Connections Inspector for the textField, drag from the "circle" under the section "Outlets" - "delegate", to the View Controller Icon. Or either you can set it in the viewDidLoad method. Some like:
self.textField.delegate = self;
The last textField is closing the keyboard because your are telling the keyboard to resign its first responder condition. Just replace that line for the one that you want to call:
[self shouldPerformSegueWithIdentifier:#"YOUR_IDENTIFIER" sender:your_sender];
And that's it!
This question already has an answer here:
Using text field to display an alert [closed]
(1 answer)
Closed 8 years ago.
I asked this question before but for some reason it says closed, but i never got the right answer,can anyone help me add a text field, where if the user types a number in text field once the number reaches the same number as the counter it displays an alert.
#import <UIKit/UIKit.h>
int NumberCount;
#interface ViewController : UIViewController
{
int counter;
IBOutlet UILabel *count;
}
-(IBAction)minus;
-(IBAction)plus;
-(IBAction)zero;
#end
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
-(IBAction)plus {
counter=counter + 1;
count.text = [NSString stringWithFormat:#"%i",counter];
}
-(IBAction)minus {
counter=counter - 1;
count.text = [NSString stringWithFormat:#"%i",counter];
}
-(IBAction)zero {
counter=0;
count.text = [NSString stringWithFormat:#"%i",counter];
}
- (void)viewDidLoad {
counter=0;
count.text = #"0";
[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.
}
#end
I tried adding this in but it didn't work
if (count.text == textField ) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Congrats"
message:#"You met that number"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
My ViewController.h :
__weak IBOutlet UITextField *textField;
You are comparing a string with an UITextField object.
You have to compare the count.text string with textField.text string.
Try this:
if ([count.text isEqualToString:textField.text]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Congrats"
message:#"You met that number"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
I have a picker view that has values already inside, for example one of the things inside is weather, I have a button that works with the picker view so when u pick weather and push the button an alert pops up and says Welcome to X. You selected Weather than u push OK to remove the alert, I was wondering if it was possible to after you push OK it takes you to the view controller that has the weather. I have never seen this done and this is an all in one app, also there are about 6 or 7 other items on the picker so if someone could help that would be great: here is my code. By the way I am new to the site sorry if I didn't do Code Blocks.
- (void)viewDidLoad
{
NSArray *data = [[NSArray alloc] initWithObjects:#"Weather", #"Calendar", #"Facebook", #"Twitter", #"Instagram",#"Tasks" ,nil];
self.array = data;
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
#pragma marks Picker Data Source Methods
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [_array count];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
#pragma mark Picker Delegate Methods
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [_array objectAtIndex:row];
}
- (IBAction)ButtonPressed:(id)sender {
NSString *select = [_array objectAtIndex:[_picker selectedRowInComponent:0]];
NSString *title = [ [NSString alloc] initWithFormat:#"You selected %#!" , select];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:#"Welcome To One" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
You have to do like bellow need to give tag to UIAlertView otherwise it will push view on each UIAlertView click
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent: (NSInteger)component
{
NSString *select = [_array objectAtIndex:component];
NSString *title = [ [NSString alloc] initWithFormat:#"You selected %#!" , select];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:#"Welcome To One" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
alert.tag = 1001;
alert.delegate = self;
[alert show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.tag == 1001)
{
[self.navigationController performSegueWithIdentifier:#"Identifier" sender:nil];
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// Show alert here
[[[UIAlertView alloc]
initWithTitle:#"" message:#"Alert Message"
delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil]
show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
UIStoryboard * storyboard = self.storyboard;
ViewController * detail = [storyboard instantiateViewControllerWithIdentifier: #"YourViewControlller"];
[self.navigationController pushViewController: detail animated: YES];
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent: (NSInteger)component
{
NSString *select = [_array objectAtIndex:component];
NSString *title = [ [NSString alloc] initWithFormat:#"You selected %#!" , select];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:#"Welcome To One" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
alert.delegate = self;
[alert show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
[self.navigationController performSegueWithIdentifier:#"Identifier" sender:nil];
}
}
i am trying to replace an object at in an array by replacing it with the text returned from an alert view.
so far i have:
int selected = indexPath.row;
and for my alertview delegate method.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (alertView.tag == 1) {
[myMutableArray replaceObjectAtIndex:selected withObject:[[alertView textFieldAtIndex:0] text]];
[_tableView reloadData];
}
}
i keep getting an error of
Incompatible integer to pointer conversion assigning to 'NSInteger *' (aka 'long *') from 'NSInteger' (aka 'long')
The error you see comes from the fact that you put a * somewhere before the NSInteger variable.
Without knowing what the rest of your code looks like, you could try this in your ViewController.m file. It sets the text of a label and replaces an object in a mutable array with the text from the alert view when the "OK" button is pressed.
#import "ViewController.h"
#interface ViewController () <UIAlertViewDelegate>
#property (strong,nonatomic) NSMutableArray *mutArray;
#property (weak,nonatomic) IBOutlet UILabel *label;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *array = #[#"item1",#"item2",#"item3"];
self.mutArray = [[NSMutableArray alloc] init];
self.mutArray = [array mutableCopy];
}
- (IBAction)showAlert:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"My Alert Example"
message:#"message here"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK",nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
int selected = 1;
if (buttonIndex != alertView.cancelButtonIndex) {
NSLog(#"ok button");
UITextField *textField = [alertView textFieldAtIndex:0];
self.label.text = textField.text;
[self.mutArray replaceObjectAtIndex:selected withObject:textField.text];
NSLog(#"mutArray is %#",self.mutArray);
} else {
NSLog(#"cancel button");
}
}
#end
Since it looks like you're using a UITableView, in your case you would have int selected = indexPath.row instead of int selected = 1.
I am making a calculator using Xcode iOS SDK 6.1. However, I have faced a problem because my calculator cannot add the two numbers together. It seems that the calculator always give me the first number as an answer. Is there a way to solve the problem?
Here's the code:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize FirstNumber,SecondNumber;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.FirstNumber.delegate = self;
self.SecondNumber.delegate = self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc
{
[FirstNumber release];
[SecondNumber release];
[super dealloc];
}
- (IBAction)Calculate:(id)sender
{
NSString *finalNumberString;
int firstNumberInt, secondNumberInt, finalNumberInt;
firstNumberInt = [FirstNumber.text integerValue];
secondNumberInt = [SecondNumber.text integerValue];
finalNumberInt = firstNumberInt + secondNumberInt;
UIAlertView *alerting = [[UIAlertView alloc]initWithTitle:#"Answer" message:[NSString stringWithFormat:#"The answer is %d",finalNumberInt] delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles: nil];
[alerting show];
_FinalNumber.text = [[NSString alloc] initWithFormat:#"%i",finalNumberInt];
}
- (BOOL)textFieldShouldReturn:(UITextField*)textField
{
[FirstNumber resignFirstResponder];
[SecondNumber resignFirstResponder];
return NO;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if ([touch view] == self.view)
{
[FirstNumber resignFirstResponder];
[SecondNumber resignFirstResponder];
}
}
#end
It looks like you're showing the wrong value in the alert.
[NSString stringWithFormat:#"The answer is %d",secondNumberInt]
This should probably be
[NSString stringWithFormat:#"The answer is %d", finalNumberInt]
instead.
UIAlertView *alerting = [[UIAlertView alloc]initWithTitle:#"Answer" message:[NSString stringWithFormat:#"The answer is %d",secondNumberInt] delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles: nil];
secondNumberInt looks like it should be finalNumberInt
Incorrect values used as make the Alert message,
UIAlertView *alerting = [[UIAlertView alloc]initWithTitle:#"Answer" message:[NSString stringWithFormat:#"The answer is %d",secondNumberInt] delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles: nil];
[alerting show];
Change that part like this,
UIAlertView *alerting = [[UIAlertView alloc]initWithTitle:#"Answer" message:[NSString stringWithFormat:#"The answer is %d",finalNumberInt] delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles: nil];
[alerting show];
Try to put an NSLog between the two integer casts, and check if strings are read fine or if one of them is zero. If one of them is zero, probably you haven't connected the outlet to the UITextField in interface builder, or maybe you are just typing some weird string in the textfield: since you are casting to integer, you obiouvsly shouldn't put decimal digits.
firstNumberInt = [FirstNumber.text integerValue];
secondNumberInt = [SecondNumber.text integerValue];
NSLog(#"FirstNumber string %# integer %d", FirstNumber.text, firstNumberInt);
NSLog(#"SecondNumber string %# integer %d", SecondNumber.text, secondNumberInt);
finalNumberInt = firstNumberInt + secondNumberInt;