在主视图控制器中的自定义单元格内使用UIButton中的IBAction

时间:2022-01-21 08:57:09

I have created a custom cell with its own .m, .h and .xib file. In the cell, I have a UIButton that I added to the xib in IB.

我创建了一个自定义单元格,其中包含自己的.m,.h和.xib文件。在单元格中,我有一个UIButton,我添加到IB中的xib。

I can receive the IBAction from the UIButton in this custom cell's .m, but really, I'd like to be forwarding that button press to the main view .m that is hosting the table (and so custom cell) and use an action there.

我可以在这个自定义单元格.m中从UIButton接收IBAction,但实际上,我想将该按钮转发到托管表格的主视图.m(以及自定义单元格)并在那里使用操作。

I've spent the last 4 hours attempting various ways of doing this - should I be using NSNotificationCenter? (I've tried Notifications lots but can't get it to work and not sure if i should be persevering)

我花了最后4个小时尝试各种方法 - 我应该使用NSNotificationCenter吗? (我已经尝试过Notifications很多但是无法让它工作并且不确定我是否应该坚持不懈)

5 个解决方案

#1


9  

You need to use delegate in .h file of cell. Declare the delegate like this

您需要在单元格的.h文件中使用委托。像这样声明委托

@class MyCustomCell;
@protocol MyCustomCellDelegate
- (void) customCell:(MyCustomCell *)cell button1Pressed:(UIButton *)btn;
@end

then declare field and property

然后声明字段和属性

@interface MyCustomCell:UItableViewCell {
    id<MyCustomCellDelegate> delegate;
}

@property (nonatomic, assign) id<MyCustomCellDelegate> delegate;

@end

in .m file

在.m文件中

@synthesize delegate;

and in button method

并在按钮方法

- (void) buttonPressed {
    if (delegate && [delegate respondToSelector:@selector(customCell: button1Pressed:)]) {
        [delegate customCell:self button1Pressed:button];
    }
}

Your view controller must adopt this protocol like this

您的视图控制器必须采用此协议

.h file

#import "MyCustomCell.h"

@interface MyViewController:UIViewController <MyCustomCellDelegate>
.....
.....
@end

in .m file in cellForRow: method you need add property delegate to cell

在cellForRow:.m文件中,您需要将属性委托添加到单元格

cell.delegate = self;

and finally you implement the method from protocol

最后你从协议实现方法

- (void) customCell:(MyCustomCell *)cell button1Pressed:(UIButton *)btn {

}

Sorry for my english, and code. Wrote it from my PC without XCODE

对不起,我的英文和代码。在没有XCODE的情况下从我的电脑上写下来

#2


1  

I had the same problem, and I solved it by subclassing the cell into it's own class, and put the buttons there as outlets, and filling the cell with data from the model, while using a method that returns the cell we're currently viewing.

我遇到了同样的问题,我通过将单元格子类化为它自己的类来解决它,并将按钮放在那里作为出口,并使用模型中的数据填充单元格,同时使用返回我们当前正在查看的单元格的方法。

For example, if you had a Person class, and each person had a name, a surname, and a number of friends. And each time you clicked a button in the cell, the number of friends for a specific person would increase by 1.

例如,如果您有一个Person类,并且每个人都有一个姓名,一个姓氏和一些朋友。每次单击单元格中的按钮时,特定人员的朋友数量将增加1。

_______________DATA SOURCE___________________________
#import <Foundation/Foundation.h>

@interface Person : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *comment;
@property (nonatomic) NSInteger numberOfFriends;


+(instancetype)personWithName:(NSString *)aName Surname:(NSString *)aSurname;

@end

#import "Person.h"

@implementation Person

+(instancetype)personWithName:(NSString *)aName Surname:(NSString *)aSurname{

    Person *person = [[Person alloc] init];
    [person setName:aName];
    [person setSurname:aSurname];
    [person setNumberOfFriends:0];

    return person;
}

@end

_____________________PERSON CELL________________________

#import <UIKit/UIKit.h>

@interface PersonCell : UITableViewCell

@property (strong, nonatomic) IBOutlet UILabel *friendsNum;
@property (strong, nonatomic) IBOutlet UIButton *friendsBtn;
@property (strong, nonatomic) IBOutlet UILabel *nameLabel;
@property (strong, nonatomic) IBOutlet UILabel *surnameLabel;


@end

Personally I created a private NSArray to hold the names of my Person objects, and a private NSMutableDictionary to hold my Person objects, and I set the keys to be the names of the people.

