所以我在UICollectionView
中有一个项目列表,其中有一个UIButton
,默认设置为UIImage
,设置为浅灰色的心脏和黑色的心脏。
我的目标是允许用户将项目添加到收藏列表中。我在数据库中添加了一个名为“favorite”的列,它的类型为boolean。
客户在项目的单元格中点击心脏。触发一个方法,用户将传递的项目的对象id作为UIButton
的titleLabel传递,以从数据库中获取项目,并将收藏列的布尔值更新为“True”。
收藏夹按钮的方法:
- (void)addFavouriteButtonTapped:(UIButton *)sender
{
NSLog(@"add to favourites button tapped %@", [[sender titleLabel] text]);
// Set data base favaourite status to 1 (yes)
PFQuery *query = [PFQuery queryWithClassName:@"Garments"];
[query getObjectInBackgroundWithId:[[sender titleLabel] text] block:^(PFObject *object, NSError *error) {
object[@"favourite"] = @YES;
[object saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error) {
[[[UIAlertView alloc] initWithTitle:@"Add Favouite"
message:@"Item successfully added to favourites"
delegate:_thisController
cancelButtonTitle:@"Ok"
otherButtonTitles: nil] show];
} else {
NSLog(@"Something went wrong");
}
}];
}];
}
然后在我的cellForItemAtIndexPath
中,我有一个if语句,用于设置UIButton
的选定状态。
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
NSLog(@"cellForItemAtIndexPath");
// other cell info here deleted to make things clearer
_addFavouriteButton = [cell addFavouriteButton];
// if database favourites status is equal to one then set highlighted to (yes)
if ([object valueForKey:@"favourite"] == [NSNumber numberWithBool:YES]) {
[_addFavouriteButton setSelected:YES];
NSLog(@"SETTING SELECTED");
} else if ([object valueForKey:@"favourite"] == [NSNumber numberWithBool:NO]) {
[_addFavouriteButton setSelected:NO];
}
[[_addFavouriteButton titleLabel] setText:[object objectId]];
[_addFavouriteButton addTarget:_thisController action:@selector(addFavouriteButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
现在,当我离开视野并且一切都被摧毁然后再次返回时,黑色的心出现在我选择的最喜欢的地方。这可以。我遇到的问题是当我实际选择要添加的项目时,心脏会更新并保持灰色,直到我离开UICollectionView
并返回。
我在addFavouriteButtonTapped:方法的主队列中尝试了reloadData
我也尝试重新加载单元格。
这些都不起作用。
我可以将UIButton
的状态设置为选中,但是当我滚动时,选择不会保持位置并移动到其他单元格UIButton
并使用我实际选择的按钮离开单元格。解决这个问题的唯一方法是留下少数几个,以便我们有一个新的UICollectionView
,它使用我数据库中的if语句来确定是否选择了一个单元格。
**My custom cell:**
@interface VAGGarmentCell : UICollectionViewCell
@property (weak, nonatomic) IBOutlet PFImageView *imageView;
@property (weak, nonatomic) IBOutlet UIButton *addFavouriteButton;
@property (weak, nonatomic) IBOutlet UITextView *title;
@property (weak, nonatomic) IBOutlet UILabel *price;
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;
@end
问题:
我已经完成了大部分需要完成的工作,并且可以在构建列出客户收藏列表中的项目的页面时使用收藏夹列。但是如何在点击按钮并成功更新后立即刷新UICollectionView
以显示UIButton
的选定状态?
答案 0 :(得分:1)
确保您也将sender
(即已按下的按钮)设置为选中,或者在更新模型后重新加载集合视图。
更新:在聊天讨论后,此答案已经过编辑和更新。
您的视图控制器中iVar
(或@property
}不需要_addFavouriteButton
,按钮变量应该只是一个局部变量。 collectionView:cellForItemAtIndexPath:object:
方法 - 首先从修复该方法开始
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
NSLog(@"cellForItemAtIndexPath");
// other cell info here deleted to make things clearer
// Create a local variable for your button - this saves a bit of typing in the rest
// of the method. You can also use dot notation as its a property
UIButton *favouriteButton = cell.addFavouriteButton;
BOOL objectFavourited = [object[@"favourite"] boolValue];
NSLog(@"Setting selected? %@", objectFavourited ? @"YES" : @"NO");
favouriteButton.selected = objectFavourited;
// You should set the title directly on the button (as per the docs -
// https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIButton_Class/UIButton/UIButton.html#//apple_ref/occ/instp/UIButton/titleLabel),
// you shouldn't touch titleLabel except for styling
// However you only used the title for seeing which object the favourite button tap was for,
// so I've commented it out
// [favouriteButton setTitle:[object objectId] forState:UIControlStateNormal];
[favouriteButton addTarget:_thisController action:@selector(addFavouriteButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
现在按钮的目标方法。在这里,您应该执行以下操作:更新模型,更改按钮状态,然后保存模型。如果模型成功保存,您的用户是否关心 - 不是真的!但是,如果保存失败,则用户需要知道,并且按钮和模型需要恢复到之前的状态。
我非常确定如果保存失败,该对象将处于与尝试保存之前相同的状态 - favourite
属性设置为YES
。即使它没有,但将其设置回NO
无论如何都不会真正重要。
获取按下按钮的项目的indexPath
的最佳方法是使用与this answer中的方法类似的方法。它是完成索引路径的完美方式,不需要可怕的标签!
现在我们有了项目的索引路径,您不需要查询该特定对象 - 我们可以使用objectAtIndexPath:
直接获取它。
- (void)addFavouriteButtonTapped:(UIButton *)button
{
// Method adapted for a collection view from the above answer
CGPoint hitPoint = [button convertPoint:CGPointZero toView:self.collectionView];
NSIndexPath *hitIndex = [self.collectionView indexPathForItemAtPoint:hitPoint];
// Now get the object for this index
PFObject *object = [self objectAtIndexPath:hitIndex];
NSLog(@"add to favourites button tapped %ld - %@", (long)hitIndex.item, [object objectId]);
// Now update the model
object[@"favourite"] = @YES;
// And the button state
button.selected = YES;
// Now save the model to parse
[object saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!succeeded) {
// Reset the object back to its previous state
object[@"favourite"] = @NO;
// Reload the item to reflect the changes in the model
[self.collectionView reloadItemsAtIndexPaths:@[hitIndex]];
// Only bother the user if something bad happened
[[[UIAlertView alloc] initWithTitle:@"Oops!"
message:@"There was a problem please try again later"
delegate:self
cancelButtonTitle:@"Dismiss"
otherButtonTitles:nil] show];
}
}];
}
您可以重新加载集合视图,但是当您更新该方法中的视图时,实际上并不需要。
但是,如果保存失败,则应重新加载集合视图,因为该按钮可能现在用于集合视图中的其他项目!