在主视图控制器的自定义单元格中使用来自 UIButton 的 IBAction
Posted
技术标签:
【中文标题】在主视图控制器的自定义单元格中使用来自 UIButton 的 IBAction【英文标题】:Use IBAction from UIButton inside custom cell in main view controller 【发布时间】:2012-05-11 17:42:44 【问题描述】:我创建了一个带有自己的 .m、.h 和 .xib 文件的自定义单元格。在单元格中,我有一个 UIButton,已添加到 IB 中的 xib。
我可以在此自定义单元格的 .m 中从 UIButton 接收 IBAction,但实际上,我希望将该按钮按下转发到托管表格(以及自定义单元格)的主视图 .m 并使用那里有一个动作。
在过去的 4 个小时里,我一直在尝试各种方法 - 我应该使用 NSNotificationCenter 吗? (我已经尝试了很多通知,但无法让它工作,并且不确定我是否应该坚持下去)
【问题讨论】:
我认为 NSNotificationCenter 是一个合理的策略。您是否没有收到按钮的操作方法发送的通知或其他问题? 我也是这么想的——我认为我还没有实现它们的诀窍……更多的练习。我现在可以让它们在同一个视图中工作,但是当我尝试不同的视图时仍然会出现异常......我们会到达那里 这是一个非常完整的关于创建和使用委托协议的解释。 dosomethinghere.com/2009/07/18/… 代理也可以工作。差异主要是关于耦合的微妙差异。委托有点松散,因为需要处理帮助的对象被告知从哪里获取它,但关于委托对象的其他内容很少。通知更加松散,通知对象只是断言发生了某些事情,并将其留给未知的侦听器是否响应。除非您需要支持多个听众,否则这可能是一个哲学选择。 【参考方案1】:您需要在单元格的 .h 文件中使用委托。 像这样声明委托
@class MyCustomCell;
@protocol MyCustomCellDelegate
- (void) customCell:(MyCustomCell *)cell button1Pressed:(UIButton *)btn;
@end
然后声明字段和属性
@interface MyCustomCell:UItableViewCell
id<MyCustomCellDelegate> delegate;
@property (nonatomic, assign) id<MyCustomCellDelegate> delegate;
@end
在 .m 文件中
@synthesize delegate;
按钮方法
- (void) buttonPressed
if (delegate && [delegate respondToSelector:@selector(customCell: button1Pressed:)])
[delegate customCell:self button1Pressed:button];
你的视图控制器必须像这样采用这个协议
.h 文件
#import "MyCustomCell.h"
@interface MyViewController:UIViewController <MyCustomCellDelegate>
.....
.....
@end
在 cellForRow 的 .m 文件中:您需要将属性委托添加到单元格的方法
cell.delegate = self;
最后你实现了协议中的方法
- (void) customCell:(MyCustomCell *)cell button1Pressed:(UIButton *)btn
对不起我的英语和代码。用我的电脑写的,没有 XCODE
【讨论】:
- (void) buttonPressed if (delegate && [delegate respondToSelector:@selector(customCell: button1Pressed:)]) [delegate customCell:self button1Pressed:button];你在哪里得到 [delegate customCell:self button1Pressed:button] 中的“按钮”;当我在控制器中添加方法时,展示另一个视图控制器的示例代码是什么?谢谢 要呈现另一个视图控制器,您可以使用 [self presentViewController: animated: completion:];或 [self.navigationController pushViewController: 动画:] @Moonkid 这个问题有快速的答案吗? @AlekPiasecki 你好,在swift中使用闭包代替委托更容易,当然你也可以使用委托。 swift 书中有一章是关于协议的developer.apple.com/library/content/documentation/Swift/…【参考方案2】:我遇到了同样的问题,我通过将单元格子类化到它自己的类中来解决它,并将按钮放在那里作为出口,并用模型中的数据填充单元格,同时使用返回单元格的方法我们'正在观看。
例如,如果您有一个 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
我个人创建了一个私有 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】:我建议使用delegate.
【讨论】:
【参考方案4】:您可能只想在具有您的 tableview 的视图控制器中为按钮添加一个选择器。
在你的 cellForIndexPath 函数中
[yourCell.button addTarget:self action:@selector(customActionPressed:) forControlEvents:UIControlEventTouchDown];
然后在“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
这对你来说可能是一个更好的解决方案,除非有更多你没有列出的因素。
我有一个教程可能会解释更多http://www.roostersoftstudios.com/2011/05/01/iphone-custom-button-within-a-uitableviewcell/
【讨论】:
谢谢,实际上我已经知道按钮的路径了,因为我使用的方法是使用被选中的单元格来选择一个 plist(有点俗气但效果很好)。不过我会试试你的教程,看看我是否可以用不同的方式解决我的问题。 听起来不错。如果您知道索引并且可以以某种方式使用它来获取所需的数据,那么您可能拥有在拥有的视图控制器中执行操作所需的一切。祝你好运 同时查看其他人对使用委托的建议也是一个非常好的主意。这是我不久前制作的另一个教程:[link]roostersoftstudios.com/2011/04/12/…【参考方案5】:为什么不为您的自定义单元格创建一个委托(使用@protocol)。然后,您可以将主视图指定为每个单元格的委托并适当地处理操作。
【讨论】:
我想我最好研究一下代表...我不知道该做什么!!以上是关于在主视图控制器的自定义单元格中使用来自 UIButton 的 IBAction的主要内容,如果未能解决你的问题,请参考以下文章
更改单元格中的数据后,UITableView 中的自定义单元格将无法正确重新加载
当我在收藏视图中滚动时,我的自定义单元格中的 UIView 锚点不断变化