gpt4 book ai didi

ios - 自定义 CollectionViewLayout 不适用于 Swift 3

转载 作者:行者123 更新时间:2023-11-29 11:51:04 25 4
gpt4 key购买 nike

我已经实现了 UICollectionView 并且它可以使用下面的示例水平和垂直滚动粘性行和列:

Example

Github

应用程序可以在 Swift2 上找到,但升级后 Swift3 CustomCollectionViewLayout 给我错误

class CustomCollectionViewLayout: UICollectionViewLayout {

let numberOfColumns = 8
var itemAttributes : NSMutableArray!
var itemsSize : NSMutableArray!
var contentSize : CGSize!

override func prepare() {
if self.collectionView?.numberOfSections == 0 {
return
}

if (self.itemAttributes != nil && self.itemAttributes.count > 0) {
for section in 0..<self.collectionView!.numberOfSections {
let numberOfItems : Int = self.collectionView!.numberOfItems(inSection: section)
for index in 0..<numberOfItems {
if section != 0 && index != 0 {
continue
}

let attributes : UICollectionViewLayoutAttributes = self.layoutAttributesForItem(at: IndexPath(item: index, section: section))
if section == 0 {
var frame = attributes.frame
frame.origin.y = self.collectionView!.contentOffset.y
attributes.frame = frame
}

if index == 0 {
var frame = attributes.frame
frame.origin.x = self.collectionView!.contentOffset.x
attributes.frame = frame
}
}
}
return
}

if (self.itemsSize == nil || self.itemsSize.count != numberOfColumns) {
self.calculateItemsSize()
}

var column = 0
var xOffset : CGFloat = 0
var yOffset : CGFloat = 0
var contentWidth : CGFloat = 0
var contentHeight : CGFloat = 0

for section in 0..<self.collectionView!.numberOfSections {
let sectionAttributes = NSMutableArray()

for index in 0..<numberOfColumns {
let itemSize = (self.itemsSize[index] as AnyObject).cgSizeValue
let indexPath = IndexPath(item: index, section: section)
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
attributes.frame = CGRect(x: xOffset, y: yOffset, width: (itemSize?.width)!, height: (itemSize?.height)!).integral

if section == 0 && index == 0 {
attributes.zIndex = 1024;
} else if section == 0 || index == 0 {
attributes.zIndex = 1023
}

if section == 0 {
var frame = attributes.frame
frame.origin.y = self.collectionView!.contentOffset.y
attributes.frame = frame
}
if index == 0 {
var frame = attributes.frame
frame.origin.x = self.collectionView!.contentOffset.x
attributes.frame = frame
}

sectionAttributes.add(attributes)

xOffset += (itemSize?.width)!
column += 1

if column == numberOfColumns {
if xOffset > contentWidth {
contentWidth = xOffset
}

column = 0
xOffset = 0
yOffset += (itemSize?.height)!
}
}
if (self.itemAttributes == nil) {
self.itemAttributes = NSMutableArray(capacity: self.collectionView!.numberOfSections)
}
self.itemAttributes .add(sectionAttributes)
}

let attributes : UICollectionViewLayoutAttributes = (self.itemAttributes.lastObject as AnyObject).lastObject as! UICollectionViewLayoutAttributes
contentHeight = attributes.frame.origin.y + attributes.frame.size.height
self.contentSize = CGSize(width: contentWidth, height: contentHeight)
}

override var collectionViewContentSize : CGSize {
return self.contentSize
}

override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes! {
return self.itemAttributes[indexPath.section][indexPath.row] as! UICollectionViewLayoutAttributes
// Error in above return line and error is Type 'Any' has no subscript members
}

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var attributes = [UICollectionViewLayoutAttributes]()
if self.itemAttributes != nil {
for section in self.itemAttributes {

let filteredArray = (section as AnyObject).filtered(

using: NSPredicate(block: { (evaluatedObject, bindings) -> Bool in
return rect.intersects(evaluatedObject.frame)
// Error in above return line and error is Value of type 'Any?' has no member 'frame'
})
) as! [UICollectionViewLayoutAttributes]


attributes.append(contentsOf: filteredArray)

}
}

return attributes
}

override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}

