【问题标题】:Problems Implementing Search Bar with Parse Data使用解析数据实现搜索栏的问题
【发布时间】:2015-01-27 22:16:16
【问题描述】:

我已经在谷歌的土地上进行了广泛的搜索,并找到了这方面的教程,但它们是在 IOS8 之前的。我已尽我所能将其拼凑在一起,但是当应用程序运行时,我在搜索栏中输入单词时,什么也没有返回,或者它崩溃了。下面是视图的外观,以及每个对象的含义:

这是我的 JobListViewController.m 文件:

#import "JobDetailViewController.h"
#import "JobListViewController.h"
#import "Job.h"
#import "SearchedResultCell.h"


@interface JobListViewController () <UISearchDisplayDelegate, UISearchBarDelegate> {

}

@property (nonatomic, weak) IBOutlet UISearchBar *searchedBar;
@property (nonatomic, strong) NSString *mainTitle;
@property (nonatomic, strong) NSString *subTitle;
@property (nonatomic, assign) BOOL canSearch;

@end

@interface JobListViewController ()

@end

@implementation JobListViewController
{
    NSArray *jobs;
    NSArray *searchResults;
}
@synthesize searchedBar;
@synthesize mainTitle;
@synthesize subTitle;
@synthesize canSearch;


- (id)initWithCoder:(NSCoder *)aCoder
{
    self = [super initWithCoder:aCoder];
    if (self) {
        // Custom the table

        // The className to query on
        self.parseClassName = @"Jobs";

        // The key of the PFObject to display in the label of the default cell style
        self.textKey = @"Position";

        // Whether the built-in pull-to-refresh is enabled
        self.pullToRefreshEnabled = YES;

        // Whether the built-in pagination is enabled
        self.paginationEnabled = YES;

        // The number of objects to show per page
        self.objectsPerPage = 10;
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.searchedBar becomeFirstResponder];


}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    self.canSearch = 0;

}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (void)objectsWillLoad {
    [super objectsWillLoad];

    // This method is called before a PFQuery is fired to get more objects
}


- (PFQuery *)queryForTable
{
    PFQuery *query;

    if (self.canSearch == 0)
    {
        query = [PFQuery queryWithClassName:@"Jobs"];
    }
    else
    {
        query = [PFQuery queryWithClassName:@"Jobs"];

        NSString *searchThis = [searchedBar.text uppercaseString];
        [query whereKey:@"Position" containsString:searchThis];

    }


    [query orderByAscending:@"Position"];


        query.cachePolicy = kPFCachePolicyCacheThenNetwork;


    return query;
}




- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object: (PFObject *)object
{
    static NSString *simpleTableIdentifier = @"JobCell";
        static NSString *pimpleTableIdentifier = @"JobCell";

    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];

    SearchedResultCell *cell = [self.tableView dequeueReusableCellWithIdentifier:pimpleTableIdentifier];

    if (cell == nil) {
        cell = [[SearchedResultCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:pimpleTableIdentifier];

        }

        [self configureSearchResult:cell atIndexPath:indexPath object:object];


    }

    // Configure the cell
    PFFile *thumbnail = [object objectForKey:@"imageFile"];
    PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
    thumbnailImageView.image = [UIImage imageNamed:@"placeholder.jpg"];
    thumbnailImageView.file = thumbnail;
    [thumbnailImageView loadInBackground];

    UILabel *positionLabel = (UILabel*) [cell viewWithTag:101];
    positionLabel.text = [object objectForKey:@"Position"];
    UILabel *rotationLabel = (UILabel*) [cell viewWithTag:102];
    rotationLabel.text = [object objectForKey:@"Rotation"];
    UILabel *locationLabel = (UILabel*) [cell viewWithTag:103];
    locationLabel.text = [object objectForKey:@"Location"];
    UILabel *typeLabel = (UILabel*) [cell viewWithTag:104];
    typeLabel.text = [object objectForKey:@"Type"];


return cell;
}

- (void) objectsDidLoad:(NSError *)error
{
    [super objectsDidLoad:error];

    NSLog(@"error: %@", [error localizedDescription]);
}


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"showJobDetail"]) {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];

        Job *job = [[Job alloc] init];

        JobDetailViewController *destViewController = segue.destinationViewController;

        PFObject *object = [self.objects objectAtIndex:indexPath.row];
        job.position = [object objectForKey:@"Position"];
        job.name = [object objectForKey:@"Name"];
        job.email = [object objectForKey:@"Email"];
        job.phone = [object objectForKey:@"Phone"];
        job.imageFile = [object objectForKey:@"imageFile"];
        job.rotation = [object objectForKey:@"Rotation"];
        job.location = [object objectForKey:@"Location"];
          job.type = [object objectForKey:@"Type"];
        job.clearance = [object objectForKey:@"Clearance"];
        job.job_description = [object objectForKey:@"Job_Description"];
        job.qualifications = [object objectForKey:@"Qualifications"];
        destViewController.job = job;

    }

}

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{

    [self clear];

    self.canSearch = 1;

    [self.searchedBar resignFirstResponder];

    [self queryForTable];
    [self loadObjects];

}
/*
 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 {
 if (searchResults == nil) {
 return 0;
 } else if ([searchResults count] == 0) {
 return 1;
 } else {
 return [self.objects count];
 }
 }
 */
- (void)configureSearchResult:(SearchedResultCell *)cell atIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
    mainTitle = [object objectForKey:@"Position"];
    cell.mainTitle.text = mainTitle;

    subTitle = [object objectForKey:@"Type"];
    cell.detail.text = subTitle;

     // Implement this if you want to Show image
     cell.showImage.image = [UIImage imageNamed:@"placeholder.jpg"];

     PFFile *imageFile = [object objectForKey:@"imageFile"];

     if (imageFile) {
     cell.showImage.file = imageFile;
     [cell.showImage loadInBackground];
     }
}


