PFQueryTableViewController 快速按日期划分

Posted

技术标签:

【中文标题】PFQueryTableViewController 快速按日期划分【英文标题】:PFQueryTableViewController sections by date in swift 【发布时间】:2015-05-24 18:20:34 【问题描述】:

首先,这可能是一个菜鸟问题,但我试图解决它一段时间但我无法解决。

目标:

使用 [PFQueryTableViewController][1],我想要有与日期相关的部分。

例如:本周、下周、很快。

背景:

有关在 PFQueryTableViewController 上添加部分的问题在此 [Parse topic][2] 中进行了讨论。但该方法与日期间隔无关,我未能使其适应我的目标。

问题:

请你们指出我应该采取哪些步骤来获得我想要的东西?首先,区分不同时间间隔的条目(例如本周,下周,例如)-从Parse中获取-,然后分段排列?

我正在使用 swift。

提前致谢!


编辑

@danh 建议放弃 PFQTVC 并开始一个新的 ViewController:这种方法的代码可以满足问题的要求,可以在 Objective C 的答案中找到斯威夫特

【问题讨论】:

您能否发布一些代码,显示您迄今为止尝试过的内容以及为什么它不起作用? 有两个挑战。第一种是取一个平面数组,将其分成N个按时间划分的数组。第二个挑战是操纵 pa​​rse 的 PFQueryTableVC 来处理二维数组而不是默认的平面数组。你正在为哪一个挑战而苦苦挣扎?请展示您目前所掌握的内容以及您认为哪里出了问题。 @danh 我用我可以对第一个挑战做些什么来编辑这个问题。但我不知道如何获得第二部分,将所有内容设置为部分。 按时间划分分区是合理的尝试,但如果您使用的是 PFQueryTableVC,则不是。您只需要在 queryForTable 方法中返回一个查询,然后对来自一个查询的结果进行除法。 @danh 我正在考虑放弃 PFQueryTableVC。也许使用标准的 UITableView 来获得我想要的东西,在 Parse 和 Core Data 之间进行同步会更好。你怎么看?你能告诉我哪一个是最好的方法吗?谢谢! 【参考方案1】:

根据我的经验,PFQueryTableViewController 可以为您节省一点工作量,并花费大量的灵活性。使用常规 UIViewController 子类的想法看起来像这样(将尝试使用最少的代码,因为我意识到 Objective-c 是 OP 的错误语言):

创建视图控制器,添加一个 UITableView 和一个名为 tableView 的出口。将表视图的数据源设置为视图控制器。

所有的表视图都需要一个模型对象数组,而我们的需要一个数组数组。这些将是按日期分组为三个数组的 PFObject。所以我们需要一个函数来从解析中查询并分组结果。

@property(weak) IBOutlet UITableView *tableView;
@property(strong) NSMutableArray *objects;

// in viewDidLoad, make an array of three arrays
self.objects = [NSMutableArray array];
[self.objects addObject:[NSMutableArray array]];
[self.objects addObject:[NSMutableArray array]];
[self.objects addObject:[NSMutableArray array]];

// in viewDidAppear, call the fetch
- (void)viewDidAppear:(BOOL)animated 
    [super viewDidAppear:animated];
    [self fetchData];


- (void)fetchData 
    PFQuery *query = [PFQuery queryWithClassName:@"MyClass"];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) 
        if (!error) 
            for (PFObject *object in objects) 
                [self insertModel:object];
            
            [self.tableView reloadData];
        
    ];


- (void)insertModel:(PFObject *)object 
    NSDate *starts = [object valueForKey@"Starts"];
    // dates are a complex topic in ios, since you're working in swift
    // its wasteful for me to go through the date calc in objective c.
    // see this answer in SO for how to get dates like thisWeek, nextWeek, etc:
    // http://***.com/a/29056735/294949

    NSMutableArray *soonModel = self.model[0];
    NSMutableArray *thisWeekModel = self.model[1];
    NSMutableArray *nextWeekModel = self.model[2];
    if (/* starts in soon range */) [soonModel addObject:object];
    if (/* starts in this week range */) [thisWeekModel addObject:object];
    if (/* starts in next week range */) [nextWeekModel addObject:object];


