我试图将TableView子类化,并且不会调用方法。
在TouchTableView.h中我有
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import "SimpleTableCell.h"
@protocol myTableViewDelegate;
@interface TouchTableView : UITableView <UITableViewDelegate, UITableViewDataSource, AVAudioRecorderDelegate, AVAudioPlayerDelegate, UITextViewDelegate, UITextFieldDelegate, UIAlertViewDelegate>
@property (nonatomic, assign) id<myTableViewDelegate> myDelegate;
@property (strong, nonatomic) NSMutableArray *sortedFiles;
@property (strong, nonatomic) NSString *simpleTableIdentifier;
@property (strong, nonatomic) SimpleTableCell *cell;
@property BOOL inverted;
-(void)refreshTable;
@end
@protocol myTableViewDelegate <NSObject>
- (void)selectedFile:(TouchTableView *)tableView withURL: (NSURL *) tableViewURL IndexPath:(NSIndexPath *)indexPath;
-(void)didDelete:(TouchTableView *)tableView IndexPath:(NSIndexPath *)indexPath;
-(void)setSortedFile:(TouchTableView *)tableView;
@end
在TouchTableView.m中我有方法
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *folders = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsFolder = [folders objectAtIndex:0];
NSString *dataPath = [documentsFolder stringByAppendingPathComponent:@"/Audio"];
NSString *fileName = [NSString stringWithFormat:@"%@/%@",dataPath,[[sortedFiles objectAtIndex:indexPath.row] objectForKey: @"path"]];
NSURL *tableViewUrl = [NSURL fileURLWithPath:fileName isDirectory:
NO];
if ([self.myDelegate respondsToSelector:@selector(selectedFile:withURL:IndexPath:)]) {
[self.myDelegate selectedFile:self withURL:tableViewUrl IndexPath:indexPath];
}
}
看来self.delegate没有响应选择器。它会跳过并且不会转到该方法。我做错了什么?
答案 0 :(得分:0)
是否将TableView委托分配给self
?默认情况下它为零,因此不会响应选择器。
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (!(self = [super initWithCoder:aDecoder])) {
return self;
}
self.delegate = self;
return self;
}
答案 1 :(得分:0)
我认为你应该使用:
if ([tableview.delegate respondsToSelector:@selector(selectedFile:withURL:IndexPath:)]) {
[tableview.delegate selectedFile:self withURL:tableViewUrl IndexPath:indexPath];
}
您更新的委托是表格视图中的属性,而不是视图控制器。
您还重新声明了子类中的delegate
属性,这可能是一个问题,因为表视图已经有一个名为delegate的属性。也许你应该打电话让你的人分开并给你打电话:myDelegate
?
答案 2 :(得分:0)
无法向UITableViewDelegate
添加新方法,因为您无权修改UIKit
。但是,它可以拦截委托,因为它完全是关于在Objective-C中传递的消息。
我想告诉您的第一件事是将您自己的代理声明为weak
引用,而不是assign
。
Whats the difference between 'weak' and 'assign' in delegate property declaration
现在,我将告诉您如何拦截代表并使其与UITableViewDelegate
看起来没有区别。
1)在头文件中使用自定义协议声明委托。
@property (nonatomic, weak) id<UITableViewDelegate, myTableViewDelegate > delegate;
2)添加以下方法以创建将用于拦截委托的对象。
@interface MessageInterceptor : NSObject
@property (nonatomic, assign) id receiver;
@property (nonatomic, assign) id middleMan;
@end
@implementation MessageInterceptor
@synthesize receiver;
@synthesize middleMan;
- (id)forwardingTargetForSelector:(SEL)aSelector {
if ([middleMan respondsToSelector:aSelector]) { return middleMan; }
if ([receiver respondsToSelector:aSelector]) { return receiver; }
return [super forwardingTargetForSelector:aSelector];
}
- (BOOL)respondsToSelector:(SEL)aSelector {
if ([middleMan respondsToSelector:aSelector]) { return YES; }
if ([receiver respondsToSelector:aSelector]) { return YES; }
return [super respondsToSelector:aSelector];
}
@end
3)为它添加一个全局对象
MessageInterceptor *delegate_interceptor;
4)初始化拦截器
delegate_interceptor = [[MessageInterceptor alloc] init];
[delegate_interceptor setMiddleMan:self];
[super setDelegate:(id)delegate_interceptor];
5)覆盖委托人的setter和getter
- (void)setDelegate:(id)newDelegate
{
[super setDelegate:nil];
[delegate_interceptor setReceiver:newDelegate];
[super setDelegate:(id)delegate_interceptor];
}
- (id)delegate
{
return delegate_interceptor.receiver;
}
6)覆盖你想要的代表
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Call the default method again to make sure it follow the original behavior
if ([self.delegate respondsToSelector:@selector(tableView:didSelectRowAtIndexPath:)]) {
[self.delegate tableView:tableview didSelectRowAtIndexPath:indexPath];
}
NSArray *folders = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsFolder = [folders objectAtIndex:0];
NSString *dataPath = [documentsFolder stringByAppendingPathComponent:@"/Audio"];
NSString *fileName = [NSString stringWithFormat:@"%@/%@",dataPath,[[sortedFiles objectAtIndex:indexPath.row] objectForKey: @"path"]];
NSURL *tableViewUrl = [NSURL fileURLWithPath:fileName isDirectory:
NO];
// Call the custom method which is declared in your protocol
if ([self.delegate respondsToSelector:@selector(selectedFile:withURL:IndexPath:)]) {
[self.delegate selectedFile:self withURL:tableViewUrl IndexPath:indexPath];
}
}
最后一步,不要忘记在创建tableview的文件中采用协议。
@interface TheFileUsingTableView ()
<UITableViewDelegate, myTableViewDelegate>
@end
答案 3 :(得分:0)
我将此添加到我的viewDidLoad中。只需要将代表设置为自己。现在它响应选择器。
self.touchTableView = [[TouchTableView alloc] init];
[self.tableView setDelegate:self.touchTableView];
[self.tableView setDataSource:self.touchTableView];
self.touchTableView.myDelegate = self;