简体   繁体   English

如何使用关系查询解析iOS填充UITableView?

[英]How to Use Relational Queries Parse iOS to populate a UITableView?

I'm developing a social app and have some problems with populating objects from parse created in a selected cell. 我正在开发一个社交应用程序,并且在从选定单元格中创建的解析中填充对象时遇到一些问题。

The Home screen is a UITableViewController, populates an array of objects stored in Parse, when a user taps a cell, a new scene DetailViewController will be pushed, which shows the object from the selected cell in a view. 主屏幕是一个UITableViewController,用于填充存储在Parse中的对象的数组,当用户点击一个单元格时,将推送一个新的场景DetailViewController,该视图将在视图中显示所选单元格中的对象。

Next, I created in DetailViewController a UIButton to add objects to a new class called "replies" and also have added into the DetailViewController scene, a TableView which is populated using a new array from those objects at the "replies" class. 接下来,我在DetailViewController中创建了一个UIButton,用于将对象添加到名为“ replies”的新类中,并且还将TableView添加到DetailViewController场景中,该TableView使用来自“ replies”类中这些对象的新数组填充。

I want to retrieve just the objects created on the selected cell :( At the moment everything works fine except on the DetailViewController scene the TableView will show all the objects created in the "replies" class no matter on which cell I tap. 我只想检索在选定单元格上创建的对象:(目前,除了在DetailViewController场景上,一切正常之外,无论我点击哪个单元格,TableView都将显示在“ replies”类中创建的所有对象。

I wonder how would I store an array from the selected cell so I can populate the objects that have been created at that selected cell... I believe that I could solve this issue with relational queries from parse at the retrieve from parse method. 我不知道如何存储选定单元格中的数组,以便可以填充在该选定单元格中创建的对象...我相信我可以通过在parse from parse方法中进行解析的关系查询来解决此问题。

Would Appreciate Very Much Any Help. 会非常感谢您的帮助。

.h file .h文件

#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#import <ParseUI/ParseUI.h>
#import "GroundTableViewCell.h"
#import "TimelineTableViewController.h"

@interface DetailViewController : UIViewController<
UITableViewDataSource,
UITableViewDelegate,
NSObject>
{
}

@property (strong, nonatomic) IBOutlet UITableView *detailTableView;
@property (strong, nonatomic) IBOutlet UITextView *TextField;
@property (nonatomic, strong) PFObject *groUnds;
@property (strong, nonatomic) IBOutlet UITextView *replyTextView;
- (IBAction)sendReply:(id)sender;

@end

.m file .m文件

#import "DetailViewController.h"
#import <Parse/Parse.h>
#import "GroundTableViewCell.h"
#import "TimelineTableViewController.h"

@interface DetailViewController ()
@property(strong)NSMutableArray* repliesMutableArray;

@end

@implementation DetailViewController

@synthesize groUnds;
@synthesize TextField;
@synthesize detailTableView;
@synthesize repliesMutableArray;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    PFUser *currentUser = [PFUser currentUser];
    if (currentUser) {
        // do stuff with the user
    } else {
        // show the signup or login screen
    }

    // Do any additional setup after loading the view.
//      [self performSelector:@selector(retrieveFromParse)];
//    repliesArray = [[NSArray alloc] initWithObjects:@"comment", nil];

       [self performSelector:@selector(retrieveFromParse)];

    // Set the Label text with the selected detail.
    self.TextField.text = [self.groUnds objectForKey:@"comment"];
}

- (void) retrieveFromParse {
    PFQuery *retrieveReplies = [PFQuery queryWithClassName:@"Replies"];

  // This is the part where im not really sure how to query...
 // if uncommented won't show any objects at all now shows all the objects from the "Replies class" -->
  //  [retrieveReplies whereKey:@"comment" equalTo:groUnds];
    [retrieveReplies orderByDescending:@"createdAt"];

    [retrieveReplies findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (!error) {
            repliesMutableArray = [[NSMutableArray alloc] initWithArray:objects];
        }
        [detailTableView reloadData];
    }];
}

//*********************Setup table of folder names ************************
//get number of sections in tableview
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}

//get number of rows by counting number of folders
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [repliesMutableArray count ];
}

//setup cells in tableView
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"replyCell";
    GroundTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    PFObject *tempObject = [repliesMutableArray objectAtIndex:indexPath.row];
    cell.cellTitle.text = [tempObject objectForKey:@"commentReplies"];

    return cell;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

 //reply button
