CompositionalLayoutDSL 0.2.0

CompositionalLayoutDSL 0.2.0

Alexandre PodlewskiCI Fabernovel维护。



CompositionalLayoutDSL

CompositionalLayoutDSL是一个Swift库。它使得创建集合视图的布局变得更容易。


要求

CompositionalLayoutDSL是用Swift 5编写的。兼容iOS 13.0+、tvOS 13.0+和macOS 10.15+。

文档

在线文档可以在这里找到。

可以通过以下命令在本地构建文档并查看:

swift package --disable-sandbox preview-documentation --target CompositionalLayoutDSL

入门指南

要查看此库的一些用法,您可以查看以下内容:

  • 一个示例项目是可用的,并且包含iOS和macOS应用程序。
  • 包含快照测试的测试目标。测试验证DSL与直接使用UIKit的行为相同,快照可以在这里找到。

这里有一些布局示例

布局代码的截图布局代码

以下是从测试目标中的示例:GroupDSLTests.swift (包含相同布局但不含DSL)

let layout = CompositionalLayout { section, environment in
    Section {
        HGroup {
            Item(width: .fractionalWidth(1 / 3))
                .contentInsets(trailing: 4)
            VGroup(count: 2) { Item() }
                .width(.fractionalWidth(1 / 3))
                .interItemSpacing(.fixed(8))
                .contentInsets(horizontal: 4)
            VGroup(count: 3) { Item() }
                .width(.fractionalWidth(1 / 3))
                .interItemSpacing(.fixed(8))
                .contentInsets(leading: 4)
        }
        .height(.absolute(100))
        .contentInsets(horizontal: 16)
    }
    .interGroupSpacing(8)
}
.interSectionSpacing(8)

// Apply to a collection view
collectionView.setCollectionViewLayout(layout, animated: false)
// or
collectionView.collectionViewLayout = LayoutBuilder { layout }

以下是从示例项目中的示例:GettingStartedCompositionalLayout.swift

collectionView.collectionViewLayout = LayoutBuilder {
    Section {
        VGroup(count: 1) { Item() }
            .height(.fractionalWidth(0.3))
            .width(.fractionalWidth(0.3))
            .interItemSpacing(.fixed(8))
    }
    .interGroupSpacing(8)
    .contentInsets(horizontal: 16, vertical: 8)
    .orthogonalScrollingBehavior(.continuous)
    .supplementariesFollowContentInsets(false)
    .boundarySupplementaryItems {
        BoundarySupplementaryItem(elementKind: UICollectionView.elementKindSectionHeader)
            .height(.absolute(30))
            .alignment(.top)
            .pinToVisibleBounds(true)
    }
}

安装

Cocoapods

要使用CocoaPods将CompositionalLayoutDSL集成到Xcode项目中,请在Podfile中指定

pod 'CompositionalLayoutDSL', '~> 0.2.0'

Swift Package Manager

CompositionalLayoutDSL可以作为Swift Package安装到Xcode 11或更高版本。要安装,请使用Xcode或将依赖项添加到您的Package.swift文件中。

.package(url: "https://github.com/faberNovel/CompositionalLayoutDSL", from: "0.2.0")

幕后

以下是一些关于此库如何工作的说明,它可以分为3部分:核心块的作用,修饰符是如何工作的,以及如何处理到UIKit世界的转换

核心结构体

此库包含创建组合布局所需的所有核心结构体,以下是一个详尽的列表

  • 配置
  • 部分
  • H组
  • V组
  • 自定义组
  • 装饰项
  • 补充项
  • 边界补充项

每个构建块都符合它们各自的公共协议,并处理其关联的UIKit对象的不可变属性。

例如,SupplementaryItem符合LayoutSupplementaryItem并处理NSCollectionLayoutSupplementaryItem的不可变属性,包括:layoutSizeelementKindcontainerAnchoritemAnchor

这些不可变属性只能在核心结构体上进行更改,并且不可以在全局的LayoutSupplementaryItem上使用。所有核心结构体都是如此。

修饰符

UIKit对象的可变属性是通过扩展Layout...协议来处理的。以下是一些示例:contentInset(_:)edgeSpacing(_:)zIndex(_:)interItemSpacing(_:)scrollDirection(_:)。通过使用修改器来改变这些可变值,这些修改器是内部结构体(例如,ValueModifiedLayoutItem)。因为这些方法是通过扩展Layout...协议提供的,因此它们对于库外的自定义元素也是可用的。

需要注意的是,一旦为可变属性应用了修改器,您就不再有Item,而是有了一个LayoutItem,因此之后无法再更改不可变值。

DSL到UIKit的转换

最后,当我们结合了核心结构和修改器,下一步是将Layout...转换为UIKit世界。这是通过构建器完成的,它们都以类似的方式工作。以下是如何工作ItemBuilder的示例

  • 它通过重复调用.layoutItem来尝试找到符合内部协议BuildableItem的布局项。
  • 然后它在候选者上调用makeItem()并返回它

⚠️警告⚠️

这意味着只有内部结构体才能转换为UIKit对象;如果您尝试定义一个自定义LayoutItem并像内部那样编写var layoutItem: LayoutItem { self },它将在ItemBuilder内部造成无限循环。

库的使用者必须根据此库提供的核心结构来构建自己的自定义布局。

致谢

CompositionalLayoutDSL由Fabernovel拥有和维护。您可以在Twitter上关注我们@Fabernovel

许可

CompositionalLayoutDSL在MIT许可下提供。有关更多信息,请参阅LICENSE文件。