【问题标题】:Expanding UICollectionView and its cell when tapped点击时展开 UICollectionView 及其单元格
【发布时间】:2016-06-30 06:13:07
【问题描述】:

我正在尝试制作一个过渡动画,如链接here 中的演示。所以当我点击单元格时,它会展开并覆盖整个屏幕。

这是我的代码(我不得不承认我对 CollectionView 不熟悉)`

import UIKit

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {

@IBOutlet weak var mainDesLabel: UILabel!
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var secDesLabel: UILabel!
let searchBar = UISearchBar()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.collectionView.delegate   = self
    self.collectionView.dataSource = self
    self.collectionView.backgroundColor = UIColor.clearColor()
    ////////////////////////////////////////////////////////////////////////
    self.searchBar.frame = CGRect(x: 175, y: 0, width: 200, height: 50)
    self.searchBar.searchBarStyle = UISearchBarStyle.Minimal
    self.searchBar.backgroundColor = UIColor.whiteColor()
    self.view.addSubview(searchBar)
    ////////////////////////////////////////////////////////////////////////
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 10
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as UICollectionViewCell

    cell.layer.cornerRadius = 5

    return cell
}



func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    return 1
}

//Use for size
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    self.collectionView.frame = self.view.bounds
    let cell = collectionView.cellForItemAtIndexPath(indexPath)
    cell!.frame = CGRectMake(0, 0, self.view.bounds.width, self.view.bounds.height)
}


}

所以我认为使用 'didSelectItemAtIndexPath' 会有所帮助,但结果却像 this

想法?任何帮助将不胜感激!

【问题讨论】:

标签: ios swift uicollectionview uicollectionviewcell uicollectionviewlayout


【解决方案1】:

或者您可以做的是扩展项目并使用 UIAnimation 更改其框架。

当他点击单元格时,您可以使用自动布局来扩展单元格内的视图,我正在暗示(剪辑到边界)。

类似这样的:

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {

    let item = collectionView.cellForItemAtIndexPath(indexPath) as! cellCollectionViewExpress  // or whatever you collection view cell class name is.

    UIView.animateWithDuration(1.0, animations: {
        self.view.bringSubviewToFront(collectionView)
        collectionView.bringSubviewToFront(item)
        item.frame.origin = self.view.frame.origin   /// this view origin will be at the top of the scroll content, you'll have to figure this out
        item.frame.size.width = self.view.frame.width
        item.frame.size.height = self.view.frame.height
    })
}

我建议你使用 UICollectionView 控制器,这样一来使用起来很轻松。

【讨论】:

    【解决方案2】:

    一旦 UICollectionView 执行完视图布局,您不能只使用 didSelectItemAtIndexPath 或任何类似的方法来更新 UICollectionViewCell 的大小。

    要更新单元格高度, 您可以先在 didSelectItemAtIndexPath 中捕获哪个单元格被点击。 然后,您可以使用在 sizeForItemAtIndexpath 中传递的新单元格框架重新加载整个集合视图。 或者,您可以使用 reloadItemsAtIndexPaths 重新加载特定单元格,但您仍然需要通过 sizeForItemAtIndexpath 传递单元格的更新大小。

    更新 我现在看到问题详细信息已通过您想要的动画进行了更新。

    我通过以下方式执行了类似的动画:-

    1. 正在捕获didSelectItemAtIndexPath中被点击的单元格。
    2. 向 UIViewContrller 添加副本视图,但其框架与被点击的单元格完全一致。
    3. 然后,对已添加的视图进行动画处理。从而给人一种细胞是有生命的印象。

    任何必须提供的附加功能也可以写在这个视图中。因此单元格和动画视图的代码也是分开的。

    【讨论】:

    • 谢谢,它确实让我想到了如何实现这一目标。你有一个例子吗?我对某些步骤感到困惑。
    • 例如,我尝试放置一个恰好覆盖单元格的uiview,但是它被添加到单元格中......
    • UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath];然后,使用 attributes.frame 你可以获得单元格的框架。现在您需要使用此框架将副本视图放置在便笺视图控制器上。 (注意:viewcontroller,不是cell或collectionview)
    • 你的建议基本有效。但是,单元格只是从视图控制器的按钮中弹出,而不是从单元格本身中弹出...github.com/Imsiaocong/DribbleExp我将其发布在我的 github 上,您可以检查一下,看看有什么问题吗?
    • 谢谢老哥,在你们的帮助下,问题已经解决了,我实际上想出了另一种方法来实现目标。其他需要帮助的可以查看我的github
    【解决方案3】:

    当单元格被点击或按钮或任何可点击的东西在单元格内被点击时,您会收到来自 didSelectItemAtIndexPath 或通过委托,然后给单元格所需的大小,您必须使当前collectionview的布局无效。在此之后,将调用 item 的 size 并给出新的尺寸,

    这将更新collectioncell的大小而不重新加载它。 你也可以给动画。

    override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    
    if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
            flowLayout.invalidateLayout()
        }
    

    }

    【讨论】:

      【解决方案4】:
      extension UICollectionView {
                  func transactionAnimation(with duration: Float, animateChanges: @escaping () -> Void) {
              
                      UIView.animate(withDuration: TimeInterval(duration)) {
                          CATransaction.begin()
                          CATransaction.setAnimationDuration(CFTimeInterval(duration))
                          CATransaction.setAnimationTimingFunction(.init(name: .default))
                          animateChanges()
                          CATransaction.commit()
              
                      }
                  }
              }
          
      override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
      
           collectionView.transactionAnimation(with: 0.3) {
                      self.carInfoCollectionView?.performBatchUpdates({}, completion: { _ in })
              
         }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-11
        • 1970-01-01
        • 2015-06-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多