如何从UICollectionViewFlowLayout中删除换行符

时间:2016-11-18 23:36:58

标签: ios swift uicollectionview tvos

我正在尝试使用UICollectionViewFlowLayout删除我的部分中的项目的换行符。

目前我有

|header         |
|0-0 0-1 0-2 0-3|
|0-4 0-5        |

|header         |
|1-0 1-1 1-2 0-3|
|1-4 1-5        |

我需要:

|header         |
|0-0 0-1 0-2 0-3| 0-4 0-5    

|header         |
|1-0 1-1 1-2 1-3| 1-4 1-5  

因此用户可以水平滚动。在iOS上我通过创建两个嵌套的collectionView来解决这个问题,但是在tvOS上我无法复制解决方案,因为我无法专注于内部单元格。

在多次尝试之后,我覆盖了嵌套的UICollectionView所在的tableCell上的preferredFocusedView变量:

override var preferredFocusedView: UIView? {
  return moviesCollection
}

此行为允许我在集合的内部元素之间水平滑动,但我不能垂直滑动以在表格单元格之间切换。

我有点迷失,任何形式的帮助都会非常感激。

谢谢。

4 个答案:

答案 0 :(得分:1)

使用自定义UICollectionViewLayout

可以很快解决这个问题

子类UICollectionViewLayout&覆盖以下属性和方法

  1. var collectionViewContentSize:CGSize
  2. func prepare()
  3. func layoutAttributesForElements(在rect:CGRect中) - > [UICollectionViewLayoutAttributes]
  4. 确保为每个单元格返回正确的框架

    这是我的工作解决方案,它还方便地提供了UICollectionViewFlowLayout(itemSize,minimumInteritemSpacing,minimumLineSpacing)的一些属性。

    您可能不需要更改任何内容,只需将其添加到项目中即可。

    https://gist.github.com/kflip/52ec15ddb07aa830d583856909fbefd4

    随意添加scrollDirection支持...它已经在两个方向上滚动,但如果一个部分应该显示为列而不是一行,您可能想要更改...

    如果您需要基于IndexPaths的更多自定义(例如CellSize),您还可以添加类似FlowLayout的协议功能

答案 1 :(得分:1)

更新

这是一个显示最终结果的GIF: enter image description here

原始

我刚刚创建了一个测试ViewController,这似乎工作正常。 基本上,我所拥有的是具有垂直流布局的UICollectionViewcollectionView的每个单元格都将其UICollectionView设置为水平流布局。

"出于行为的唯一不方便"是水平流动铺设集合视图不记得"回到它时所选择的项目,但可以通过一点点的游戏来解决。

希望它有所帮助。这是我的代码:

class ViewController: UIViewController, UICollectionViewDataSource {

    @IBOutlet weak var collectionView: UICollectionView!

    override var preferredFocusEnvironments: [UIFocusEnvironment] {
        return [collectionView]
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

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

    // MARK: - UICollectionViewDataSource

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 3
    }

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        return collectionView.dequeueReusableCell(withReuseIdentifier: "ParentTestCell", for: indexPath)
    }

    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        return collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "TestHeader", for: indexPath)
    }

}

// Parent cell - included in the vertical collection view & includes the horizontal collection view

class ParentTestCell: UICollectionViewCell, UICollectionViewDataSource {

    @IBOutlet weak var collectionView: UICollectionView!

    override var preferredFocusEnvironments: [UIFocusEnvironment] {
        return [collectionView]
    }

    // MARK: - UICollectionViewDataSource

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

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        return collectionView.dequeueReusableCell(withReuseIdentifier: "TestCell", for: indexPath)
    }

}

// Child cell - included in the horizontal collection view

class TestCell: UICollectionViewCell {

    override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
        coordinator.addCoordinatedAnimations({ 
            if self.isFocused {
                self.backgroundColor = .red
            }
            else {
                self.backgroundColor = .blue
            }
        }, completion: nil)
    }

}

这是故事板结构:

enter image description here

答案 2 :(得分:0)

只是一个建议,如果它可以帮助你。

  1. 添加tableView
  2. 创建自定义TableVeiwCell,其中包含具有水平滚动的单元格内的集合视图。
  3. 对于您拥有的每个部分,将成为tableview的数字行
  4. 对于行中的项目,将成为相应集合视图的项目数。

答案 3 :(得分:-1)

var obj = [ {longitude: 1, latitude: 2}, {longitude: 3, latitude: 4} ] var permute = function(object) { var i = Object.keys(object[0]).length; // ["latitude", "longitude"], length = 2 var switchedObj = new Array(i); while (i--) switchedObj[i] = object[i]; // go through obj in reverse order // and assign values to new obj return switchedObj; }; permute(obj); // => [ // {latitude: 2, longitude: 1}, // {latitude: 4, longitude: 3} // ] 在使用UICollectionView时以非常具体的方式布置其单元格,我不确定是否可以使用集合视图进行此类行为,并自行制作{{1} }}。有关如何使用自定义布局制作UIColloctionView,请参阅this guide

我建议尝试使用嵌套的UICollectionViewFlowLayout来解决问题。创建一个垂直滚动的tableview,其中tableview中的每个单元格都有自己的水平滚动tableview。水平表视图中的单元格将是用户可以选择的实际单元格。有关如何执行此操作,请参阅this guide

这也适用于tvOS,因为焦点引擎应该查看单元格子视图,并找到可聚焦的子视图。我希望它有所帮助:)