- (PFObject *)objectAtIndexPath:(NSIndexPath *)indexPath 
    NSArray *section = self.model[indexPath.section];
    return section[indexPath.row];

这是第一个挑战。调用 parse,将结果分成三个数组。由于我们已经抛弃了 PFQueryTableVC,我们不需要跳过任何障碍来使用它。我们只需要像任何应用程序一样实现 tableview 数据源方法:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    return self.model.count;


- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
    if (section == 0) return @"Soon";
    if (section == 1) return @"This Week";
    if (section == 2) return @"Next Week";
    return nil;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    NSArray *section = self.model[section];
    return section.count;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    // get your cell as you would in swift
    PFObject *object = [self objectAtIndexPath:indexPath];
    // configure cell with values from object
    return cell;

【讨论】:

感谢@danh 的回答!我正在努力,这是我延迟回答的原因。当我得到它时,我会在这里发布。再次感谢您! 乐于助人。考虑,在处理这个问题时,将工作分解为两部分:(1)获取和划分 PFObjects,(2)呈现多节表。我会先做(2),只需硬编码一个数组数组来测试它,不用担心解析。然后(1.a)只是证明您可以获取对象并将它们划分为一些简单的函数,而不用担心日期,这是一个很难的话题。最后,(1.b) 按日期划分 PFObjects。【参考方案2】:

非常感谢@danh,为我指路!

我用 Swift 完成了这个工作!我想代码中有一些不好的做法,如果有人能指出它们以更好地帮助那些寻求问题的人,我将不胜感激。

var container:NSMutableArray = NSMutableArray()
var thisWeek:NSMutableArray = NSMutableArray()
var nextWeek:NSMutableArray = NSMutableArray()


//FetchData
func fetchData() 

    var query = PFQuery(className: "container")
    query.findObjectsInBackgroundWithBlock  (objects, error) -> Void in
        if error == nil 
            if let staffObjects = objects as? [PFObject] 
                for staff in staffObjects 
                    self.insertModel(staff)
                
                self.tableView.reloadData()
            
         else 
            NSLog("error: \(error)")
        
    


// Models
func insertModel(object: PFObject)
    var starts: NSDate = (object.valueForKey("Starts") as? NSDate)!

    // Here I managed to build the rules very easily using 
    // the SwiftDate Pod (https://github.com/malcommac/SwiftDate)
    let today = NSDate.today()
    let todayPlus7Days = today.add(years: 0, months: 0, weeks: 0, days: 7, hours: 0, minutes: 0, seconds: 0)
    let todayPlus14Days = today.add(years: 0, months: 0, weeks: 0, days: 14, hours: 0, minutes: 0, seconds: 0)

    if starts >= today && starts < todayPlus7Days 
        thisWeek.addObject(object)
    
    if starts >= todayPlus7Days && starts < todayPlus14Days
        nextWeek.addObject(object)
    


func objectAtIndexPath(indexPath: NSIndexPath) -> PFObject 
    var section: NSArray = container[indexPath.section] as! NSArray
    return section[indexPath.row] as! PFObject


// Table View
func numberOfSectionsInTableView(tableView: UITableView) -> Int 
    return container.count


func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? 
    if section == 0  return "NEXT 7 DAYS" 
    if section == 1  return "ANOTHERS 7 DAYS" 
    return nil


func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    var section: NSArray = container[section] as! NSArray
    return section.count


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    var cell:DestaqueTableViewCell? = tableView.dequeueReusableCellWithIdentifier("destaqueCell") as? DestaqueTableViewCell
    let object: PFObject = objectAtIndexPath(indexPath)
    // Configure cell with values from object
    return cell!


// - viewDidLoad
override func viewDidLoad() 
    super.viewDidLoad()
    container.addObject(thisWeek)
    container.addObject(nextWeek)
    fetchData()

【讨论】:

看起来不错(据我所知,swift)。我注意到的一件事是您在 insertModel 中使用了排他的不等式运算符。底部检查(如开始>今天)不应该包含(如开始> =今天)吗? +7天也一样?如果不包括下限,您可能会在日期范围内留下微小的差距。真高兴你做到了。干得好!

以上是关于PFQueryTableViewController 快速按日期划分的主要内容,如果未能解决你的问题,请参考以下文章