带有搜索栏的 cell.accessoryType 不影响 NSPredicate

Posted

技术标签:

【中文标题】带有搜索栏的 cell.accessoryType 不影响 NSPredicate【英文标题】:cell.accessoryType with search bar don't affect with NSPredicate 【发布时间】:2014-07-15 10:35:31 【问题描述】:

我创建了一个使用搜索栏编辑朋友的视图。一切正常,但是当我找到带有搜索栏的用户时,cell.accessoryType 不正确。 (当我不使用搜索栏时,我的 cell.accessoryType 很好)。 复选标记不适合正确的用户。

我认为这是“isFriend”操作中的问题?

这是我的代码:

editfriends.h:

#import <UIKit/UIKit.h>
#import <Parse/Parse.h>

@interface EditFriendsViewController : UITableViewController <UISearchBarDelegate, UISearchDisplayDelegate>


@property (nonatomic, strong) NSArray *allUsers;
@property (nonatomic, strong) PFUser *currentUser;
@property (nonatomic, strong) NSMutableArray *friends;
@property (strong, nonatomic) NSArray *searchResults;
@property (nonatomic, strong) PFUser *user;


@property (nonatomic, strong) UIImage *MindleNav;



-(BOOL)isFriend:(PFUser*)user;

@end

editfriends.m:

#import "EditFriendsViewController.h"

@interface EditFriendsViewController ()

@end

@implementation EditFriendsViewController

- (void)viewDidLoad

    [super viewDidLoad];

    self.navigationItem.titleView = [[UIImageView alloc] initWithImage:self.MindleNav];

    self.searchResults = [[NSArray alloc] init];


    PFQuery *query = [PFUser query];
    [query orderByAscending:@"email"];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) 
        if (error) 
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        
        else 
            self.allUsers = objects;
            //            self.user = [objects objectAtIndex:0];
            [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
        
    ];

    self.currentUser = [PFUser currentUser];


#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    // Return the number of sections.
    return 1;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    // Return the number of rows in the section.
    if (tableView == self.searchDisplayController.searchResultsTableView)
    
        return [self.searchResults count];
    
    else
    
        return [self.allUsers count];
    


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];


    PFUser *user = [self.allUsers objectAtIndex:indexPath.row];

    if (tableView == self.searchDisplayController.searchResultsTableView) 
        cell.textLabel.text = [[self.searchResults objectAtIndex:indexPath.row] email];
     else 
        cell.textLabel.text = user.email;
    


    if ([self isFriend:user]) 
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    
    else 
        cell.accessoryType = UITableViewCellAccessoryNone;
    

    return cell;



#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    [self.tableView deselectRowAtIndexPath:indexPath animated:NO];

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    PFRelation *friendsRelation = [self.currentUser relationforKey:@"friendsRelation"];

    //Edit Friends with searchbar
    if (tableView == self.searchDisplayController.searchResultsTableView) 
        PFUser *user = [self.searchResults objectAtIndex:indexPath.row];

        if ([self isFriend:user]) 
            cell.accessoryType = UITableViewCellAccessoryNone;


            for(PFUser *friend in self.searchResults) 
                if ([friend.objectId isEqualToString:user.objectId]) 
                    [self.friends removeObject:friend];
                                [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
                    break;
                
            

            [friendsRelation removeObject:user];
        
        else 
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
            [self.friends addObject:user];
            [friendsRelation addObject:user];
            [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
        

        [self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) 
            if (error) 
                NSLog(@"Error: %@ %@", error, [error userInfo]);
            
        ];

        //Edit Friends
     else 
        PFUser *user = [self.allUsers objectAtIndex:indexPath.row];

        if ([self isFriend:user ]) 
            cell.accessoryType = UITableViewCellAccessoryNone;

            for(PFUser *friend in self.friends) 
                if ([friend.objectId isEqualToString:user.objectId]) 
                    [self.friends removeObject:friend];
                    break;
                
            

            [friendsRelation removeObject:user];
        
        else 
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
            [self.friends addObject:user];
            [friendsRelation addObject:user];
        

        [self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) 
            if (error) 
                NSLog(@"Error: %@ %@", error, [error userInfo]);
            
        ];
    




#pragma mark - Helper methods
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"email beginswith[c] %@", searchText];
    self.searchResults = [self.allUsers filteredArrayUsingPredicate:predicate];



-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString

    [self filterContentForSearchText:searchString
                               scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
                                      objectAtIndex:[self.searchDisplayController.searchBar
                                                     selectedScopeButtonIndex]]];

    return YES;



- (BOOL)isFriend:(PFUser *)user 
    for(PFUser *friend in self.friends) 
        if ([friend.objectId isEqualToString:user.objectId]) 
            return YES;
        
    

    return NO;


@end

【问题讨论】:

【参考方案1】:

这似乎是因为您使用了错误的用户对象来检查状态。比较:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    NSArray *sourceData = (tableView == self.searchDisplayController.searchResultsTableView ? self.searchResults : self.allUsers);
    PFUser *user = [sourceData objectAtIndex:indexPath.row];

    cell.textLabel.text = user.email;

    if ([self isFriend:user]) 
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
     else 
        cell.accessoryType = UITableViewCellAccessoryNone;
    

    return cell;

【讨论】:

哇...简直完美!这很好地压缩了代码:) 您以后也可以使用相同的表单:cell.accessoryType = ([self isFriend:user] ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone) 但使用此表单时请确保您的代码不会失去可读性... 是的,太好了!我不知道这种类型的代码:) 谓词,是的,可能。所以usernameemail 应该可以工作。请注意,还有其他NSArray 过滤方法,例如indexesOfObjectsPassingTest: 谢谢!你知道如何影响 PFUser 的名称(在我的 Parse 数据库中)而不是 user.email 吗?我试过 NSString *name = [[self.friends objectAtIndex:indexPath.row] valueForKey:@"name"]; cell.textLabel.text = 名称;我的 NSPredicate 与: [NSPredicate predicateWithFormat:@"name contains[c] %@", searchText];是因为 user.email 被识别而不是 user.name 吗?错误 Xcode : -[__NSArrayM objectAtIndex:]: index 5 beyond bounds [0 .. 4]

以上是关于带有搜索栏的 cell.accessoryType 不影响 NSPredicate的主要内容,如果未能解决你的问题,请参考以下文章

Swift 3:为啥我不能在 didDeselectRowAt 中更改 cell.accessoryType 和 cell.textLabel

cell.accessoryType = .复选标记

UITableView 中 cell.accessoryType 的问题

cell.accessoryType 在 tableView cellForRowAtIndexPath ... 方法中不起作用

UITableViewCell 的附件类型 accessoryType 选中详情箭头

iosttableViewCell右侧的箭头,圆形等