#pragma mark - UITableViewDelegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    [searchedBar resignFirstResponder];

    if ([self.objects count] == indexPath.row) {
        [self loadNextPage];
    } else {
        PFObject *photo = [self.objects objectAtIndex:indexPath.row];
        NSLog(@"%@", photo);

        // Do something you want after selected the cell
    }
}

#pragma mark - UIScrollViewDelegate


- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    [self.searchedBar resignFirstResponder];
}

- (void)searchBarCancelButtonClicked:(UISearchBar *) searchBar {
    [self.searchedBar resignFirstResponder];
    [self queryForTable];
    [self loadObjects];

}




@end

我找不到哪里出错了。任何帮助将不胜感激。或者如果你能指出我正确的方向的话。

【问题讨论】:

    标签: objective-c xcode parse-platform searchbar uisearchbardelegate


    【解决方案1】:

    几个月前我遇到了问题,所以下面是一个对我很有帮助的项目。也希望你。

    https://github.com/mwazir2/ParseSearchNoPagination

    干杯!

    更新

    在我对上面这个例子的改编中,我遵循了项目中的所有内容。该项目使用 Parse SDK 中的 PFQueryTableViewController,而不是默认的 iOS TableViewController。

    在第一部分 -(id)initWithCoder 我已经评论了

    //self.textKey = @"username";
    

    然后我在某些方面更改了 - (PFQuery *)queryForTable 方法。一个只是更改了 whereKey 以适应我的项目,第二个更改了查询,因为它应该只显示在与特定用户相关的表对象中。以下是各自的查询。

    第一个更一般的查询

    - (PFQuery *)queryForTable
    {
    PFQuery *query = [PFUser query];
    if (self.canSearch == 0) {
        query = [PFQuery queryWithClassName:@"_User"];
    } else {
    
    
        query = [PFQuery queryWithClassName:@"_User"];
    
        NSString *searchThis = [searchedBar.text capitalizedString];
    
        //PFQuery *query = [PFQuery queryWithClassName:@"Channel"];
        //[query whereKey:@"channelName" equalTo:searchThis];
        [query whereKey:@"username" containsString:searchThis];
    
    }
    

    第二个,特定于当前用户:

    - (PFQuery *)queryForTable
    {
    PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
    [query whereKey:@"owner" equalTo:[PFUser currentUser]];
    
    [query orderByDescending:@"createdAt"];
    
    if (self.pullToRefreshEnabled) {
        query.cachePolicy = kPFCachePolicyNetworkOnly;
    }
    
    // If no objects are loaded in memory, we look to the cache first to fill the table
    // and then subsequently do a query against the network.
    if (self.objects.count == 0) {
        query.cachePolicy = kPFCachePolicyCacheThenNetwork;
    }
    
    return query;
    }
    

    对于我只使用的 tableView 方法:tableView cellForRowAtIndexPath(很像你的)。还有 LoadMoreCell 的 cellForRowAtIndexPath,如示例中所示。

    还有 tableView heightForRowAtIndexPath: 用于 LoadMoreCell 和 tableView didSelectRowAtIndexPath,如下所示:

     - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:  (NSIndexPath *)indexPath
     {
     [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
    //[searchedBar resignFirstResponder];
    
    if ([self.objects count] == indexPath.row) {
        [self loadNextPage];
    } else {
        PFObject *photo = [self.objects objectAtIndex:indexPath.row];
        NSLog(@"%@", photo);
    
        // Do something you want after selected the cell
    }
    }
    

    当然,在 } else { 语句下面你可以更改它或删除 NSLog 行。

    我建议您尝试使用您的对象和键来更改示例本身,直到它起作用,然后更改您的,就像示例一样...:)

    复合查询

    PFQuery *query1 = [PFQuery queryWithClassName:@"Class1"];
    [name whereKey:@"column1" equalTo:[fieldInCode text]];
    PFQuery *query2 = [PFQuery queryWithClassName:@"Class1"];
    [enterKey whereKey:@"column2" equalTo:[anotherField text]];
    PFQuery *query = [PFQuery orQueryWithSubqueries:@[query1,query2]];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError   *error) {
    

    干杯!

    【讨论】:

    • 谢谢,我遵循了他们的编码,它让我走得更远,但是当我在搜索栏中输入文本时它不起作用。我认为这是我的 PFQuery 方法 queryForTable。我告诉它在我的名为 Jobs 的类中查找,我希望它专门搜索名为 Position 的 Key 的内容。但是它并没有这样做。
    • 嗨,伙计!我现在有点着急,大概 8 小时后我会回到这里,并用我从这个代码示例中更新的一些内容来编辑我的答案,这些内容是我指向你的。只是要知道,您在 Parse 中的 ACL 列设置为 public read and write ?如果是私下,该查询将无法正常工作...
    • 没问题!是的,我的 ACL 列设置为公共读写。
    • 我认为它不会同时搜索多个键。但它搜索键之间的关系......在我的回答中,第二个查询使用该关系特征。但是你必须设置你的对象和代码才能工作并且有任何关系。在 Parse 文档中,他们对此进行了更多解释。另外我建议下载他们的一些项目教程,因为他们实现了那种关系
    • 嗨@DiplomaticMedic!我做了一些研究,发现了可以搜索相同类型的两个键的查询类型。它被 Parse 称为复合查询。它在他们的文档中描述,查询部分的最后一项。我将使用复合查询更新我的答案。干杯!
    猜你喜欢
    • 2022-07-06
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多