IOS: UICollectionView UIButtons 不工作

IOS: UICollectionView UIButtons are not working

在我的项目中,我使用 UICollectionView 来显示数据。数据完美地显示在 UICollectionViewCells 中,但我还在单元格中使用 "Edit" 和 "Delete" 按钮来编辑或删除数据。

当我尝试编辑任何单元格并按下 "edit" 按钮时出现问题。它仅适用于前 3 个单元格。当我单击第四个单元格的编辑按钮时,它会在编辑页面上显示第一个单元格的结果,对于第五个单元格,它显示第二行的结果,对于第六个单元格,它显示第三行的内容,然后对于第七行,它再次显示第一行的结果单元格,此过程一直持续到单元格结束。

编辑功能

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {

        static NSString *identifier = @"cellIdentifier";
        UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];

       editbtn = (UIButton *)[cell.contentView viewWithTag:206];
        editbtn.tag = indexPath.row;
        [editbtn addTarget:self action:@selector(editprocedure:) forControlEvents:UIControlEventTouchUpInside];
        [editbtn setTintColor:[UIColor blackColor]];

        deletebtn = (UIButton *)[cell.contentView viewWithTag:207];
        [deletebtn addTarget:self action:@selector(deleteprocedure:) forControlEvents:UIControlEventTouchUpInside];
        [deletebtn setTintColor:[UIColor blackColor]];
        deletebtn.tag = indexPath.row;

        return cell;
    }

我也在分享截图在模拟器上的样子

这里是编辑功能的代码

-(IBAction)editprocedure:(UIButton*)sender
{
    UIButton *btnTapped = (UIButton *)sender;
    self.strdiagid = btnTapped.accessibilityIdentifier;
    NSLog(@"str ID : %@",self.strdiagid);

    self.strdiagid = [CompletephyDic objectForKey:@"id"];
    UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
    EditProcedureVC *vch = [mainStoryboard instantiateViewControllerWithIdentifier:@"EditProcedureVC"];

    self.strdiagid = [CompletephyDic objectForKey:@"id"];
    NSString * a = self.strdiagid;
    NSLog(@"id...%@",a);

    vch.stridd = a; //stridd is the id of the procedure which is transferred to other view
    vch.infoDictionary = [dataArray objectAtIndex:sender.tag];

    [self presentViewController:vch animated:NO completion:nil];
}

试试这个:

 - (void)prepareForReuse {
        [super prepareForReuse];
        //Reset your components to nil here.
    }

Subclass UICollectionViewCell 并将您的 collectionViewCell 的自定义 class 设置为故事板上的此子classed class。制作 EditButton 和 DeleteButton 的出口。

用 indexPath 行或部分替换按钮的标签,并按以下方式访问它:-

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCollectionViewCells *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cvCells" forIndexPath:indexPath];
    [cell.editButton setTag:indexPath.row];
    [cell.button addTarget:self action:@selector(clicked:) forControlEvents:UIControlEventTouchUpInside];
    }

- (IBAction)clicked:(id)sender {

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[sender tag] inSection:0];

    CustomCollectionViewCell *cell = (CustomCollectionViewCell *) [self.collectionview cellForItemAtIndexPath:indexPath];
          //Your desired code for the specific cell
    }

希望对您有所帮助。如果您有任何疑问,请告诉我。

试试这个

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

    [self setAutomaticallyAdjustsScrollViewInsets:NO];
}

很遗憾,所选答案对我不起作用。这是对所做事情的记录:

我花了几个小时在网上搜索我的 UIButton 在 UICollectionView 中无法正常工作的解决方案。让我发疯,直到我终于找到适合我的解决方案。而且我相信这也是正确的方法:破解命中测试。这是一个比修复 UICollectionView 按钮问题更深入(双关语意)的解决方案,因为它可以帮助您将点击事件发送到埋在其他视图下的任何按钮,这些按钮阻止您的事件通过:

UIButton in cell in collection view not receiving touch up inside event

由于 SO 答案在 Objective C 中,我按照那里的线索找到了 swift 解决方案:

http://khanlou.com/2018/09/hacking-hit-tests/

--

当我禁用单元格上的用户交互或我尝试过的任何其他各种答案时,没有任何效果。

我在上面发布的解决方案的美妙之处在于,您可以让您的 addTarget 和选择器函数按照您习惯的方式使用,因为它们很可能永远不会成为问题。您只需覆盖一个函数即可帮助触摸事件到达目的地。

解决方案为何有效:

在最初的几个小时里,我认为我的 addTarget 调用没有正确注册该手势。事实证明目标没有问题。触摸事件根本就没有到达我的按钮。

事实似乎是从我读过的许多 SO 帖子和文章来看,UICollectionView Cells 是用来容纳一个动作的,而不是出于多种原因的多个动作。所以你只是应该使用内置的选择操作。考虑到这一点,我认为绕过此限制的正确 方法不是破解 UICollectionView 以禁用滚动或用户交互的某些方面。 UICollectionView 只是在做它的工作。 正确的 方法是破解命中测试以在它到达 UICollectionView 之前拦截点击并找出他们正在点击的项目。然后,您只需向他们正在点击的按钮发送一个触摸事件,然后让您的正常工作来完成工作。


我的最终解决方案(来自 khanlou.com 文章)是将我的 addTarget 声明和我的选择器函数放在我喜欢的任何地方(在单元格 class 或 cellForItemAt 覆盖中),并在单元格中class 重写 hitTest 函数。

在我的手机里 class 我有:

@objc func didTapMyButton(sender:UIButton!) {
    print("Tapped it!")
}

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {

    guard isUserInteractionEnabled else { return nil }

    guard !isHidden else { return nil }

    guard alpha >= 0.01 else { return nil }

    guard self.point(inside: point, with: event) else { return nil }


    // add one of these blocks for each button in our collection view cell we want to actually work
    if self.myButton.point(inside: convert(point, to: myButton), with: event) {
        return self.myButton
    }

    return super.hitTest(point, with: event)
}

在我的单元格 class init 中,我有:

self.myButton.addTarget(self, action: #selector(didTapMyButton), for: .touchUpInside)