表格单元格内的电话

时间:2013-08-06 20:07:35

标签: ios iphone ibaction

我正在编写一个应用程序,有人在应用程序中添加联系人,提供他们的姓名,号码和照片。然后,该信息显示在表格中,每个单独的联系人在不同的单元格上,当用户按下该单元格时,它将调用为该联系人输入的号码。我在每个单元格上放了一个大按钮供用户按下。这是代码

PictureListMainTable.m

#import "PictureListMainTable.h"
#import "PictureListDetail.h"
#import "CoreDataHelper.h"
#import "Pictures.h"

@implementation PictureListMainTable

@synthesize managedObjectContext, pictureListData, callButton;

//  When the view reappears, read new data for table
- (void)viewWillAppear:(BOOL)animated
{
    //  Repopulate the array with new table data
    [self readDataForTable];
}

//  Grab data for table - this will be used whenever the list appears or reappears after an add/edit
- (void)readDataForTable
{
    //  Grab the data
    pictureListData = [CoreDataHelper getObjectsForEntity:@"Pictures" withSortKey:@"title" andSortAscending:YES andContext:managedObjectContext];

    //  Force table refresh
    [self.tableView reloadData];
}

#pragma mark - Actions

//  Button to log out of app (dismiss the modal view!)
- (IBAction)logoutButtonPressed:(id)sender
{
    [self dismissModalViewControllerAnimated:YES];
}

#pragma mark - Segue methods

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    //  Get a reference to our detail view
    PictureListDetail *pld = (PictureListDetail *)[segue destinationViewController];

    //  Pass the managed object context to the destination view controller
    pld.managedObjectContext = managedObjectContext;

    //  If we are editing a picture we need to pass some stuff, so check the segue title first
    if ([[segue identifier] isEqualToString:@"EditPicture"])
    {
        //  Get the row we selected to view
        NSInteger selectedIndex = [[self.tableView indexPathForSelectedRow] row];

        //  Pass the picture object from the table that we want to view
        pld.currentPicture = [pictureListData objectAtIndex:selectedIndex];
    }
}

#pragma mark - Table view data source

//  Return the number of sections in the table
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

//  Return the number of rows in the section (the amount of items in our array)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [pictureListData count];
}



//  Create / reuse a table cell and configure it for display
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";





    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    }


    // Get the core data object we need to use to populate this table cell
    Pictures *currentCell = [pictureListData objectAtIndex:indexPath.row];

    //  Fill in the cell contents
    cell.textLabel.text = [currentCell title];
    cell.detailTextLabel.text = [currentCell desc];

    int number;


    number = [currentCell desc];

        -(IBAction)MakePhoneCall:(id)sender {
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel:",number]];
}






    //  If a picture exists then use it
    if ([currentCell smallPicture])
    {
        cell.imageView.contentMode = UIViewContentModeScaleAspectFit;
        cell.imageView.image = [UIImage imageWithData:[currentCell smallPicture]];
    }
    else{


    }



    return cell;

}

//  Swipe to delete has been used.  Remove the table item
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        //  Get a reference to the table item in our data array
        Pictures *itemToDelete = [self.pictureListData objectAtIndex:indexPath.row];

        //  Delete the item in Core Data
        [self.managedObjectContext deleteObject:itemToDelete];

        //  Remove the item from our array
        [pictureListData removeObjectAtIndex:indexPath.row];

        //  Commit the deletion in core data
        NSError *error;
        if (![self.managedObjectContext save:&error])
            NSLog(@"Failed to delete picture item with error: %@", [error domain]);

        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }

}


-(IBAction)MakePhoneCall:(id)sender {
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel:",number]];
}

@end

PictureListMainTable.h

#import <UIKit/UIKit.h>

@interface PictureListMainTable : UITableViewController

@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (strong, nonatomic) NSMutableArray *pictureListData;
@property (nonatomic, retain) IBOutlet UIButton *callButton;




-(IBAction)MakePhoneCall:(id)sender;

- (void)readDataForTable;

