我在启用分页的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)];
.....
}
答案 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
}
}
您需要管理数组并确保其中的对象是正确的。但这应该让你朝着正确的方向前进。