IBActions not working - iphone

I have two buttons that are not performing the IBAction that they are programmed to do. I have them correctly connected in Interface Builder, but when I click them in the simulator or on a phone, they do not perform their task. No crashes, nothing. Here is my code
MapDetailInfo.h:
#interface MapDetailInfo : UIViewController {
IBOutlet UILabel *name;
IBOutlet UITextView *address;
NSString * nameText;
NSString * addressText;
NSString * stringOne;
NSString * stringTwo;
IBOutlet UILabel *phoneNumber;
}
#property (retain, nonatomic) IBOutlet UILabel *name;
#property (retain, nonatomic) IBOutlet UITextView *address;
#property (nonatomic, copy) NSString * nameText;
#property (nonatomic, copy) NSString * addressText;
#property (retain, nonatomic) NSString * stringOne;
#property (retain, nonatomic) NSString * stringTwo;
#property (retain, nonatomic) IBOutlet UILabel *phoneNumber;
- (IBAction)callPhone:(id)sender;
- (IBAction)getDirections:(id)sender;
#end
MapDetailInfo.m:
#implementation MapDetailInfo
#synthesize name, address, nameText, addressText, phoneNumber, stringTwo, stringOne;
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *myWords = [addressText componentsSeparatedByCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString:#"("]
];
stringOne = [myWords objectAtIndex:1];
stringTwo = #"(";
stringTwo = [stringTwo stringByAppendingString:stringOne];
self.name.text = nameText;
self.address.text = [myWords objectAtIndex:0];
self.phoneNumber.text = stringTwo;
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(callPhone:)
forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"Call Shop" forState:UIControlStateNormal];
button.frame = CGRectMake(104.0, 332.0, 160.0, 40.0);
[self.view addSubview:button];
}
- (IBAction)callPhone:(id)sender {
NSString *URLString = [#"tel://" stringByAppendingString:stringTwo];
NSURL *URL = [NSURL URLWithString:URLString];
[[UIApplication sharedApplication] openURL:URL];
}
- (IBAction)getDirections:(id)sender {
[[UIApplication sharedApplication] openURL:
[NSURL URLWithString:[NSString stringWithFormat:#"http://maps.google.com/maps?saddr=Current Location&daddr=%#",self.address.text]]];
}
I am pulling this view from an annotation in a map. Everything works perfect accept for these two buttons not performing their task. Any help would be much appreciated. Thanks!

The reason the buttons were not working is because the URL's were incorrect. If you run into the same problem, make sure your telephone number URL's are:
#"tel://5555555"
I had the parenthesis and dash inside of mine and that is why it would not pull up. Also there was an error in my google URL.
Thanks!

I dont see any UIButton in your code. Did you use them ?
Edit:
I had suggested that you use buttons for that is the specific purpose. And yes, you can still use labels and follow the same procedure to call the methods.
There has to be some issue with the way you are connecting the outlets.
I would suggest that you follow tutorials - 4, 5, and 6 of this Youtube link.
http://www.youtube.com/watch?v=B7jB0D3Y7Ws&feature=relmfu

Related

Custom Annotation with a button. didSelectAnnotaionView does not seem to get called

I am having a problem with my didSelectAnnotationView getting called when I use a custom annotation view. I was hoping someone might be able to take a look and help me with what I am missing.
I actually want a method to get called when the user touches the button show in the screenshot of my custom annotation which can be seen below. I was trying to make that the calloutAccessoryView, but I am doing something wrong. Please if anyone has done custom annotation views that a user can click on please see if you can help!! This is driving me crazy. I think I have posted the relevant info here, if not ask and I will edit my post.
I am adding a custom annotation like this:
LocationObject * obj = [m_MyObject.marLocations objectAtIndex:page];
obj.title =#"A";
[mvMapView addAnnotation:obj];
My Location object used above is defined like this:
// Location Object
#interface LocationObject : NSObject <MKAnnotation>
#property (nonatomic, retain) NSString * practicename;
#property (nonatomic, retain) NSString * address1;
#property (nonatomic, retain) NSString * mapaddress1;
#property (nonatomic, retain) NSString * address2;
#property (nonatomic, retain) NSString * city;
#property (nonatomic, retain) NSString * state;
#property (nonatomic, retain) NSString * zip;
#property (nonatomic, retain) NSString * phone;
#property (nonatomic, retain) NSString * fax;
#property (nonatomic, retain) NSString * email;
#property (nonatomic, retain) NSString * longitude;
#property (nonatomic, retain) NSString * latitude;
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *subtitle;
#end // End Location Object
My viewForAnnotation does this:
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
{
[map.userLocation setTitle:#"I am here"];
return nil;
}
static NSString* AnnotationIdentifier = #"annotationViewID";
ViewDirectionsAnnotationView * annotationView = [[ViewDirectionsAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];
int page = floor((svOfficesScrollView.contentOffset.x - svOfficesScrollView.frame.size.width / 2) / svOfficesScrollView.frame.size.width) + 1;
LocationObject * obj = [m_DentistObject.marLocations objectAtIndex:page];
double dLatitude = [obj.latitude doubleValue];
double dLongitude = [obj.longitude doubleValue];
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(dLatitude, dLongitude);
((LocationObject*)annotation).coordinate = coordinate;
annotationView.lbPracticeName.text = obj.practicename;
annotationView.lbStreet.text = obj.address1;
NSString * sCityStateZip = [NSString stringWithFormat:#"%#, %# %#", obj.city, obj.state, obj.zip];
annotationView.lbCityStateZip.text = sCityStateZip;
annotationView.lbPhoneNumber.text = obj.phone;
annotationView.canShowCallout = YES;
annotationView.annotation = annotation;
annotationView.rightCalloutAccessoryView = (UIButton *)[annotationView viewWithTag:1]; //[UIButton buttonWithType:UIButtonTypeDetailDisclosure];
return annotationView;
}
And my Annotation View is like this:
#interface ViewDirectionsAnnotationView : MKAnnotationView
{
CLLocationCoordinate2D coordinate;
NSString * title;
NSString * subtitle;
}
#property (nonatomic, retain) IBOutlet UIView * loadedView;
#property (weak, nonatomic) IBOutlet UILabel * lbPracticeName;
#property (weak, nonatomic) IBOutlet UILabel * lbStreet;
#property (weak, nonatomic) IBOutlet UILabel * lbCityStateZip;
#property (weak, nonatomic) IBOutlet UILabel * lbPhoneNumber;
#end
And the xib for the above view looks like this:
But, my didSelectAnnotationView never gets called. Can anybody explain what I am missing?
Please, any help is appreciated this has been driving me nuts. I could have it completely wrong, but the custom view does appear so I think I am close.
Thanks for the help!!
UPDATE:
I forgot to mention about the delegate. I have checked the delegate many times and believe I have it right. In the ViewController .h file where the mapView is, I have the and I set [mapView setDelegate:self] In that same .m file is where I have implemented the viewForAnnotation method and didSelectAnnotationView. The viewForAnnotation gets called but not the other.
One more interesting piece of information is that if I click (touch) just below my custom annotation then didSelectAnnotationView does get called. I guess now I am more confused!!
UPDATE #2:
My xib is loaded this way:
In my viewForAnnotation I call initWithAnnotation. That method is as follows:
- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString*)reuseIdentifier
{
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
if (self != nil)
{
[[NSBundle mainBundle] loadNibNamed:#"DirectionsAnnotation" owner:self options:nil];
if (loadedView)
{
[loadedView setFrame:CGRectMake(-(loadedView.frame.size.width/2), -(loadedView.frame.size.height), loadedView.frame.size.width, loadedView.frame.size.height)];
[self addSubview:loadedView];
}
}
return self;
}
The view which is displaying your MapView needs to be set as your delegate.
Where is your didSelectAnnotationView? Make sure that it implements the delegate protocol. E.g.
#interface MyView : UIViewController <MKMapViewDelegate>
...
#end
Then somewhere else...
[mapView setDelegate:myView];

string set to null when pushing detail view

I am pushing a detail view from the master of a Master-Detail Application template.
I want to load a single view with different information depending on which row was clicked. I plan to load the data from a plist file.
Here is the code I used in the MasterViewController, when I added didSelectRowAtIndexPath:
DetailViewController *dvc = [[DetailViewController alloc]init];
dvc.rowItem = [_objects objectAtIndex:indexPath.row];;
NSLog(#"row is %i", indexPath.row);
NSLog(#"master %#", dvc.rowItem);
where rowItem is an NSString belonging to the DetailViewController. Inside the viewDidLoad of the DetailViewController I put:
[super viewDidLoad];
NSLog(#" thingy %#", rowItem);
[self setup:rowItem];
and setup looks like this:
-(void) setup: (NSString *)eval {
filePath = [NSString stringWithFormat:#"%#.plist",eval];
NSLog(#"%#", filePath);
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
NSString *subName;
NSString *yesNo;
NSString *theseChanges;
subName = [plistDict objectForKey:#"subContractAddress"];
yesNo = [plistDict objectForKey:#"yesOrno"];
theseChanges = [plistDict objectForKey:#"Changes"];
}
Here is my interface:
#import <UIKit/UIKit.h>
#interface DetailViewController : UIViewController
#property (strong, nonatomic) id detailItem;
#property (strong, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
#property (strong, nonatomic) IBOutlet UIButton *finishedButton;
#property (strong, nonatomic) IBOutlet UITextView *changes;
#property (strong, nonatomic) IBOutlet UIButton *saveButton;
#property (strong, nonatomic) IBOutlet UISwitch *test;
#property (strong, nonatomic) IBOutlet UILabel *finishedLabel;
#property (strong, nonatomic) IBOutlet UITextField *subContractName;
#property BOOL needsChanges;
#property (strong, nonatomic) NSString *rowItem;
-(IBAction)change:(id)sender;
-(IBAction)save:(id)sender;
#end
when I build and run I get the console output of:
thingy (null)
(null).plist
row is 0
master Excavations
when I press the first row, and
thingy (null)
(null).plist
row is 1
master Flooring
so somehow, rowItem is getting set to null in the crossover.
Can someone see what I am doing wrong here?
Try changing your two log statements as follows:
NSLog(#"master %#, detail %#", dvc.rowItem, dvc);
NSLog(#" thingy %# in detail %#", rowItem, self);
I suspect that the detail you create as dvc is not the same object that is in the view controller hierarchy. Showing the object addresses should verify whether that's the answer.
Do your setup in "viewWillAppear" and I'll bet it starts working.
Please check with this,
dvc.rowItem = [[NString alloc]initWithString:#"%#",[_objects objectAtIndex:indexPath.row]];

NSMutableArray, with UIImage and NSString objects, unable use the objects

I'm new to xCode and objective-c, and trying to use different classes to familiarize myself with the language.
I was trying to use an NSMutableArray to show several pictures and a corresponding textsnippet to tell about the picture. I have a segmentedControl to switch between several choices. Using an UIImageView to show a picture, and a UITextView the corresponding text.
But for some reason they will not load properly? The picture and the text isn't shown. What am I doing wrong?
#interface TestingViewController : UIViewController{
UIImageView *pic;
UITextView *description;
UISegmentedControl *choice;
NSMutableArray *infoDescription;
}
#property (nonatomic, retain) IBOutlet UIImageView *pic;
#property (nonatomic, retain) IBOutlet UITextView *description;
#property (nonatomic, retain) NSMutableArray *infoDescription;
#property (nonatomic, retain) IBOutlet UISegmentedControl *choice;
- (IBAction) segmentedControllIndexChanged;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
infoDescription = [[NSMutableArray alloc] init];
}
UIImage *miko = [UIImage imageNamed:#"miko.jpg"];
NSString *mikoString = #"Info about Miko";
UIImage *alex = [UIImage imageNamed:#"alex.jpg"];
NSString *alexString = #"Info about Alex";
[infoDescription addObject:miko];
[infoDescription addObject:mikoString];
[infoDescription addObject:alex];
[infoDescription addObject:alexString];
- (IBAction)segmentedControllIndexChanged{
switch (choice.selectedSegmentIndex) {
case 0:
[pic setImage: miko];
[pic setImage: [infoDescription objectAtIndex:0]];
[description setText: [[infoDescription objectAtIndex:1] stringValue]];
break;
case 1:
[pic setImage: [infoDescription objectAtIndex:2]];
[description setText: [[infoDescription objectAtIndex:3] stringValue]];
break;
default:
break;
}
}
Thanks for any help out there.
NSMutableArray should not be an IBOutlet ..
Change this
#property (nonatomic, retain) IBOutlet NSMutableArray *infoDescription;
to
#property (nonatomic, retain) NSMutableArray *infoDescription;
and make sure you synthesize it..
and also the program isn't working since your array is not initialized and is not adding objects to it.
put this in ViewDidLoad
infoDescription = [[NSMutableArray alloc] init];
Your infoDescription array is probably nil. Put this before you add items to it:
infoDescription = [[NSMutableArray alloc] init];
Also, infoDescription doesn't need to be declared as an IBOutlet. IBOutlets are only for properties that you bind in Interface Builder (usually views).

Setting the value of a UITextField in an IBAction

I'm trying to use a UITextField as an output for a simple encryption. The field starts out with a nil string (its default behavior), and I try to update it in the encryptButtonPressed: action. I know I'm getting a good NSString into ciphertext, and I'm getting no errors or warnings or anything that the method doesn't exist, but the field remains blank. Any ideas?
Here's the header:
#interface FirstViewController : UIViewController <UITextFieldDelegate> {
IBOutlet UITextField *affineKeyField;
IBOutlet UITextField *shiftKeyField;
IBOutlet UITextField *messageField;
IBOutlet UITextField *ciphertextField;
MAAffineMachine* machine;
}
#property (nonatomic, retain) UITextField *affineKeyField;
#property (nonatomic, retain) UITextField *shiftKeyField;
#property (nonatomic, retain) UITextField *messageField;
#property (nonatomic, retain) UITextField *ciphertextField;
#property (nonatomic, retain) UIButton *encryptButton;
#property (nonatomic, retain) UIButton *clipboardButton;
- (IBAction)encryptButtonPressed:(id)sender;
- (IBAction)clipboardButtonPressed:(id)sender;
#end
And the action, defined in the controller's implementation:
- (IBAction)encryptButtonPressed:(id)sender {
NSLog(#"Encrypt Button pushed.\n");
int affine = [[affineKeyField text] intValue];
int shift = [[shiftKeyField text] intValue];
NSString* message = [messageField text];
NSLog(#"%d, %d, %#", affine, shift, message);
NSString* ciphertext = [machine encryptedStringFromString:message
ForAffine:affine
Shift:shift];
NSLog(#"%#\n", ciphertext);
[[self ciphertextField] setText: ciphertext];
}
If ciphertext has a proper value, you should check that ciphertextField is linked properly in the interface builder.
Try [[self ciphertextField] setText: ciphertext] -> [ciphertextField setText: ciphertext] or cipherTextField.text = ciphertext;

Play a sound based on the button pressed on the IPhone/xcode

I'm trying to play a sound based on which button is pressed using AVAudioPlayer.
(This is not a soundboard or fart app.)
I have linked all buttons using this code in the header file:
#interface appViewController : UIViewController <AVAudioPlayerDelegate> {
AVAudioPlayer *player;
UIButton *C4;
UIButton *Bb4;
UIButton *B4;
UIButton *A4;
UIButton *Ab4;
UIButton *As4;
UIButton *G3;
UIButton *Gb3;
UIButton *Gs3;
UIButton *F3;
UIButton *Fs3;
UIButton *E3;
UIButton *Eb3;
UIButton *D3;
UIButton *Db3;
UIButton *Ds3;
UIButton *C3;
UIButton *Cs3;
}
#property (nonatomic, retain) AVAudioPlayer *player;
#property (nonatomic, retain) IBOutlet UIButton *C4;
#property (nonatomic, retain) IBOutlet UIButton *B4;
#property (nonatomic, retain) IBOutlet UIButton *Bb4;
#property (nonatomic, retain) IBOutlet UIButton *A4;
#property (nonatomic, retain) IBOutlet UIButton *Ab4;
#property (nonatomic, retain) IBOutlet UIButton *As4;
#property (nonatomic, retain) IBOutlet UIButton *G3;
#property (nonatomic, retain) IBOutlet UIButton *Gb3;
#property (nonatomic, retain) IBOutlet UIButton *Gs3;
#property (nonatomic, retain) IBOutlet UIButton *F3;
#property (nonatomic, retain) IBOutlet UIButton *Fs3;
#property (nonatomic, retain) IBOutlet UIButton *E3;
#property (nonatomic, retain) IBOutlet UIButton *Eb3;
#property (nonatomic, retain) IBOutlet UIButton *D3;
#property (nonatomic, retain) IBOutlet UIButton *Db3;
#property (nonatomic, retain) IBOutlet UIButton *Ds3;
#property (nonatomic, retain) IBOutlet UIButton *C3;
#property (nonatomic, retain) IBOutlet UIButton *Cs3;
- (IBAction) playNote;
#end
Buttons are all linked to the event "playNote" in interfaceBuilder and each note is linked to the proper referencing outlet according to note name.
All *.mp3 sound files are named after the UIButton name (IE- C3 == C3.mp3).
In my implementation file, I have this to play a only one note when the C3 button is pressed:
#import "sonicfitViewController.h"
#implementation appViewController
#synthesize C3, Cs3, D3, Ds3, Db3, E3, Eb3, F3, Fs3, G3, Gs3, A4, Ab4, As4, B4, Bb4, C4;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
NSString *path = [[NSBundle mainBundle] pathForResource:#"3C" ofType:#"mp3"];
NSLog(#"path: %#", path);
NSURL *file = [[NSURL alloc] initFileURLWithPath:path];
AVAudioPlayer *p = [[AVAudioPlayer alloc]
initWithContentsOfURL:file error:nil];
[file release];
self.player = p;
[p release];
[player prepareToPlay];
[player setDelegate:self];
[super viewDidLoad];
}
- (IBAction) playNote {
[self.player play];
}
Now, with the above I have two issues:
First, the NSLog reports NULL and crashes when trying to play the file. I have added the mp3's to the resources folder and they have been copied and not just linked. They are not in an subfolder under the resources folder.
Secondly, how can I set it up so that when say button C3 is pressed, it plays C3.mp3 and F3 plays F3.mp3 without writing duplicate lines of code for each different button? playNote should be like
NSString *path = [[NSBundle mainBundle] pathForResource:nameOfButton ofType:#"mp3"];
instead of defining it specifically (#"C3").
Is there a better way of doing this and why does the *path report NULL and crash when I load the app?
I'm pretty sure it's something as simple as adding additional variable inputs to - (IBAction) playNote:buttonName and putting all the code to call AVAudioPlayer in the playNote function but I'm unsure of the code to do this.
Performing multiple actions with same selector is a common task. Just set a tag property for each button and use a NSArray of NSStrings to store file names. Your even need not create each button separately. See code sample for similar question problem with selector in iphone? answer.
Check if your files is realy copied to bundle. For example in simulator
log your bundle directory with NSLog(#"myBundle:%#",[[NSBundle mainBundle] bundlePath]);
and look at files.