我遇到了一个问题,即我的收藏视图中的对象会无意间碰撞并互相交互。
说明:
我有一个UICollectionView,我用自定义的UICollectionViewCell对象填充。这一切都很好,很好。我还有标题来分隔每个部分。
现在,这些按钮的基本功能之一是关闭状态和开启状态。
但问题是,当我按下按钮时," on"对于我的第一部分中的某些内容,它会变成" on"或者"关闭"我的上一部分中的一个按钮,显示在屏幕外。此外,章节标题也有重叠。
以下是生成每个单元格的代码:
自定义单元格类
- (id) initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.tagBtn = [UIButton buttonWithType:UIButtonTypeCustom];
self.tagBtn.frame = CGRectMake(-frame.size.width/4+20, -frame.size.width/4+15, frame.size.width, frame.size.height);
[[self.tagBtn layer] setBorderColor:[[UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f] CGColor]];
[[self.tagBtn layer] setBorderWidth:1.0f];
self.tagBtn.backgroundColor = [UIColor whiteColor];
[self.tagBtn setTitleColor:[UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f] forState:UIControlStateNormal];
self.tagBtn.titleLabel.font = [UIFont systemFontOfSize:12.0f];
[self.tagBtn addTarget:self action:@selector(toggleTag) forControlEvents:UIControlEventTouchUpInside];
[self.contentView addSubview:self.tagBtn];
}
return self;
}
单元格数据源代理
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
TagCellCollectionViewCell *cell = (TagCellCollectionViewCell *) [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
NSArray *data = [dataArray objectAtIndex:indexPath.section];
// Configure the cell
NSString *labelText = data[indexPath.row];
[cell.tagBtn setTitle:labelText forState:UIControlStateNormal];
return cell;
}
按钮切换方法
- (void) toggleTag {
if (self.tagBtn.backgroundColor == [UIColor whiteColor]) {
self.tagBtn.backgroundColor = [UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f];
[self.tagBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
}
else {
self.tagBtn.backgroundColor = [UIColor whiteColor];
[self.tagBtn setTitleColor:[UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f] forState:UIControlStateNormal];
}
}
章节标题
- (UICollectionReusableView *) collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
if (kind == UICollectionElementKindSectionHeader) {
UICollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"Header" forIndexPath:indexPath];
if (headerView == nil) {
headerView = [[UICollectionReusableView alloc] initWithFrame:CGRectMake(5, 0, 320, 25)];
}
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(15, 0, 320, 25)];
label.text = [NSString stringWithFormat:@"Section %li", indexPath.section];
[label setTextColor:[UIColor colorWithRed:38.0f/255.0f green:34.0f/255.0f blue:108.0f/255.0f alpha:1.0f]];
headerView.backgroundColor = [UIColor colorWithRed:204.0f/255.0f green:204.0f/255.0f blue:222.0f/255.0f alpha:1.0f];
[headerView addSubview:label];
return headerView;
}
return nil;
}
您还有什么想看的吗?
更新
新按钮代码,答案如下
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
TagCellCollectionViewCell *cell = (TagCellCollectionViewCell *) [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
NSArray *data = [dataArray objectAtIndex:indexPath.section];
// Configure the cell
NSString *labelText = data[indexPath.row];
[cell.tagBtn setTitle:labelText forState:UIControlStateNormal];
[cell.tagBtn addTarget:self action:@selector(toggleTag:) forControlEvents:UIControlEventTouchUpInside];
cell.tagBtn.tag = indexPath.row + 1000*indexPath.section;
if (self.toggledIndexPath == indexPath) {
cell.tagBtn.backgroundColor = [UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f];
[cell.tagBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
}
else {
cell.tagBtn.backgroundColor = [UIColor whiteColor];
[cell.tagBtn setTitleColor:[UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f] forState:UIControlStateNormal];
}
return cell;
}
- (void) toggleTag:(UIButton *) btn {
NSIndexPath *path;
if (btn.backgroundColor == [UIColor whiteColor]) {
path = [NSIndexPath indexPathForItem:btn.tag/1000 inSection:btn.tag % 1000];
}else{
path = [NSIndexPath indexPathForItem:-1 inSection:0];
}
self.toggledIndexPath = path;
[self.collectionView reloadData];
}
答案 0 :(得分:2)
您的代码有几个与单元格和标题视图重用有关的问题。您对单元格UI所做的任何更改都应该在cellForItemAtIndexPath中完成,而不是像在按钮的操作方法中那样。如果在action方法中执行此操作,则在重用该单元格时,该按钮仍将具有这些更改的值,但现在位于集合视图中的不同位置。您需要获取触摸按钮的单元格的indexPath。有几种方法可以做到这一点,最简单的方法是给你的按钮一个基于indexPath的标签(当你有部分时,你需要使用两者,比如button.tag = indexPath.row + 1000 * indexPath.section )。在按钮的操作方法中,您应该在数据源中设置一些属性,指示特定indexPath上的按钮应该更改其属性,然后在cellForItemAtIndexPath中的if-else子句中更改它们。
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
TagCellCollectionViewCell *cell = (TagCellCollectionViewCell *) [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
NSArray *data = [dataArray objectAtIndex:indexPath.section];
NSString *labelText = data[indexPath.row];
[cell.tagBtn setTitle:labelText forState:UIControlStateNormal];
[cell.tagBtn addTarget:self action:@selector(toggleTag:) forControlEvents:UIControlEventTouchUpInside];
cell.tagBtn.tag = indexPath.row + 1000*indexPath.section;
if (self.toggledIndexPath == indexPath) {
cell.tagBtn.backgroundColor = [UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f];
[self.tagBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
}else {
cell.tagBtn.backgroundColor = [UIColor whiteColor];
[cell.tagBtn setTitleColor:[UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f] forState:UIControlStateNormal];
}
return cell;
}
- (void) toggleTag:(UIButton *) btn {
if (self.tagBtn.backgroundColor == [UIColor whiteColor]) {
indexPath *path = [NSIndexPath indexPathForItem:btn.tag % 1000 inSection:btn.tag/1000];
}else{
indexPath *path = [NSIndexPath indexPathForItem:-1 inSection:0];
}
self.toggledIndexPath = path;
[self.tableView reloadData];
}
请注意,我在cellForRowAtIndexPath中添加了按钮的操作方法,而不是在按钮的init方法中。 toggledIndexPath是我添加的属性,用于跟踪触摸的按钮。
部分标题的问题在于,您要向headerView添加多个标签,因为当调用viewForSupplementaryElementOfKind并且它有一个要重复使用的单元格时,您仍然会向其添加标签。您应该在xib中创建视图,或者在视图的init方法中添加任何子视图(如果您在代码中执行所有操作)。您应该在viewForSupplementaryElementOfKind中做的唯一事情是设置标题并返回视图。
答案 1 :(得分:1)
集合视图部分重叠问题解决此代码
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
UICollectionReusableView *reusableview=nil;
reusableview = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];
NSArray *viewsToRemove = [reusableview subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
if (reusableview==nil) {
reusableview=[[UICollectionReusableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 30)];
}
reusableview.backgroundColor=[UIColor colorWithRed:234.0/255.0 green:234.0/255.0 blue:234.0/255.0 alpha:1.0];
UILabel *lblTitle=[[UILabel alloc] initWithFrame:CGRectMake(10, 0, [UIScreen mainScreen].bounds.size.width-90, 30)];
[lblTitle setFont:[UIFont fontWithName:@"Ubuntu-Light" size:12]];
lblTitle.textColor=HTAtHomeColor;
[reusableview addSubview:lblTitle];
UILabel *lblCount=[[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width-80, 0, 70, 30)];
lblCount.textAlignment=NSTextAlignmentRight;
lblCount.textColor=[UIColor blackColor];
[lblCount setFont:[UIFont fontWithName:@"Ubuntu-Light" size:12]];
if (indexPath.section==0){
lblCount.text=[NSString stringWithFormat:@"%ld Selected",(long)mealTypeCount];
lblTitle.text=[NSString stringWithFormat:@"MEAL TYPE"];
}
else if (indexPath.section==1){
lblCount.text=[NSString stringWithFormat:@"%ld Selected",(long)mealOfDayCount];
lblTitle.text=[NSString stringWithFormat:@"MEAL OF THE DAY"];
}
else if (indexPath.section==2){
lblCount.text=[NSString stringWithFormat:@"%ld Selected",(long)cuisineCount];
lblTitle.text=[NSString stringWithFormat:@"TYPES OF CUSINE"];
}
[reusableview addSubview:lblCount];
return reusableview;
}
return nil;
}