func sizeForItemWithColumnIndex(_ columnIndex: Int) -> CGSize {
var text : String = ""
switch (columnIndex) {
case 0:
text = "Col 0"
case 1:
text = "Col 1"
case 2:
text = "Col 2"
case 3:
text = "Col 3"
case 4:
text = "Col 4"
case 5:
text = "Col 5"
case 6:
text = "Col 6"
default:
text = "Col 7"
}

let size : CGSize = (text as NSString).size(attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 17.0)])
let width : CGFloat = size.width + 25
return CGSize(width: width, height: 30)
}

func calculateItemsSize() {
self.itemsSize = NSMutableArray(capacity: numberOfColumns)
for index in 0..<numberOfColumns {
self.itemsSize.add(NSValue(cgSize: self.sizeForItemWithColumnIndex(index)))
}
}
}

ContentCollectionViewCell

class ContentCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var contentLabel: UILabel!

override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}

}

DateCollectionViewCell

class DateCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var dateLabel: UILabel!

override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}

}

Collection View Controller

class CollectionViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
let dateCellIdentifier = "DateCellIdentifier"
let contentCellIdentifier = "ContentCellIdentifier"
@IBOutlet weak var collectionView: UICollectionView!


override func viewDidLoad() {
super.viewDidLoad()

self.collectionView .register(UINib(nibName: "DateCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: dateCellIdentifier)
self.collectionView .register(UINib(nibName: "ContentCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: contentCellIdentifier)
}


// MARK - UICollectionViewDataSource

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


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


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
print(indexPath.description)
if indexPath.section == 0 {
if indexPath.row == 0 {
let dateCell : DateCollectionViewCell = collectionView .dequeueReusableCell(withReuseIdentifier: dateCellIdentifier, for: indexPath) as! DateCollectionViewCell
dateCell.backgroundColor = UIColor.white
dateCell.dateLabel.font = UIFont.systemFont(ofSize: 13)
dateCell.dateLabel.textColor = UIColor.black
dateCell.dateLabel.text = "Donor ID"

return dateCell
} else {
let contentCell : ContentCollectionViewCell = collectionView .dequeueReusableCell(withReuseIdentifier: contentCellIdentifier, for: indexPath) as! ContentCollectionViewCell
contentCell.contentLabel.font = UIFont.systemFont(ofSize: 13)
contentCell.contentLabel.textColor = UIColor.black
contentCell.contentLabel.text = "Section"

if indexPath.section % 2 != 0 {
contentCell.backgroundColor = UIColor(white: 242/255.0, alpha: 1.0)
} else {
contentCell.backgroundColor = UIColor.white
}

return contentCell
}
} else {
if indexPath.row == 0 {
let dateCell : DateCollectionViewCell = collectionView .dequeueReusableCell(withReuseIdentifier: dateCellIdentifier, for: indexPath) as! DateCollectionViewCell
dateCell.dateLabel.font = UIFont.systemFont(ofSize: 13)
dateCell.dateLabel.textColor = UIColor.black
dateCell.dateLabel.text = String(indexPath.section)
if indexPath.section % 2 != 0 {
dateCell.backgroundColor = UIColor(white: 242/255.0, alpha: 1.0)
} else {
dateCell.backgroundColor = UIColor.white
}

return dateCell
} else {
let contentCell : ContentCollectionViewCell = collectionView .dequeueReusableCell(withReuseIdentifier: contentCellIdentifier, for: indexPath) as! ContentCollectionViewCell
contentCell.contentLabel.font = UIFont.systemFont(ofSize: 13)
contentCell.contentLabel.textColor = UIColor.black
contentCell.contentLabel.text = "Section:\(indexPath.section.description) / Row: \(indexPath.row.description)"
if indexPath.section % 2 != 0 {
contentCell.backgroundColor = UIColor(white: 242/255.0, alpha: 1.0)
} else {
contentCell.backgroundColor = UIColor.white
}

return contentCell
}
}
}
}

谢谢

最佳答案

你好用这个替换你的 CustomCollectionViewLayout
CustomCollectionViewLayout.swift

class CustomCollectionViewLayout: UICollectionViewLayout {
let numberOfColumns = 8
var itemAttributes : NSMutableArray!
var itemsSize : NSMutableArray!
var contentSize : CGSize!

override func prepare() {
if self.collectionView?.numberOfSections == 0 {
return
}

if (self.itemAttributes != nil && self.itemAttributes.count > 0) {
for section in 0..<self.collectionView!.numberOfSections {
let numberOfItems : Int = self.collectionView!.numberOfItems(inSection: section)
for index in 0..<numberOfItems {
if section != 0 && index != 0 {
continue
}

let attributes : UICollectionViewLayoutAttributes = self.layoutAttributesForItem(at: IndexPath(item: index, section: section))
if section == 0 {
var frame = attributes.frame
frame.origin.y = self.collectionView!.contentOffset.y
attributes.frame = frame
}

if index == 0 {
var frame = attributes.frame
frame.origin.x = self.collectionView!.contentOffset.x
attributes.frame = frame
}
}
}
return
}

if (self.itemsSize == nil || self.itemsSize.count != numberOfColumns) {
self.calculateItemsSize()
}

var column = 0
var xOffset : CGFloat = 0
var yOffset : CGFloat = 0
var contentWidth : CGFloat = 0
var contentHeight : CGFloat = 0

for section in 0..<self.collectionView!.numberOfSections {
let sectionAttributes = NSMutableArray()

for index in 0..<numberOfColumns {
let itemSize = (self.itemsSize[index] as AnyObject).cgSizeValue
let indexPath = IndexPath(item: index, section: section)
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
attributes.frame = CGRect(x: xOffset, y: yOffset, width: (itemSize?.width)!, height: (itemSize?.height)!).integral

if section == 0 && index == 0 {
attributes.zIndex = 1024;
} else if section == 0 || index == 0 {
attributes.zIndex = 1023
}

if section == 0 {
var frame = attributes.frame
frame.origin.y = self.collectionView!.contentOffset.y
attributes.frame = frame
}
if index == 0 {
var frame = attributes.frame
frame.origin.x = self.collectionView!.contentOffset.x
attributes.frame = frame
}

sectionAttributes.add(attributes)

xOffset += (itemSize?.width)!
column += 1

if column == numberOfColumns {
if xOffset > contentWidth {
contentWidth = xOffset
}

column = 0
xOffset = 0
yOffset += (itemSize?.height)!
}
}
if (self.itemAttributes == nil) {
self.itemAttributes = NSMutableArray(capacity: self.collectionView!.numberOfSections)
}
self.itemAttributes .add(sectionAttributes)
}

let attributes : UICollectionViewLayoutAttributes = (self.itemAttributes.lastObject as AnyObject).lastObject as! UICollectionViewLayoutAttributes
contentHeight = attributes.frame.origin.y + attributes.frame.size.height
self.contentSize = CGSize(width: contentWidth, height: contentHeight)
}

override var collectionViewContentSize : CGSize {
return self.contentSize
}

override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes! {
//return self.itemAttributes[indexPath.section][indexPath.row] as! UICollectionViewLayoutAttributes
let arr = self.itemAttributes[indexPath.section] as! NSMutableArray
return arr[indexPath.row] as! UICollectionViewLayoutAttributes
}

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var attributes = [UICollectionViewLayoutAttributes]()
if self.itemAttributes != nil {
for section in self.itemAttributes {

let filteredArray = (section as! NSMutableArray).filtered(

using: NSPredicate(block: { (evaluatedObject , bindings) -> Bool in
let a = evaluatedObject as! UICollectionViewLayoutAttributes
return rect.intersects(a.frame)
})
) as! [UICollectionViewLayoutAttributes]


attributes.append(contentsOf: filteredArray)

}
}

return attributes
}

override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}

func sizeForItemWithColumnIndex(_ columnIndex: Int) -> CGSize {
var text : String = ""
switch (columnIndex) {
case 0:
text = "Col 0"
case 1:
text = "Col 1"
case 2:
text = "Col 2"
case 3:
text = "Col 3"
case 4:
text = "Col 4"
case 5:
text = "Col 5"
case 6:
text = "Col 6"
default:
text = "Col 7"
}

let size : CGSize = (text as NSString).size(attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 17.0)])
let width : CGFloat = size.width + 25
return CGSize(width: width, height: 30)
}

func calculateItemsSize() {
self.itemsSize = NSMutableArray(capacity: numberOfColumns)
for index in 0..<numberOfColumns {
self.itemsSize.add(NSValue(cgSize: self.sizeForItemWithColumnIndex(index)))
}
}
}

关于ios - 自定义 CollectionViewLayout 不适用于 Swift 3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41134748/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com