通过点击带有协议的滑出菜单过滤 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 提要的主要内容,如果未能解决你的问题,请参考以下文章

没有后退按钮的滑出菜单

如何以编程方式在 ios 的滑出式侧边栏菜单中添加按钮

在导航控制器中实现滑出菜单时在哪里以及如何设置协议委托?

仅滑出式菜单 css

如何修改 PKRevealController 滑出菜单以处理 iOS 7?

带有滑出菜单的标签栏