带有分页功能的UICollectionView,每个单元格覆盖整个屏幕,拖动时出现问题,但尚未转到下一个或上一个单元格

问题描述 投票:0回答:3

我在启用分页的情况下遇到 UICollectionView 问题。每个单元格将覆盖整个屏幕,因此一次只能看到 1 个单元格 在主视图中,我有 UICollectionView,当用户滑动到其他单元格时,导航标题将根据新单元格而变化,当用户正确滑动时,这非常有效,这意味着当滑动时,UICollectionView 将整个新单元格推送到屏幕 但是,当用户稍微滑动以显示下一个单元格,然后移回到当前显示的单元格时,导航标题会发生变化,但内容仍然是当前的 有谁知道如何解决这个问题? 我在这里附上图片作为说明

这是我的代码:

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    SingleLabViewCollectionScrollCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:collectionCellID forIndexPath:indexPath];
    if (cell == nil){
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"SingleLabViewCollectionScrollCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }
    
    // hide
    [cell.viewMain2 setHidden:YES];
    [cell.viewMain3 setHidden:YES];
    [cell.viewBubble2 setHidden:YES];
    [cell.viewBubble3 setHidden:YES];
    
    // set text view
    [cell.lblLabText setFont:FONT_AVANT_BOOK(cell.lblLabText.font.pointSize)];
    [cell.textview setScrollEnabled:YES];
    [cell.textview setUserInteractionEnabled:YES];
    
    NSDictionary *thisDict = [dictLabContentPlist valueForKey:self.titleName];
    if(thisDict != nil){
        NSDictionary *thisDictContent = [thisDict objectForKey:@"Text"];
        NSString *content = [thisDictContent valueForKey:@"Content"];
        NSAttributedString *ctAttri = [self attributedMessageFromMessage:content];
        UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(messageTapped:)];
        [cell.textview addGestureRecognizer:gesture];
        cell.textview.attributedText = ctAttri;
        cell.lblLabText.text = [thisDictContent valueForKey:@"Title"];
    }
    
    // expand textview according to text
    [cell.textview sizeToFit];
    [cell.textview layoutIfNeeded];
    cell.textview.backgroundColor = [UIColor clearColor];
    
    CGRect rect = cell.viewDescription.frame;
    rect.size.height = cell.textview.contentSize.height + 40;
    cell.viewDescription.frame = rect;
    [cell.viewMain.layer setCornerRadius:5];
    [cell.viewMain2.layer setCornerRadius:5];
    [cell.viewMain3.layer setCornerRadius:5];
    [cell.viewDescription.layer setCornerRadius:5];
    
    // set scrollview contentsize
    rect.size.height += 400;
    cell.cellScrollView.contentSize = rect.size;
    [cell.cellScrollView setScrollEnabled:YES];
    [cell.cellScrollView scrollsToTop];
    
    // set bubble view
    [cell.btnSeeMore addTarget:self action:@selector(expand:) forControlEvents:UIControlEventTouchUpInside];
    
    // get data for this testID
    for(int i = 0; i < self.arrayTestIDs.count; i++){
        if([self.arrayTestIDs[i] isEqualToString:currentID]){
            currentIndex = i;
            break;
        }
    }
    
    // load 1st time
    if(firstTimeOpenThisView){
        cell.lblTestName.text = self.arrayTestNames[currentIndex];
        self.titleName = self.arrayTestNames[currentIndex];
        currentID = self.arrayTestIDs[currentIndex];
    }else{
        currentIndex ++;
        // set title name
        cell.lblTestName.text = self.arrayTestNames[indexPath.row];
        self.titleName = self.arrayTestNames[indexPath.row];
        currentID = self.arrayTestIDs[indexPath.row];
    }
    
   
    
    NSMutableDictionary *postData = [[NSMutableDictionary alloc] init];
    [postData setValue:singleton.ACCESS_TOKEN forKey:@"token"];
    [postData setValue:currentID forKey:@"testId"];
    
    // this is new block that check db when click next
    NSArray *fetchObjects = [singleton loadDataFromTable:@"TestData"];
    // first load data from DB
    isDataExist = false;
    for(NSManagedObject *item in fetchObjects){
        if ([[item valueForKey:@"testID"] isEqualToString:[NSString stringWithFormat:@"%@",currentID]]) {
            
            dataResponseDict = [item valueForKey:@"data"];
            NSDictionary *commonDict = [dataResponseDict objectForKey:@"Common"];
            cell.lblLeftValue.text = [commonDict valueForKey:@"min"];
            cell.lblLeftLevel.text = [commonDict valueForKey:@"statusBegin"];
            cell.lblUnit.text = [commonDict valueForKey:@"avg"];
            cell.lblRightLevel.text = [commonDict valueForKey:@"statusEnd"];
            cell.lblRightValue.text = [commonDict valueForKey:@"max"];
            
            dataResponseArray = [dataResponseDict objectForKey:@"LabReport"];
            
            //kenvu
            NSDictionary *testDict = [dataResponseArray[0] objectForKey:@"Test"];
            NSString *resultStr = [testDict valueForKey:@"result"];
            if([resultStr isKindOfClass:[NSNull class]])
                numberOfRows = 1;
            else
                numberOfRows = 2;
            
            [self loadDataIntoCell:cell indexPath:indexPath];
            isDataExist=true;
            
        }
    }
    
    if(!isDataExist){ // even data exist, still needs to download from server for latest labs data
        clvMain.hidden = YES;
        [self showHud];
        [ws downloadDataWithMethod:@"viewlab" requestMethod:@"POST" data:postData completionBlock:^(NSDictionary *resultDict){
            
            NSDictionary *tmpDict = [resultDict valueForKey:WS_RESULT_DATA];
            dataResponseDict = [resultDict valueForKey:WS_RESULT_DATA];
            if(dataResponseDict != NULL && ![dataResponseDict isKindOfClass:[NSNull class]] && dataResponseDict.count > 0){
                // remove existing data for this category id
                for(NSManagedObject *item in fetchObjects){
                    if ([[item valueForKey:@"testID"] isEqualToString:[NSString stringWithFormat:@"%@",currentID]]) {
                        [singleton deleteObjectFromDB:item];
                    }
                }
                // save data to db
                NSMutableDictionary *dataToSave = [[NSMutableDictionary alloc]init];
                [dataToSave setObject:[NSString stringWithFormat:@"%@",currentID] forKey:@"testID"];
                [dataToSave setObject:tmpDict forKey:@"data"];
                [singleton saveNewData:dataToSave forTable:@"TestData"];
                
                // only reload data if no data in DB
                if(!isDataExist){
                    NSDictionary *commonDict = [dataResponseDict objectForKey:@"Common"];
                    cell.lblLeftValue.text = [commonDict valueForKey:@"min"];
                    cell.lblLeftLevel.text = [commonDict valueForKey:@"statusBegin"];
                    cell.lblUnit.text = [commonDict valueForKey:@"avg"];
                    cell.lblRightLevel.text = [commonDict valueForKey:@"statusEnd"];
                    cell.lblRightValue.text = [commonDict valueForKey:@"max"];
                    
                    dataResponseArray = [dataResponseDict objectForKey:@"LabReport"];
                    //kenvu
                    NSDictionary *testDict = [dataResponseArray[0] objectForKey:@"Test"];
                    NSString *resultStr = [testDict valueForKey:@"result"];
                    if([resultStr isKindOfClass:[NSNull class]])
                        numberOfRows = 1;
                    else
                        numberOfRows = 2;
                    
                    [self loadDataIntoCell:cell indexPath:indexPath];
                }
                
            }else{ // if data == nil, still show static info
                numberOfRows = 1;
                cell.lblLeftValue.text = cell.lblLeftLevel.text = cell.lblUnit.text = cell.lblRightLevel.text = cell.lblRightValue.text = @"";
                [self loadDataIntoCell:cell indexPath:indexPath];
            }
            [self hideHud];
            clvMain.hidden = NO;
        }];
    }
    
    
    firstTimeOpenThisView = false;
    return cell;
}

