对于想了解Objective-C----UICollectionView(梳理总结)的读者,本文将是一篇不可错过的文章,我们将详细介绍c++objectivec,并且为您提供关于ios–UIColle
对于想了解Objective-C --- - UICollectionView (梳理总结)的读者,本文将是一篇不可错过的文章,我们将详细介绍c++ objective c,并且为您提供关于ios – UICollectionView中带有自定义UICollectionViewLayout的部分标题、ios – UICollectionView布局不一致,UICollectionViewFlowLayout、ios – 在呈现UICollectionView时防止UICollectionViewCell动画外观、ios – 如何从UICollectionViewCell将pan手势传递给UICollectionVIew?的有价值信息。
本文目录一览:- Objective-C --- - UICollectionView (梳理总结)(c++ objective c)
- ios – UICollectionView中带有自定义UICollectionViewLayout的部分标题
- ios – UICollectionView布局不一致,UICollectionViewFlowLayout
- ios – 在呈现UICollectionView时防止UICollectionViewCell动画外观
- ios – 如何从UICollectionViewCell将pan手势传递给UICollectionVIew?
Objective-C --- - UICollectionView (梳理总结)(c++ objective c)
1准备
2.设置CollectionView
// FlowLayout布局
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
//设计方向
// layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
_collectionView = [[UICollectionView alloc]initWithFrame:[UIScreen mainScreen].bounds collectionViewLayout:layout];
[self.view addSubview:_collectionView];
// 设置代理
_collectionView.delegate = self;
_collectionView.dataSource = self;
// 注册cell
[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:kCellID];
// 背景颜色默认为黑色
_collectionView.backgroundColor = [UIColor whiteColor];
3.实现代理方法(常用的几个举例)
//cell个数
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [self.dataList[section] count];
}
//cell组数
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return [self.dataList count];
}
//cell大小
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
return CGSizeMake(kWidthOfCell, kWidthOfCell);
}
//cell之间的距离 系统会根据数值自动调节
-(UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(5, 5, 5, 5);
}
//cell的关键代理
-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCellID forIndexPath:indexPath];
cell.contentView.backgroundColor = [UIColor greenColor];
return cell;
}
//点击cell触发的代理
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"%@",self.dataList[indexPath.section][indexPath.item]);
}
ios – UICollectionView中带有自定义UICollectionViewLayout的部分标题
class ACollectionViewController: UICollectionViewController { enum Identifiers: String { case CellIdentifier = "Cell" case HeaderIdentifier = "Header" } override func viewDidLoad() { super.viewDidLoad() self.collectionView.registerClass(UICollectionReusableView.self,forSupplementaryViewOfKind: UICollectionElementKindSectionHeader,withReuseIdentifier: Identifiers.HeaderIdentifier.rawValue) } // MARK: UICollectionViewDataSource override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { return 1 } override func collectionView(collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int { return 10 } override func collectionView(collectionView: UICollectionView,cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier(Identifiers.CellIdentifier.rawValue,forIndexPath: indexPath) as Cell cell.backgroundColor = UIColor.redColor() return cell } override func collectionView(collectionView: UICollectionView,viewForSupplementaryElementOfKind kind: String,atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView { println("ip = \(indexPath.item)") var supplementaryView = collectionView.dequeueReusableCellWithReuseIdentifier(Identifiers.HeaderIdentifier.rawValue,forIndexPath: indexPath) as UICollectionReusableView supplementaryView.backgroundColor = UIColor.blueColor() return supplementaryView }
这里是我的自定义布局:
class ALayout: UICollectionViewLayout { override func prepareLayout() { super.prepareLayout() } override func collectionViewContentSize() -> CGSize { return self.collectionView!.bounds.size } let itemWidth = 40 override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! { var attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath) let x: Float = Float(10) * Float(indexPath.item) let y: Float = Float(indexPath.item * itemWidth) attributes.frame = CGRect(x: CGFloat(x),y: CGFloat(y),width: CGFloat(itemWidth),height: CGFloat(itemWidth)) return attributes } override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? { var attributes = [UICollectionViewLayoutAttributes]() let sectionsCount = self.collectionView!.dataSource!.numberOfSectionsInCollectionView!(self.collectionView!) for section in 0..<sectionsCount { /// add header attributes.append(self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader,atIndexPath: NSIndexPath(forItem: 0,inSection: section))) let itemsCount = self.collectionView!.numberOfItemsInSection(section) for item in 0..<itemsCount { let indexPath = NSIndexPath(forItem: item,inSection: section) attributes.append(self.layoutAttributesForItemAtIndexPath(indexPath)) } } return attributes } override func layoutAttributesForSupplementaryViewOfKind(elementKind: String,atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! { var attributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: elementKind,withIndexPath: indexPath) attributes.frame = CGRect(x: 0,y: 0,width: 320,height: 50) return attributes } }
问题是我不明白如何正确添加section头,这个header的indexPath应该是什么.在代码中有添加标题的注释.应用程序从错误开始崩溃
2014-10-21 13:06:22.793 UICollectionViewLayout-Demo[3805:95924] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException',reason: 'Could not dequeue a view of kind: UICollectionElementKindCell with identifier Header - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
我明白,这是因为单元格具有与我要添加的section header相同的indexPath,但是标题的indexPath应该是多少?或者也许我这样做完全错了?
先谢谢你.
解决方法
var supplementaryView = collectionView.dequeueReusableCellWithReuseIdentifier(Identifiers.HeaderIdentifier.rawValue,forIndexPath: indexPath) as UICollectionReusableView
尝试将标题和页脚排列(在collectionView:viewForSupplementaryElementOfKind中).改为
var supplementaryView = collectionView.dequeueReusableSupplementaryViewOfKind(kind,withReuseIdentifier:Identifiers.HeaderIdentifier.rawValue,forIndexPath: indexPath) as UICollectionReusableView
应该摆脱崩溃,所以你可以调查indexPath.但是在我的测试中,indexPath总是只是“0”.
ios – UICollectionView布局不一致,UICollectionViewFlowLayout
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeforItemAtIndexPath:(NSIndexPath *)indexPath { return [self preferredSizeforIndexPath:indexPath]; } - (CGSize)preferredSizeforIndexPath:(NSIndexPath *)indexPath { BOOL isLastObjectInSection = NO; Nsstring *sectionKey = [[arrCollectionData[indexPath.section] allKeys] objectAtIndex:0]; DLog(@"SectionKey: %@",sectionKey); NSArray *arrSection = [arrCollectionData[indexPath.section] objectForKey:sectionKey]; DLog(@"ArrSection: %@",arrSection); if ( arrSection[indexPath.row] == arrSection.lastObject ) { if( arrSection.count % 2 != 0 ) { isLastObjectInSection = YES; } } CGSize cellSize = CGSizeZero; if (UIDeviceOrientationIsLandscape([[UIDevice currentDevice] orientation])) { if (isLastObjectInSection == YES) { cellSize = CGSizeMake(IPAD_BADGE_WIDTH_LANDSCAPE_WIDE,IPAD_BADGE_HEIGHT_LANDSCAPE_WIDE); } else { cellSize = CGSizeMake(IPAD_BADGE_WIDTH_LANDSCAPE,IPAD_BADGE_HEIGHT_LANDSCAPE); } } else { if (isLastObjectInSection == YES) { cellSize = CGSizeMake(IPAD_BADGE_WIDTH_WIDE,IPAD_BADGE_HEIGHT_WIDE); } else { cellSize = CGSizeMake(IPAD_BADGE_WIDTH,IPAD_BADGE_HEIGHT); } } DLog(@"CellSize: %@",NsstringFromCGSize(cellSize)); return cellSize; }
以下是收集数据的示例.
Printing description of self->arrCollectionData: <__NSArrayI 0x94bbc40>( { "march 12,2013" = ( "<FMLeafTimelineContainer: 0x94b2430>","<FMLeafTimelineContainer: 0x94b3670>" ); },{ "February 25,2013" = ( "<FMLeafTimelineContainer: 0x94b4500>" ); },{ "February 14,2013" = ( "<FMLeafTimelineContainer: 0x94b48f0>","<FMLeafTimelineContainer: 0x94b3a60>" ); },{ "February 12,2013" = ( "<FMLeafTimelineContainer: 0x94b3ce0>","<FMLeafTimelineContainer: 0x94b2b00>" ); },{ "February 4,2013" = ( "<FMCommunityTimelineContainer: 0x94b4e90>","<FMCommunityTimelineContainer: 0x94b5050>","<FMCommunityTimelineContainer: 0x94b5f70>" ); },{ "January 30,2013" = ( "<FMCommunityTimelineContainer: 0x94b6ad0>","<FMCommunityTimelineContainer: 0x94b5a90>" ); },{ "January 24,2013" = ( "<FMCommunityTimelineContainer: 0x94b5d00>","<FMCommunityTimelineContainer: 0x94b6d90>" ); },{ "January 22,2013" = ( "<FMCommunityTimelineContainer: 0x94b6440>" ); },{ "January 21,2013" = ( "<FMCommunityTimelineContainer: 0x94b6260>","<FMCommunityTimelineContainer: 0x94b62e0>","<FMCommunityTimelineContainer: 0x94b70c0>","<FMCommunityTimelineContainer: 0x94b55a0>","<FMCommunityTimelineContainer: 0x94b82d0>","<FMCommunityTimelineContainer: 0x94b78b0>" ); },{ "December 20,2012" = ( "<FMCommunityTimelineContainer: 0x94b53f0>" ); },{ "December 6,2012" = ( "<FMCommunityTimelineContainer: 0x94b7200>" ); },{ "December 4,2012" = ( "<FMCommunityTimelineContainer: 0x94b72b0>" ); },{ "November 19,2012" = ( "<FMCommunityTimelineContainer: 0x94b7ae0>" ); } )
下面的图片都展示了集合视图的相同部分.
解决方法
ios – 在呈现UICollectionView时防止UICollectionViewCell动画外观
问题在于,以这种方式做事会使单元格以不希望的方式出现:它们从左上角扩展到指定的大小.我希望集合视图能够出现,并且所有单元格都已经按照它们的最终尺寸和外观进行了布局.
我知道像UIView的setAnimationEnabled:方法之类的东西,但我似乎无法找到我应该如何以及在哪里使用它(如果这是要走的路).
我想这个问题是由于集合视图单元格被添加到视图层次结构中,就在包含对[superview layoutIfNeeded]的调用的动画块之前.这可能导致UIKit认为它也应该对布局的这些更改进行动画处理.如果是这种情况,那么解决方案可能就是从动画中排除,视图层次结构的特定更改.
解决方法
要解决它,你需要两件事:
>确保您编辑的约束与集合视图的位置有关,而不是与大小相关.我的意思是,你不是通过将其高度从零改为最终值来呈现你的集合视图.>在编辑约束之前在视图上调用layoutIfNeeded,然后在进行更改后再在动画块中再次调用它.这样,您只需将您指定的更改设置为约束,而不是整个布局.
ios – 如何从UICollectionViewCell将pan手势传递给UICollectionVIew?
当我触摸时,UICollectionView仍然(水平地)滚动并从单元格之间的点开始向左/向右滑动,但只要将平移手势识别器添加到单元格中,当我开始轻扫时,似乎CollectionView拒绝滚动在一个细胞内.
现在,我将水平左/右拖动与垂直向上/向下拖动分开,因此拖出单元格(垂直滑动)和滚动CollectionView(水平滑动)之间不应存在任何冲突.在这种情况下,如何将滑动传递到集合/滚动视图,以便它知道像正常一样滚动?不得不开始在细胞之间的边界或间隔是非常烦人的.
一旦我从单元格中移除平移手势,无论我是开始在单元格上还是在单元格之间滑动,滚动都会正常工作.
编辑:下面作为当前代码发布的所需平移手势行为
// Handle pans by detecting swipes: -(void) handlePan:(UIPanGestureRecognizer*)recognizer { // Calculate touch location CGPoint touchXY = [recognizer locationInView:masterWindowView]; // Handle touch if (recognizer.state == UIGestureRecognizerStateBegan) { gestureWasHandled = NO; pointCount = 1; startPoint = touchXY; } if (recognizer.state == UIGestureRecognizerStateChanged) { ++pointCount; // Calculate whether a swipe has occurred float dX = deltaX(touchXY,startPoint); float dY = deltaY(touchXY,startPoint); BOOL finished = YES; if ((dX > kSwipeDragMin) && (ABS(dY) < kDragLimitMax)) { touchType = TouchSwipeLeft; NSLog(@"LEFT swipe detected"); [recognizer requireGestureRecognizerToFail:recognizer]; //[masterScrollView handlePan] } else if ((dX < -kSwipeDragMin) && (ABS(dY) < kDragLimitMax)) { touchType = TouchSwipeRight; NSLog(@"RIGHT swipe detected"); [recognizer requireGestureRecognizerToFail:recognizer]; } else if ((dY > kSwipeDragMin) && (ABS(dX) < kDragLimitMax)) { touchType = TouchSwipeUp; NSLog(@"UP swipe detected"); } else if ((dY < -kSwipeDragMin) && (ABS(dX) < kDragLimitMax)) { touchType = TouchSwipeDown; NSLog(@"DOWN swipe detected"); } else finished = NO; // If unhandled and downward,produce a new draggable view if (!gestureWasHandled && finished && (touchType == TouchSwipeDown)) { [self.delegate cellBeingDragged:self]; dragView.center = touchXY; dragView.hidden = NO; dragView.backgroundColor = [UIColor clearColor]; masterScrollView.scrollEnabled = NO; // prevent user from scrolling during gestureWasHandled = YES; } else if (gestureWasHandled) { // allow continued dragging after detection dragView.center = touchXY; } } if (recognizer.state == UIGestureRecognizerStateEnded) { // ensure that scroll view returns to scrollable if (gestureWasHandled) { [self.delegate cell:self dragEndedAt:touchXY]; } } } // Allow simultaneous recognition -(BOOL) gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer { return YES; }
该代码适用于每个单独的单元格.当连接到UICollectionView作为其手势识别器时它不起作用,并且它实际上停止所有滚动.
解决方法
locationInView
获取平移开始的UICollectionView中的点,然后是
indexPathForItemAtPoint
,它将返回索引路径对于你应该动画的单元格.
这样,您将只有一个手势识别器(好!)用于整个集合视图,同时还在视图控制器中保持控制(如您所愿) – 双赢!
使用此解决方案,在视图控制器中,您将实现gestureRecognizer:shouldReceiveTouch:,获取给定的gestureRecognizer,确保它是您的UIPanGestureRecognizer并使用其translationInView:方法来确定转换是在X轴还是Y轴上.使用该信息来决定是否要返回YES或NO.例如:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivetouch:(UITouch *)touch { if([gestureRecognizer isEqual:myTapGesture]) { CGPoint point = [gestureRecognizer translationInView:self.collectionView]; if(point.x != 0) { //adjust this condition if you want some leniency on the X axis //The translation was on the X axis,i.e. right/left,//so this gesture recognizer shouldn't do anything about it return NO; } } return YES; }
今天关于Objective-C --- - UICollectionView (梳理总结)和c++ objective c的分享就到这里,希望大家有所收获,若想了解更多关于ios – UICollectionView中带有自定义UICollectionViewLayout的部分标题、ios – UICollectionView布局不一致,UICollectionViewFlowLayout、ios – 在呈现UICollectionView时防止UICollectionViewCell动画外观、ios – 如何从UICollectionViewCell将pan手势传递给UICollectionVIew?等相关知识,可以在本站进行查询。
本文标签: