通过使用协议点击滑出菜单来过滤 UITableView Feed

Filter UITableView Feed via tap on Slide Out Menu with protocol

假设您有一个滑出式菜单。当您从此滑出菜单中键入一个项目时,您希望使用位于该滑出菜单项中的 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

在您的 Feed 视图控制器中,您有以下头文件和实现文件:

//  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 是 class 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

如何解决?

非常感谢任何帮助。

谢谢!

你要注意的那一行是:

-[__NSCFConstantString filterFeedFromSlideOutItemTapped:]: unrecognized selector sent to instance 0x100306d10

这是在告诉您,您正在尝试通过字符串发送 filterFeedFromSlideOutItemTapped: 消息,这显然行不通。

您没有显示将此委托 属性 设置为符合 filterFeed 协议的实例的位置,因此这是您下一步需要查看的地方。

更新:

要正确设置它,实际上取决于您是使用故事板还是在代码中构建所有内容。如果您在代码中设置它,那么您需要找到创建这 2 个控制器(可能是导航控制器或拆分视图控制器)的公共父级并将委托设置在那里。

如果您使用故事板,则可以在设计器中连接委托。

如果这些选项中的任何一个都失败,您可以让您的 tableview 进入视图控制器层次结构并找到滑出控制器,以这种方式设置 属性,但这并不是很理想。