1

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

图片列表主表.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

图片列表主表.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 放在哪里,为什么它在它所在的那一刻工作,我怎样才能让它工作?

4

1 回答 1

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. 例如

- (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

于 2013-08-06T20:51:35.713 回答