通过点击带有协议的滑出菜单过滤 UITableView 提要
Posted
技术标签:
【中文标题】通过点击带有协议的滑出菜单过滤 UITableView 提要【英文标题】:Filter UITableView Feed via tap on Slide Out Menu with protocol 【发布时间】:2015-10-13 19:43:14 【问题描述】:假设您有一个滑出式菜单。当您在此滑出菜单中键入一个项目时,您希望使用位于该滑出菜单项中的 NSString 来过滤掉您的应用程序的提要,即填充自定义单元格的 UITableView。
您认为正确的方法是使用协议和委托。
在您的滑出菜单视图控制器中,您声明协议、相关方法(在您的提要视图控制器中实现)和委托。
// SlideOutMenuTableViewController.h
#import <UIKit/UIKit.h>
#import "SlideOutMenuItems.h"
#import "SlideOutMenuCellTableViewCell.h"
@protocol filterFeed <NSObject>
-(void)filterFeedFromSlideOutItemTapped:(NSString *)slideOutItemStringData; //String to pass slideOut menu item string back to feed
@end
@interface SlideOutMenuTableViewController : UITableViewController
@property(nonatomic,assign)id<filterFeed> stringDelegate;
@end
在您的提要视图控制器中,您有以下头文件和实现文件:
// FeedVCTableViewController.h
#import <UIKit/UIKit.h>
#import "FlameCellTableViewCell.h"
#import "Feed.h"
#import "SlideOutMenuTableViewController.h"
#import "FlameDetailViewController.h"
@interface FeedVCTableViewController : UITableViewController<FlameCellDelegate, senddataProtocol, filterFeed,UIPopoverPresentationControllerDelegate, UIAdaptivePresentationControllerDelegate>
@property Feed *feed;
@property Feed *filteredFeed;
@property NSInteger *indexTapCell;
@end
// FeedVCTableViewController.m
#import "FeedVCTableViewController.h"
#import "Feed.h"
#import "SWRevealViewController.h"
#import <Parse/Parse.h>
@interface FeedVCTableViewController ()
@end
@implementation FeedVCTableViewController
// First quite a few methods not relevant to solve this
#pragma mark - Filter feed based on slideout menu item tapped
-(void)filterFeedFromSlideOutItemTapped:(NSString *)slideOutItemStringData
NSLog(@"filterFeedFromSlideOutItemTapped just started");
if (!(slideOutItemStringData == (nil)))
//Pass self.feed.flames + filtering string ==> filtered flames
NSMutableArray* allFlames = [[NSMutableArray alloc] initWithArray:self.feed.flames];
NSString *flameRelationFilter = slideOutItemStringData;
NSPredicate* sortFlames = [NSPredicate predicateWithFormat:@"(kFlameRelation like %@)", flameRelationFilter];
NSArray* filteredFlames = [allFlames filteredArrayUsingPredicate:sortFlames];
NSLog(@"The filter flames are %@", filteredFlames);
NSMutableArray *mutableFilteredFlames = [filteredFlames mutableCopy];
self.filteredFeed.flames = mutableFilteredFlames;
[self.tableView reloadData];
//Other methods not relevant here
@end
最后但并非最不重要的一点是,在验证您要传递给 stringDelegate 的 NSString 属于 NSString 类并且正在传递预期值(位于被点击的卖出内的 NSString ):
#pragma mark - segue method
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if([segue.identifier isEqualToString:@"Filter_MenuItem"])
if ([sender isKindOfClass:[SlideOutMenuCellTableViewCell class]])
NSIndexPath* indexPath = [self.tableView indexPathForCell:sender];
NSLog(@"The indexPath of slideout cell is: %@", indexPath);
NSLog(@"class for object sender: %@", NSStringFromClass([sender class]));
//Assign tapped cell string to stringDelegate
NSLog(@"The NSString in the slide out menue item cell is %@",[self.slideOutMenuItems menuItemAtIndex:indexPath.row]);
if([[self.slideOutMenuItems menuItemAtIndex:indexPath.row] isKindOfClass:[NSString class]])
NSLog(@"The string of the tapped menu items is kind of class NSString");
NSLog(@"The stringDelegate value prior to executing the delegate method is %@",stringDelegate);
[stringDelegate filterFeedFromSlideOutItemTapped:[self.slideOutMenuItems menuItemAtIndex:indexPath.row]];
NSLog(@"The stringDelegate from the slide out menu VC has been set to %@", stringDelegate);
您确保在后一种实现中也合成您的委托:
@implementation SlideOutMenuTableViewController
@synthesize stringDelegate;
您启动构建并崩溃并显示以下错误消息:
2015-10-13 15:15:06.245 Flame[1607:479051] The NSString in the slide out menue item cell is Friend into
2015-10-13 15:15:06.245 Flame[1607:479051] The string of the tapped menu items is kind of class NSString
2015-10-13 15:15:06.245 Flame[1607:479051] The stringDelegate value prior to executing the delegate method is All Flames
2015-10-13 15:15:13.270 Flame[1607:479051] -[__NSCFConstantString filterFeedFromSlideOutItemTapped:]: unrecognized selector sent to instance 0x100306d10
2015-10-13 15:15:13.272 Flame[1607:479051] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFConstantString filterFeedFromSlideOutItemTapped:]: unrecognized selector sent to instance 0x100306d10'
*** First throw call stack:
(0x183e94f5c 0x19899bf80 0x183e9bc6c 0x183e98c14 0x183d9cdcc 0x1000e0d0c 0x189ad9c78 0x189ad9ae0 0x189ad9da8 0x18951dc6c 0x1895d8f8c 0x189694828 0x1896a0dc8 0x1893dd1c8 0x183e4bc30 0x183e499d4 0x183e49e04 0x183d78dc0 0x18eecc088 0x189452f44 0x1000e05ec 0x1991c68b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
如何解决?
非常感谢任何帮助。
谢谢!
【问题讨论】:
【参考方案1】:你应该注意的那一行是:
-[__NSCFConstantString filterFeedFromSlideOutItemTapped:]: unrecognized selector sent to instance 0x100306d10
这告诉您您正在尝试通过字符串发送filterFeedFromSlideOutItemTapped:
消息,这显然行不通。
您没有显示将此委托属性设置为符合filterFeed
协议的实例的位置,因此这是您接下来需要查看的位置。
更新:
要正确设置它,这实际上取决于您是使用故事板还是在代码中构建所有内容。如果您在代码中设置它,那么您需要找到创建这 2 个控制器(可能是导航控制器或拆分视图控制器)的公共父级并将委托设置在那里。
如果您使用故事板,您可以在设计器中连接代理。
如果这些选项中的任何一个都失败,您可以让 tableview 进入视图控制器层次结构并找到滑出控制器,以这种方式设置属性,但这并不理想。
【讨论】:
嗨@Ben Scheirman:谢谢!我正在努力设置委托的位置,因为我没有 segue(我通常在哪里设置协议委托,并且它有效)。当我试图弄清楚一些事情时,会重视更多的指导。如您所知,我是一名创业企业家,自学成才,希望让它发挥作用,即使它并不漂亮! :) 感谢您更新您的回复并提供更多详细信息。这很有帮助。以上是关于通过点击带有协议的滑出菜单过滤 UITableView 提要的主要内容,如果未能解决你的问题,请参考以下文章