GVKun编程网logo

Objective-C --- - UICollectionView (梳理总结)(c++ objective c)

15

对于想了解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)

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的部分标题

ios – UICollectionView中带有自定义UICollectionViewLayout的部分标题

我正在使用具有自定义布局的UICollectionView.在两天内我不明白如何添加头到UICollectionView.我有非常简单的视图控制器(在具有自定义布局的故事板中创建):
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

ios – UICollectionView布局不一致,UICollectionViewFlowLayout

我无法以一致的方式在UICollectionView中显示单元格.单元的初始显示是正确的,但是每次用户滚动过去然后返回到一组单元格时,显示都是不正确的.行应该只包含2个或1个单元格. 2个单元格,每个显示宽度的一半,1个单元格占全宽.
- (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>"
    );
}
)

下面的图片都展示了集合视图的相同部分.

解决方法

问题是由父实例的子视图引起的,该子视图具有在实例化时分配的固定帧大小. Overrode setFrame:用于UICollectionView子类以分配子视图帧的值,每次单元格出列并重新排队时调用setFrame:进行相应调整.

ios – 在呈现UICollectionView时防止UICollectionViewCell动画外观

ios – 在呈现UICollectionView时防止UICollectionViewCell动画外观

当用户执行某些操作时,我需要将UICollectionView从底部拉到一定高度.由于新状态完全是可选的,因此集合视图就在以这种方式呈现之前创建.从底部到顶部的动画是使用对NSLayoutConstraint的常量属性的更改以及在某些动画块中调用[view layoutIfNeeded]来执行的.

问题在于,以这种方式做事会使单元格以不希望的方式出现:它们从左上角扩展到指定的大小.我希望集合视图能够出现,并且所有单元格都已经按照它们的最终尺寸和外观进行了布局.

我知道像UIView的setAnimationEnabled:方法之类的东西,但我似乎无法找到我应该如何以及在哪里使用它(如果这是要走的路).

我想这个问题是由于集合视图单元格被添加到视图层次结构中,就在包含对[superview layoutIfNeeded]的调用的动画块之前.这可能导致UIKit认为它也应该对布局的这些更改进行动画处理.如果是这种情况,那么解决方案可能就是从动画中排除,视图层次结构的特定更改.

解决方法

从左上角扩展通常是在原始视图从未布局时在动画块中调用layoutIfNeeded的症状.您基本上是为初始布局传递设置动画,其中所有子视图都是从CGRectZero开始的.

要解决它,你需要两件事:

>确保您编辑的约束与集合视图的位置有关,而不是与大小相关.我的意思是,你不是通过将其高度从零改为最终值来呈现你的集合视图.>在编辑约束之前在视图上调用layoutIfNeeded,然后在进行更改后再在动画块中再次调用它.这样,您只需将您指定的更改设置为约束,而不是整个布局.

ios – 如何从UICollectionViewCell将pan手势传递给UICollectionVIew?

ios – 如何从UICollectionViewCell将pan手势传递给UICollectionVIew?

我有一个UICollectionView实现自定义UICollectionViewCells的基于网格的布局.为了允许单元格响应拖动,我单独向每个单元格添加UIPanGestureRecognizer.

当我触摸时,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作为其手势识别器时它不起作用,并且它实际上停止所有滚动.

解决方法

而不是将UIPanGestureRecognizer附加到每个单元格(这会降低性能),而是将UIPanGestureRecognizer添加到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?等相关知识,可以在本站进行查询。

本文标签: