UICollectionView with Paging,每个单元格覆盖整个屏幕,在拖动时发出但不会进入下一个或上一个单元格

时间:2014-08-02 07:06:46

标签: ios objective-c uicollectionview paging

我在启用分页的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

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

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

您还可以利用UIScrollViewDelegate的{​​{1}}方法 - 覆盖此方法,然后使用scrollViewDidScroll确定可见单元格移动了多远并触发导航栏的更改文本。因此,您可以等到当前单元格在更改之前将其宽度的50%滚动到下一个单元格时 - 这样,如果用户触摸并让单元格“快速”返回,导航栏标题将不会被更改

答案 2 :(得分:1)

好的,看看Apple的开发人员文档,可以看出,当屏幕上的单元格可见时,确实没有任何委托方法可以告诉您。我在cellForItemAtIndexPath中检查此问题的第一条评论在技术上也不准确。该方法不应该知道哪里一个单元格在屏幕上。只需如何来显示它。

所以我的建议是试试这个:

loadDataIntoCell移除对cellForItemAtIndexPath的方法调用。

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

方法[collectionView visibleCells]将为您提供数组中的所有visibleCell。您可以使用它来更改标题:

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

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