我个人创建了一个私有NSArray来保存我的Person对象的名称,并创建一个私有的NSMutableDictionary来保存我的Person对象,并将键设置为人员的名字。

_____________________PERSON TABLE VIEW________________________    
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    PersonCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    NSString *name = [peopleNames objectAtIndex:indexPath.row];
    Person *person = [people objectForKey:name];

    if(cell == nil)
    {
        cell = [[PersonCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...
    cell.nameLabel.text = person.name;
    cell.surname.Label.text = person.surname

    [cell.friendsButton addTarget:self action:@selector(moreFriends:) forControlEvents:UIControlEventTouchUpInside];

    cell.friendsNum.text = [NSString stringWithFormat:@"%i", person.numberOfFriends];

    return cell;
}

- (IBAction)moreFriends:(id)sender {
    UIButton *btn = (UIButton *)sender;
    PersonCell *cell = [self parentCellForView:btn];
    Person *person = [people objectForKey:cell.nameLabel.text];
    person.numberOfFriends++;
    [self.tableView reloadData];
}

-(PersonCell *)parentCellForView:(id)theView
{
    id viewSuperView = [theView superview];
    while (viewSuperView != nil) {
        if ([viewSuperView isKindOfClass:[PersonCell class]]) {
            return (PersonCell *)viewSuperView;
        }
        else {
            viewSuperView = [viewSuperView superview];
        }
    }
    return nil;
}

#3


0  

I would recommend using a delegate.

我建议使用代表。

#4


0  

You might want to just add a selector for the button in your view controller which has your tableview.

您可能只想在视图控制器中为按钮添加一个选择器,该选择器具有您的tableview。

in your cellForIndexPath function

在你的cellForIndexPath函数中

[yourCell.button addTarget:self action:@selector(customActionPressed:) forControlEvents:UIControlEventTouchDown];

then handle the button press in your "customActionPressed:(id) sender" method

然后在“customActionPressed:(id)sender”方法中按下按钮

    //Get the superview from this button which will be our cell
UITableViewCell *owningCell = (UITableViewCell*)[sender superview];

//From the cell get its index path.
NSIndexPath *pathToCell = [myTableView indexPathForCell:owningCell];

    //Do something with our path

This may be a better solution for you unless there are more factors that you haven't listed.

除非您没有列出更多因素,否则这可能是更好的解决方案。

I have a tutorial which is might explain more http://www.roostersoftstudios.com/2011/05/01/iphone-custom-button-within-a-uitableviewcell/

我有一个教程,可能会解释更多http://www.roostersoftstudios.com/2011/05/01/iphone-custom-button-within-a-uitableviewcell/

#5


0  

Why not create a delegate (using @protocol) for your custom cell. You can then designate the main view as each cell's delegate and process the action appropriately.

为什么不为自定义单元格创建委托(使用@protocol)。然后,您可以将主视图指定为每个单元格的委托,并相应地处理该操作。

#1


9  

You need to use delegate in .h file of cell. Declare the delegate like this

您需要在单元格的.h文件中使用委托。像这样声明委托

@class MyCustomCell;
@protocol MyCustomCellDelegate
- (void) customCell:(MyCustomCell *)cell button1Pressed:(UIButton *)btn;
@end

then declare field and property

然后声明字段和属性

@interface MyCustomCell:UItableViewCell {
    id<MyCustomCellDelegate> delegate;
}

@property (nonatomic, assign) id<MyCustomCellDelegate> delegate;

@end

in .m file

在.m文件中

@synthesize delegate;

and in button method

并在按钮方法

- (void) buttonPressed {
    if (delegate && [delegate respondToSelector:@selector(customCell: button1Pressed:)]) {
        [delegate customCell:self button1Pressed:button];
    }
}

Your view controller must adopt this protocol like this

您的视图控制器必须采用此协议

.h file

#import "MyCustomCell.h"

@interface MyViewController:UIViewController <MyCustomCellDelegate>
.....
.....
@end

in .m file in cellForRow: method you need add property delegate to cell

在cellForRow:.m文件中,您需要将属性委托添加到单元格

cell.delegate = self;

and finally you implement the method from protocol

最后你从协议实现方法

- (void) customCell:(MyCustomCell *)cell button1Pressed:(UIButton *)btn {

}

Sorry for my english, and code. Wrote it from my PC without XCODE

对不起,我的英文和代码。在没有XCODE的情况下从我的电脑上写下来

#2


1  

I had the same problem, and I solved it by subclassing the cell into it's own class, and put the buttons there as outlets, and filling the cell with data from the model, while using a method that returns the cell we're currently viewing.

我遇到了同样的问题,我通过将单元格子类化为它自己的类来解决它,并将按钮放在那里作为出口,并使用模型中的数据填充单元格,同时使用返回我们当前正在查看的单元格的方法。

For example, if you had a Person class, and each person had a name, a surname, and a number of friends. And each time you clicked a button in the cell, the number of friends for a specific person would increase by 1.

例如,如果您有一个Person类,并且每个人都有一个姓名,一个姓氏和一些朋友。每次单击单元格中的按钮时,特定人员的朋友数量将增加1。

_______________DATA SOURCE___________________________
#import <Foundation/Foundation.h>

@interface Person : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *comment;
@property (nonatomic) NSInteger numberOfFriends;


+(instancetype)personWithName:(NSString *)aName Surname:(NSString *)aSurname;

@end

#import "Person.h"

@implementation Person

+(instancetype)personWithName:(NSString *)aName Surname:(NSString *)aSurname{

    Person *person = [[Person alloc] init];
    [person setName:aName];
    [person setSurname:aSurname];
    [person setNumberOfFriends:0];

    return person;
}

@end

_____________________PERSON CELL________________________

#import <UIKit/UIKit.h>

@interface PersonCell : UITableViewCell

@property (strong, nonatomic) IBOutlet UILabel *friendsNum;
@property (strong, nonatomic) IBOutlet UIButton *friendsBtn;
@property (strong, nonatomic) IBOutlet UILabel *nameLabel;
@property (strong, nonatomic) IBOutlet UILabel *surnameLabel;


@end

Personally I created a private NSArray to hold the names of my Person objects, and a private NSMutableDictionary to hold my Person objects, and I set the keys to be the names of the people.

我个人创建了一个私有NSArray来保存我的Person对象的名称,并创建一个私有的NSMutableDictionary来保存我的Person对象,并将键设置为人员的名字。

_____________________PERSON TABLE VIEW________________________    
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    PersonCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    NSString *name = [peopleNames objectAtIndex:indexPath.row];
    Person *person = [people objectForKey:name];

    if(cell == nil)
    {
        cell = [[PersonCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...
    cell.nameLabel.text = person.name;
    cell.surname.Label.text = person.surname

    [cell.friendsButton addTarget:self action:@selector(moreFriends:) forControlEvents:UIControlEventTouchUpInside];

    cell.friendsNum.text = [NSString stringWithFormat:@"%i", person.numberOfFriends];

    return cell;
}

- (IBAction)moreFriends:(id)sender {
    UIButton *btn = (UIButton *)sender;
    PersonCell *cell = [self parentCellForView:btn];
    Person *person = [people objectForKey:cell.nameLabel.text];
    person.numberOfFriends++;
    [self.tableView reloadData];
}

-(PersonCell *)parentCellForView:(id)theView
{
    id viewSuperView = [theView superview];
    while (viewSuperView != nil) {
        if ([viewSuperView isKindOfClass:[PersonCell class]]) {
            return (PersonCell *)viewSuperView;
        }
        else {
            viewSuperView = [viewSuperView superview];
        }
    }
    return nil;
}

#3


0  

I would recommend using a delegate.

我建议使用代表。

#4


0  

You might want to just add a selector for the button in your view controller which has your tableview.

您可能只想在视图控制器中为按钮添加一个选择器,该选择器具有您的tableview。

in your cellForIndexPath function

在你的cellForIndexPath函数中

[yourCell.button addTarget:self action:@selector(customActionPressed:) forControlEvents:UIControlEventTouchDown];

then handle the button press in your "customActionPressed:(id) sender" method

然后在“customActionPressed:(id)sender”方法中按下按钮

    //Get the superview from this button which will be our cell
UITableViewCell *owningCell = (UITableViewCell*)[sender superview];

//From the cell get its index path.
NSIndexPath *pathToCell = [myTableView indexPathForCell:owningCell];

    //Do something with our path

This may be a better solution for you unless there are more factors that you haven't listed.

除非您没有列出更多因素,否则这可能是更好的解决方案。

I have a tutorial which is might explain more http://www.roostersoftstudios.com/2011/05/01/iphone-custom-button-within-a-uitableviewcell/

我有一个教程,可能会解释更多http://www.roostersoftstudios.com/2011/05/01/iphone-custom-button-within-a-uitableviewcell/

#5


0  

Why not create a delegate (using @protocol) for your custom cell. You can then designate the main view as each cell's delegate and process the action appropriately.

为什么不为自定义单元格创建委托(使用@protocol)。然后,您可以将主视图指定为每个单元格的委托,并相应地处理该操作。