I'm making a UITableView where you can click on a tableviewcell and this should trigger a phone call to a phone number in an array.
The phone numbers are listed in an array, and these are also shown in the tableviewcell.
_Number = #[#"100",
#"101",
#"070 245 245"];
I'm new at this and I don't know how to start with this, I already got my tableviewcontroller and tableviewcell classes which are working.
Gratz and thanks in advance
You can do following :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *phoneNumber = [Number objectAtIndex:indexPath.row];
NSURL *phoneNumberURL = [NSURL URLWithString:[NSString stringWithFormat:#"tel:%#", phoneNumber]];
if( [[UIApplication sharedApplication] canOpenURL:phoneNumberURL] )
{
[[UIApplication sharedApplication] openURL:phoneNumberURL];
}
else
{
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:#"Alert!!!" message:#"Not able to make a phone call." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
}
Related
This question already has answers here:
Pass a NSDictionary as parameter to UITapGestureRecognizer
(3 answers)
Closed 7 years ago.
I am newbie too ios and objective c,I know my question is very simple but i found not solution do asked,I am having a method for a static value,now i want to make it dynamic by passing value to that method,So can anybuddy please tell me how to write method with parameter and how to call it.my code is as below:
-(void)phoneNumberLabelTap
{
NSURL *phoneUrl = [NSURL URLWithString:[NSString stringWithFormat:#"telprompt:%#",fonlabel.text]];
if ([[UIApplication sharedApplication] canOpenURL:phoneUrl]) {
[[UIApplication sharedApplication] openURL:phoneUrl];
} else {
UIAlertView * calert = [[UIAlertView alloc]initWithTitle:#"Alert" message:#"Call facility is not available!!!" delegate:nil cancelButtonTitle:#"ok" otherButtonTitles:nil, nil];
[calert show];
}
}
I want to add a parameter to this method,
And i am calling this method as below,
fonlabel.userInteractionEnabled = YES;
homeLabel.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(phoneNumberLabelTap)];
[fonlabel addGestureRecognizer:tapGesture];
[homeLabel addGestureRecognizer:tapGesture];
- (void)setPhoneNumber:(NSString *)phoneNumber; // set a phoneNumber property
- (void)prepareToBeTapped
{
UITapGestureRecognizer *tapFirstGuy = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(makeCallToThisPerson:)];
[self addGestureRecognizer:tapFirstGuy];
}
- (void)makeCallToThisPerson:(id)sender
{
NSString *phoneURL = [NSString stringWithFormat:#"tel:%#", phoneNumber];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneURL]];
}
Instead of giving a UILabel, you can give a UIButton and can give the same method as target for the button
UIButton *fonButton = [[UIButton alloc] init];
[fonButton addTarget:self action:#selector(phoneNumberButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
and in the target method like this
-(void)phoneNumberButtonClicked:(UIButton *)sender
{
NSURL *phoneUrl = [NSURL URLWithString:[NSString stringWithFormat:#"telprompt:%#",sender.titleLabel.text]];
if ([[UIApplication sharedApplication] canOpenURL:phoneUrl]) {
[[UIApplication sharedApplication] openURL:phoneUrl];
} else {
UIAlertView * calert = [[UIAlertView alloc]initWithTitle:#"Alert" message:#"Call facility is not available!!!" delegate:nil cancelButtonTitle:#"ok" otherButtonTitles:nil, nil];
[calert show];
}
}
One gesture can be applied to one object. You need to create 2 gestures for both labels. Below code with small changes will resolve your problem.
-(void)phoneNumberLabelTap:(UITapGestureRecognizer*)tapRecognizer
{
UILabel* lblPhone = (UILabel*)tapRecognizer.view;
NSURL *phoneUrl = [NSURL URLWithString:[NSString stringWithFormat:#"telprompt:%#",lblPhone.text]];
if ([[UIApplication sharedApplication] canOpenURL:phoneUrl]) {
[[UIApplication sharedApplication] openURL:phoneUrl];
} else {
UIAlertView * calert = [[UIAlertView alloc]initWithTitle:#"Alert" message:#"Call facility is not available!!!" delegate:nil cancelButtonTitle:#"ok" otherButtonTitles:nil, nil];
[calert show];
}
}
fonlabel.userInteractionEnabled = YES;
homeLabel.userInteractionEnabled = YES;
[homeLabel addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(phoneNumberLabelTap:)]];
[fonlabel addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(phoneNumberLabelTap:)]];
i am making a chat app with xmpp framework.
I have setup XMPPFramework in my project by referring this link:- http://code.tutsplus.com/tutorials/building-a-jabber-client-for-ios-xmpp-setup--mobile-7190
In this message sending is working perfectly and in receive message it is show in alertview as it is in code. When message received this method is calling which is in Appdelegate.m file:-
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{ DDLogVerbose(#"%#: %#", THIS_FILE, THIS_METHOD);
// A simple example of inbound message handling.
if ([message isChatMessageWithBody])
{
XMPPUserCoreDataStorageObject *user = [xmppRosterStorage userForJID:[message from]
xmppStream:xmppStream
managedObjectContext:[self managedObjectContext_roster]];
NSString *body = [[message elementForName:#"body"] stringValue];
NSString *displayName = [user displayName];
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:displayName
message:body
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}
else
{
// We are not active, so use a local notification instead
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.alertAction = #"Ok";
localNotification.fireDate=[NSDate dateWithTimeIntervalSinceNow:1.0];
localNotification.alertBody = [NSString stringWithFormat:#"From: %#\n%#",displayName,body];
NSLog(#"localNotification.alertBody:-%#",localNotification.alertBody);
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}
}
}
And i want to show that received messages in conversation view (in tableview) which is in an other class.
Here the code which is displaying send messages in tableview
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell=nil;
cell=[tableView dequeueReusableCellWithIdentifier:#"MessageCellIdentifier" forIndexPath:indexPath];
cell.textLabel.text=[[messages objectAtIndex:indexPath.row] objectForKey:#"msg"];
cell.detailTextLabel.text=#"You";
cell.textLabel.textAlignment=NSTextAlignmentRight;
return cell;
}
So, my question is how to take that received messages in array or in dictionary and take that to tableview cell for row at indexpath to show in tableview.
As far as I understand, you want to display a chat view between two people ?
I made a Swift Wrapper around the XMPPFramework, it uses JSQMessageViewController for the UI.
It will simplify the development of a basic chat app.
You can check it out here.
I have an UITableView, with cells that you can tap on.
When you tap, some actions are run, but that is not important in this context. First time I press, it handles the tap correctly. Second time it is running the code, but all View updates like showing a UIAlertView or showing a new view is delayed. But not delayed by time - It's waiting for me to touch the screen. No matter where I press or how long I wait, I just have to press. And it's every time but the first.
My TableView is set to single selection and not to show selection on touch. Any Ideas why it does this?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if ([cell isKindOfClass:[DetailTableViewCell class]]) {
DetailTableViewCell *detailCell = (DetailTableViewCell *)cell;
NSString *hourString = [detailCell hourString];
if (!detailCell.booking) {
NSDate *rightNow = [NSDate new];
NSDate *cellDate = [self.currentDate dateWithHour:indexPath.row andMinutes:0];
// Only allow future bookings (but allow people people to book within the hour)
if([rightNow compare:[cellDate nextHour]] == NSOrderedAscending){
[self performSegueWithIdentifier:#"roomBooking" sender:indexPath];
return;
} else {
[[[UIAlertView alloc] initWithTitle:#"Error" message:#"We currently do not allow our users make bookings in the past" delegate:nil cancelButtonTitle:#"Gotcha" otherButtonTitles:nil] show];
return;
}
} else if ([detailCell.booking hasPhoneNumber]) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:#"telprompt://%ld",(long)[detailCell.booking telephone]]]];
return;
} else {
//TODO: FIND OUT IF BOOKING IS OWNED BY THE CURRENT USER
[[[UIAlertView alloc] initWithTitle:#"Booking"
message:[NSString stringWithFormat:#"You are now removing the booking at %#.", hourString]
delegate:nil
cancelButtonTitle:#"OK" otherButtonTitles:nil] show];
#weakify(self);
[self.room removeBookingWithId:[detailCell.booking.bookingId integerValue] andCompletion:^(BOOL success, NSError *error) {
#strongify(self);
if (success) {
#weakify(self);
[self.room.location updateBookingsWithCompletion:^(BOOL success, NSError *error) {
#strongify(self);
if (success) {
[self.calendar reloadData];
}
}];
}
}];
return;
}
}
}
SelectionStyle was set to None, but we changed it to something else, which solved the problem.
Click on the TableViewCell itself.
In your properties section locate: "Selection"
Set to: Blue/Grey/Default.
I need to add a button Facebook, Then the action should take user to Facebook, I'm just not sure how to do it from the code below?
-(IBAction)btContinueClick:(id)sender{
if(Level == [list count]){
UIAlertView *info = [[UIAlertView alloc]initWithTitle:#"Good" message:#"Go to facebook?" delegate:self cancelButtonTitle:#"NO" otherButtonTitles:#"Facebook"];
[info show]; //// Change Game End Message
}
}
If you want to go to the native app of Facebook in iOS.
Using delegate method of alertView
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex == 1) {
NSURL *url = [NSURL URLWithString:#"fb://profile"];
if ([[UIApplication sharedApplication] canOpenURL:url]) { //USE FB NATIVE APP
[[UIApplication sharedApplication] openURL:url];
}
else { //IF THE DEVICE IS UNABLE TO OPEN IN NATIVE APP, USE BROWSER INSTEAD
NSURL *browserURL = [NSURL URLWithString:#"http://www.facebook.com"];
[[UIApplication sharedApplication] openURL:browserURL];
}
}
}
Make sure you have added UIAlertViewDelegate in .h file
-(IBAction)btContinueClick:(id)sender{
if(Level == [list count]){
UIAlertView *info = [[UIAlertView alloc]initWithTitle:#"Good" message:#"Go to facebook?" delegate:self cancelButtonTitle:#"NO" otherButtonTitles:#"Facebook"];
[info show]; //// Change Game End Message
info.delegate=self;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if(buttonIndex==1)
{
NSLog(#"Facebook selected.");
NSURL *url = [NSURL URLWithString:#"fb://profile/<id>"]; // provide the app ID
[[UIApplication sharedApplication] openURL:url];
}
}
A button from the first alert executes the second alert which is basically a confirmation to call someone. I don't get any errors but it doesn't work.
When I press on the second alert the Call button it crashes
-(void) alertView: (UIAlertView *) alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *buttonString = [alertView buttonTitleAtIndex:buttonIndex];
if ([buttonString isEqualToString:#"Phone"])
{
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:#"Notice!" message:#"You are about to call .... Do you wish to continue?" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"Call", nil];
[alert2 show];
if ([buttonString isEqualToString:#"Call"]){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:#"tel://12345678"]]];
}
if([buttonString isEqualToString:#"Website"]){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"website"]];
}
if ([buttonString isEqualToString:#"Facebook"]){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://www.facebook.com/groups/..../"]];
}
}
}
You assigned to delegate as a nil in second alertview. That's why the alertView:clickedButtonAtIndex: delegate method is not called in second time. So you should assign to delegate as a self.
-(void) alertView: (UIAlertView *) alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *buttonString = [alertView buttonTitleAtIndex:buttonIndex];
if([buttonString isEqualToString:#"Phone"]) {
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:#"Notice!" message:#"You are about to call .... Do you wish to continue?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Call", nil];
[alert2 show];
}
if([buttonString isEqualToString:#"Call"]){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:#"tel://12345678"]]];
}
if([buttonString isEqualToString:#"Website"]){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"website"]];
}
if([buttonString isEqualToString:#"Facebook"]){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://www.facebook.com/groups/..../"]];
}
}
I think it will be helpful to you.
Launch the second alert with a delay. Problem is - alert needs some time to hide itself, before any new alerts can appear, thus directly calling second one will not work.
try this for example:
- (void) alertView: (UIAlertView *) alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *buttonString = [alertView buttonTitleAtIndex:buttonIndex];
if ([buttonString isEqualToString:#"Phone"])
{
[self performSelector:#selector(callSecondAlertView) withObject:nil afterDelay:1];
}
}
- (void)callSecondAlertView
{
//show new alert view
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:#"Notice!" message:#"You are about to call .... Do you wish to continue?" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"Call", nil];
[alert2 show];
[alert2 release];
}
If not working, or too long delay - play with afterDelay: value.
got it! for some reason the [[[alertView subviews] objectAtIndex:6] setBackgroundColor... for the fisrt alertView buttons i had interferes with the second alertView functionality. xcode though did not direct me directly to the problem until i updated xcode to 4.4.1
Use the alertView:didDismissWithButtonIndex: delegate method instead of the alertView:clickedButtonAtIndex: delegate method. The former is called after the alert is gone. This make more sense when you want to show a second based on the tapped button of the first alert view.
Also give tag to UIAlertview objects.