swift 中集合视图的自定义布局?
Custom layout for collection view in swift?
我在 UICollectionView 的一个部分中有 7 个单元格。
我已经搜索了几个小时,但我所能找到的只是有关 CollectionFlow 和包含数百个单元格的自定义布局的信息。我想要的只是使用如下图所示的布局在集合视图中显示具有不同标识符的 7 个单元格:
如何实现这种布局?
我认为有两种解决方案:
我想你有你需要的一切! ;)
可以使用 FlowLayout,但您必须自定义 FlowLayout 属性。
对于不同的单元格大小,使用此方法 -
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
按照这个 URL 一步步来....
SWIFT :
http://www.raywenderlich.com/78550/beginning-ios-collection-views-swift-part-1
OBJECTIVE C :
https://github.com/eoghain/RBCollectionViewBalancedColumnLayout
这就是我的解决方案。
class HistoryLayout: UICollectionViewLayout {
var delegate : HistoryLayoutDelegate?
var yOffSet : CGFloat = 0
var xOffSetLand : CGFloat = 0
var xOffSetPort : CGFloat = 0
var portraitElements : [Int] = []
var portraintItemPositionIndex = PortraintItemPositionIndex.Left
private var cache = [CGRect]()
var contentHeight: CGFloat = 0.0
var contentWidth: CGFloat {
let insets = collectionView!.contentInset
return CGRectGetWidth(collectionView!.bounds) - (insets.left + insets.right)
}
override func collectionViewContentSize() -> CGSize {
return CGSize(width: contentWidth, height: contentHeight)
}
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var layoutAttributes = [UICollectionViewLayoutAttributes]()
for item in 0 ..< collectionView!.numberOfItemsInSection(0) {
let indexPath = NSIndexPath(forItem: item, inSection: 0)
let attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
attributes.frame = cache[item]
if CGRectIntersectsRect(attributes.frame, rect) {
layoutAttributes.append(attributes)
}
}
//send index list of elements with portraint position
if let _ = delegate {
delegate?.elementsWithVerticalPosition(self.portraitElements)
}
return layoutAttributes
}
override func prepareLayout() {
if cache.isEmpty {
var gropCount = Int(collectionView!.numberOfItemsInSection(0) / 3)
if collectionView!.numberOfItemsInSection(0) % 3 != 0 {
gropCount++
}
for index in 1...gropCount {
self.improGroupByItem(index)
contentHeight = ((contentWidth / 3) * 2) * CGFloat(index)
}
}
}
private func improGroupByItem(index : Int){
if index % 2 == 0 {
xOffSetLand = contentWidth / 3
xOffSetPort = 0
self.portraintItemPositionIndex = .Right
}else{
xOffSetLand = 0
xOffSetPort = (contentWidth / 3) * 2
self.portraintItemPositionIndex = .Left
}
if index > 1 {
self.yOffSet += (contentWidth / 3) * 2
}
addItemToStack(index)
}
func addItemToStack(gIndex : Int){
let columnWidth = self.contentWidth / 3
var frame : CGRect
var dublicate = 0
for index in 1...3 {
if index % portraintItemPositionIndex.rawValue == 0 {
let width = columnWidth * 1
let height = columnWidth * 2
frame = CGRect(x: self.xOffSetPort, y: yOffSet, width: width, height: height)
let indexOfPortElement = ((gIndex - 1)*3) + index - 1
portraitElements.append(indexOfPortElement)
}else{
let width = columnWidth * 2
let height = columnWidth * 1
frame = CGRect(x: self.xOffSetLand, y: yOffSet + (height * CGFloat(dublicate)), width: width, height: height)
dublicate++
}
cache.append(frame)
}
}
}
我在 UICollectionView 的一个部分中有 7 个单元格。 我已经搜索了几个小时,但我所能找到的只是有关 CollectionFlow 和包含数百个单元格的自定义布局的信息。我想要的只是使用如下图所示的布局在集合视图中显示具有不同标识符的 7 个单元格:
如何实现这种布局?
我认为有两种解决方案:
我想你有你需要的一切! ;)
可以使用 FlowLayout,但您必须自定义 FlowLayout 属性。
对于不同的单元格大小,使用此方法 -
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
按照这个 URL 一步步来....
SWIFT :
http://www.raywenderlich.com/78550/beginning-ios-collection-views-swift-part-1
OBJECTIVE C :
https://github.com/eoghain/RBCollectionViewBalancedColumnLayout
这就是我的解决方案。
class HistoryLayout: UICollectionViewLayout {
var delegate : HistoryLayoutDelegate?
var yOffSet : CGFloat = 0
var xOffSetLand : CGFloat = 0
var xOffSetPort : CGFloat = 0
var portraitElements : [Int] = []
var portraintItemPositionIndex = PortraintItemPositionIndex.Left
private var cache = [CGRect]()
var contentHeight: CGFloat = 0.0
var contentWidth: CGFloat {
let insets = collectionView!.contentInset
return CGRectGetWidth(collectionView!.bounds) - (insets.left + insets.right)
}
override func collectionViewContentSize() -> CGSize {
return CGSize(width: contentWidth, height: contentHeight)
}
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var layoutAttributes = [UICollectionViewLayoutAttributes]()
for item in 0 ..< collectionView!.numberOfItemsInSection(0) {
let indexPath = NSIndexPath(forItem: item, inSection: 0)
let attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
attributes.frame = cache[item]
if CGRectIntersectsRect(attributes.frame, rect) {
layoutAttributes.append(attributes)
}
}
//send index list of elements with portraint position
if let _ = delegate {
delegate?.elementsWithVerticalPosition(self.portraitElements)
}
return layoutAttributes
}
override func prepareLayout() {
if cache.isEmpty {
var gropCount = Int(collectionView!.numberOfItemsInSection(0) / 3)
if collectionView!.numberOfItemsInSection(0) % 3 != 0 {
gropCount++
}
for index in 1...gropCount {
self.improGroupByItem(index)
contentHeight = ((contentWidth / 3) * 2) * CGFloat(index)
}
}
}
private func improGroupByItem(index : Int){
if index % 2 == 0 {
xOffSetLand = contentWidth / 3
xOffSetPort = 0
self.portraintItemPositionIndex = .Right
}else{
xOffSetLand = 0
xOffSetPort = (contentWidth / 3) * 2
self.portraintItemPositionIndex = .Left
}
if index > 1 {
self.yOffSet += (contentWidth / 3) * 2
}
addItemToStack(index)
}
func addItemToStack(gIndex : Int){
let columnWidth = self.contentWidth / 3
var frame : CGRect
var dublicate = 0
for index in 1...3 {
if index % portraintItemPositionIndex.rawValue == 0 {
let width = columnWidth * 1
let height = columnWidth * 2
frame = CGRect(x: self.xOffSetPort, y: yOffSet, width: width, height: height)
let indexOfPortElement = ((gIndex - 1)*3) + index - 1
portraitElements.append(indexOfPortElement)
}else{
let width = columnWidth * 2
let height = columnWidth * 1
frame = CGRect(x: self.xOffSetLand, y: yOffSet + (height * CGFloat(dublicate)), width: width, height: height)
dublicate++
}
cache.append(frame)
}
}
}