-(void)loadDataIntoCell:(SingleLabViewCollectionScrollCell *)cell indexPath:(NSIndexPath*)indexPath{
    if(indexPath.row == self.arrayTestIDs.count - 1){
        btnNext.hidden = YES;
    }else{
        btnNext.hidden = NO;
    }
    if(indexPath.row == 0){
        btnPrevious.hidden = YES;
    }else{
        btnPrevious.hidden = NO;
    }
    
    // set navigation title
    titleView.lblTestName.text = self.titleName;
    [titleView.lblTestName setFont:FONT_AVANT_BOOK(cell.lblTestName.font.pointSize)];

    .....
}

enter image description here

ios objective-c pagination uicollectionview
3个回答
2
投票

我找到了解决方案。 通过使用scrollViewDidEndDecelerating,我只需在获取UICollectionView的visibleCells之前添加0.1秒的延迟,并且它总是返回正确的可见单元格


2
投票

UICollectionView
继承自
UIScrollView
,这意味着您可以随时访问集合视图的
contentOffset
属性。 如果将
contentOffset
除以集合视图单元格的宽度,您将得出所显示单元格的索引,以便您可以找出当前可见的单元格。

您还可以利用

UIScrollViewDelegate
scrollViewDidScroll
方法 - 覆盖此方法,然后使用
contentOffset
计算出可见单元格移动了多远并触发导航栏文本的更改。因此,您可以等到当前单元格滚动超过其宽度的 50% 到下一个单元格后再进行更改 - 这样,如果用户触摸并让单元格“弹回”,导航栏标题将不会更改.


1
投票

好吧,浏览一下 Apple 的开发人员文档就会发现,确实没有任何委托方法可以告诉您单元格何时在屏幕上可见。我关于在

cellForItemAtIndexPath
检查这一点的第一个评论在技术上也不准确。该方法不应该知道单元格在屏幕上的“位置”。只是如何显示它。 所以我的建议是尝试这个:

loadDataIntoCell

中删除对

cellForItemAtIndexPath
的方法调用。

接下来,由于

UICollectionView

继承自

UIScrollView
,您可以使用这些委托方法来确定滚动时要执行的操作。这是一个粗略的例子:

方法

[collectionView visibleCells]

将为您提供数组中的所有可见单元格。您可以使用它来更改您的标题:


- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ for (UICollectionViewCell *cell in [collectionView visibleCells]) { NSIndexPath *indexPath = [collectionView indexPathForCell:cell]; NSLog(@"%@",indexPath); //Set the navigation title here } }

您只需要管理数组并确保其中的对象是正确的。但这应该会让你朝着正确的方向前进。 

© www.soinside.com 2019 - 2024. All rights reserved.