@end

我应该在哪里放置IBaction,为什么它在它出现的那一刻起作用?如何才能使它发挥作用?

1 个答案:

答案 0 :(得分:1)

您可以采取几种方法来实现这一目标。但首先,我不明白你在-tableview:cellForRowAtIndexPath:的底部做了什么。就像你试图在这个方法中定义你的IBAction方法一样。您也可以在实现的底部定义它,但在该方法中,number变量不在范围内。

无论如何,你应该继承UITableViewCell。在子类的实现中,您应该定义IBAction方法并将其挂钩在接口构建器中,否则。

当点击按钮时,您应该将所选单元格的编号交回PictureListMainTable视图控制器,以便该视图控制器处理它(即调用该编号)。您可以通过两种方式执行此操作:

1)委托方法

创建一个协议,在UITableViewCell子类的头文件中定义。并使主视图控制器符合此协议。将单元格的委托设置为主视图控制器。在单元子类的实现中,调用此委托方法。例如:

UITableViewCell子类“PictureListMainTableCell.h”的头文件

@protocol PictureListMainTableCellDelegate;

@interface PictureListMainTableCell : UITableViewCell
@property (nonatomic, copy) NSString *telephoneNumber;
@property (nonatomic, weak) id<PictureListMainTableCellDelegate> delegate;
@end

@protocol PictureListMainTableCellDelegate
-(void)pictureListMainTableCell:(PictureListMainTableCell *)cell wantsToCallNumber:(NSString *)number;
@end

实施文件“PictureListMainTableCell.m”

#import "PictureListMainTableCell.h"

@implementation PictureListMainTableCell

-(IBAction)MakePhoneCall:(id)sender
{
    //send the delegate the number to call.
    [self.delegate pictureListMainTableCell:self wantsToCallNumber:self.telephoneNumber];
}

@end

上面,在MakePhoneCall方法中,我们在委托上调用-pictureListMainTableCell:wantsToCallNumber:。在这种情况下,委托是您的主视图控制器。我们将在下面进行设置。

设置单元格的委托:在主视图控制器文件(PictureListMainTable.m)中,在-tableView:cellForRowAtIndexPath:方法中,将单元格上的委托设置为self。 e.g。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // get the cell...
    PictureListMainTableCell *cell = // dequeue the cell

    // do some other setting up...

    // set the delegate on the cell
    cell.delegate = self;

    // set the telephoneNumber variable on the cell, for example...
    cell.telephoneNumber = [currentCell desc];

    return cell;
}

现在您需要确保self实现委托方法。所以仍然在PictureListMainTable.m中,您需要按如下方式定义方法:

#pragma mark - PictureListMainTableCellDelegate methods
-(void)pictureListMainTableCell:(PictureListMainTableCell *)cell wantsToCallNumber:(NSString *)number
{
    NSString *urlString = [NSString stringWithFormat:@"tel://%@", number];
    NSLog(@"calling telephone number [%@]", number);
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
}

您还应该指定PictureListMainTable类符合您的新协议以及UITableViewDataSource协议。在PictureListMainTable上添加一个私有类别,如下所示(在执行文件的顶部,在导入之后,在@implementation之前):

@interface PictureListMainTable () <UITableViewDataSource, PictureListMainTableCellDelegate>
@end

(这扩展了PictureListMainTable接口。它只扩展它以私下指定它符合这些协议。)

2)NSNotification方法

当我输入上述解释时,我认为这是我首选的做事方式,所以我建议这样做。可以选择在您的单元子类中发布NSNotification,并从主视图控制器观察此通知。只需查看NSNotificationCenter,可以使用以下方法: –postNotificationName:object:userInfo:(在userInfo字典中发送号码)。使用–addObserver:selector:name:object:收听它。

但就像我说的那样,在我看来,选项1更好。

如果有什么不清楚,请告诉我,祝你好运:)。

编辑:我真的建议您阅读此博文以了解授权:http://alexefish.com/post/15966868557/understanding-and-creating-delegates-in-objective-c