- (IBAction)sendReply:(id)sender {
    //1
    //Add the image to the object, and add the comment and the user
    PFObject *Reply = [PFObject objectWithClassName:@"Replies"];
    [Reply setObject:[PFUser currentUser].username forKey:@"user"];
    [Reply setObject:self.replyTextView.text forKey:@"commentReplies"];
    //2
    [Reply saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
        //3
        if (succeeded){
            //Go back to the wall
            [self.navigationController popViewControllerAnimated:YES];
        }
        else{
            NSString *errorString = [[error userInfo] objectForKey:@"error"];
            UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
            [errorAlertView show];
        }
    }];
}

@end

Overview 概观

The basic structure of passing information between view controllers is that you need to set the data you want to display in the Detail View Controller (DVC) while you are in the main view controller (MVC). 在视图控制器之间传递信息的基本结构是,当您位于主视图控制器(MVC)中时,需要设置要在明细视图控制器(DVC)中显示的数据。 So on the delegate method in the MVC which is called when you select a cell (didSelectRowAtIndexPath) you can get the data specific to the selected cell and place it into a variable. 因此,在选择单元格(didSelectRowAtIndexPath)时调用的MVC中的委托方法上,可以获得特定于所选单元格的数据并将其放入变量中。 Inside of the prepareForSegue... method you can set that data to be a variable on the dvc that represents your tableview data. 在prepareForSegue ...方法内部,可以将数据设置为dvc上代表表视图数据的变量。

Passing Data Between View Controllers 在视图控制器之间传递数据

To see how to properly pass data between view controllers look at the answers to this highly rated question on SO. 要了解如何在视图控制器之间正确传递数据,请查看对SO的高度评价的问题的答案。

You can think of this as a push instead of pull. 您可以将其视为推动而非拉动。 Data should be added to a property on the DVC before the view is presented. 在显示视图之前,应将数据添加到DVC的属性中。 There are a number of ways to limit the data using NSPredicates, SubQueries, Related Queries or Queries on Array Values: 使用NSPredicates,子查询,相关查询或数组值查询有多种方法来限制数据:

Queries on Array Values 数组值查询

For keys with an array type, you can find objects where the key's array value contains 2 by: 对于具有数组类型的键,可以通过以下方式找到键的数组值包含2的对象:

// Find objects where the array in arrayKey contains 2.
// Using PFQuery
[query whereKey:@"arrayKey" equalTo:@2];

// Or using NSPredicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"2 IN arrayKey"];
PFQuery *query = [PFQuery queryWithClassName:@"MyClass" predicate:predicate];

( more Parse Queries ) 更多解析查询

Keep in mind that you can also handle this problem of refining the data by using Apple API solutions to refine the data you add onto the DVC property. 请记住,您还可以使用Apple API解决方案来优化添加到DVC属性中的数据,从而解决优化数据的问题。 You mentioned that you are new so please make sure you have read and completed the tutorial on the getting started link below. 您提到您是新手,因此请确保您已阅读并完成下面的入门链接上的教程。 It's important because it shows Apple's paradigm for handling data movement in iOS. 这很重要,因为它显示了Apple处理iOS中数据移动的范例。

Getting Started 入门

Please review the getting started guide if the explanation doesn't make sense. 如果解释不合理,请查阅入门指南 There are critical concepts that cannot be glossed over or easily explained in the context of this answer. 在此答案的上下文中,有些关键概念无法掩盖或轻易解释。

Proposed Resolution 拟议决议

Pass in the indexPath.row of the selected cell to detail view controller so that you can limit the results of the array to that cell. 将所选单元格的indexPath.row传递到详细信息视图控制器,以便可以将数组的结果限制为该单元格。 If the indexPath row is not useful for this purpose then just pass a value that will limit the results to something unique within the selected cell. 如果indexPath行对此没有用,则只需传递一个值,该值会将结果限制为所选单元格中唯一的值。 Use the delegate method didSelectRowAtIndexPath on your tableview delegate to set a relevant data value that you pass to the object managing the underlying tableview on the detail scene. 在表视图委托上使用委托方法didSelectRowAtIndexPath来设置一个相关的数据值,该数据值将传递给管理详细场景中基础表视图的对象。 You will want to identify a "where-clause" that is appropriate to the data you want to show in the DVC and then use either a new query or an nspredicate to limit the results from your array of data. 您将要确定一个与要在DVC中显示的数据相对应的“ where-clause”,然后使用新查询或nspredicate来限制数据数组中的结果。 Search SO for examples of each of these concepts. 在SO中搜索每个概念的示例。

Hopefully these tips will help you to find the ultimate answer. 希望这些技巧将帮助您找到最终的答案。 Searching SO will give you examples that you then need to apply to your specific situation. 搜索SO将为您提供示例,然后您需要将这些示例应用于您的特定情况。 However, I really recommend that you step back for a moment to make sure you understand how to pass data between view controllers correctly. 但是,我确实建议您退一步,以确保您了解如何正确在视图控制器之间传递数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM