我对自定义布局类有一个小问题,我需要通过代码而不是故事板将其连接到我的收藏夹视图,因为我是通过代码创建整个项目的。有任何帮助吗?
我的主班
import UIKit
import Firebase
class UserProfileController: UICollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = .white
//fetchUser()
collectionView?.dataSource = self
collectionView?.delegate = self
collectionView?.register(TestCell.self, forCellWithReuseIdentifier: mainCellId)
}
fileprivate let mainCellId = "mainCellId"
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: mainCellId, for: indexPath) as! TestCell
return cell
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 15
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
}
需要通过代码而不是故事板将其连接到集合视图的自定义布局类
import UIKit
struct UltraVisualLayoutConstants {
struct Cell {
static let standardHeight: CGFloat = 100
static let featuredHeight: CGFloat = 280
// static let standardWidth: CGFloat = 100
// static let featuredWidth: CGFloat = 280
}
}
class UltraVisualLayout: UICollectionViewLayout {
// amount which users need to scroll before featured cell changes\
let dragOffset: CGFloat = 180.0
var cache = [UICollectionViewLayoutAttributes]()
//return item index of current featured cell
var featuredItemIndex: Int {
get {
//use max to ensure that featureditemindex never be < 0
return max(0 , Int(collectionView!.contentOffset.y / dragOffset))
}
}
// returns value between 0 and 1 to represent how close the next cell becomes the featured cell
var nextItemPercentegeOffset: CGFloat {
get {
return (collectionView!.contentOffset.y / dragOffset) - CGFloat(featuredItemIndex)
}
}
// return the width of collection view
var width: CGFloat {
get {
guard let width = collectionView?.bounds.width else {return 0}
return width
}
}
// return the height of collection view
var height: CGFloat {
get {
guard let height = collectionView?.bounds.height else {return 0}
return height
}
}
//returns the number of items in the collection view
var numberOfItems: Int {
get {
return collectionView!.numberOfItems(inSection: 0)
}
}
// MARK: UICollectionViewLayout
// return the size of all content in collection view
override var collectionViewContentSize: CGSize {
let contentHeight = (CGFloat(numberOfItems) * dragOffset) + (height - dragOffset)
return CGSize(width: width, height: contentHeight)
}
override func prepare() {
cache.removeAll(keepingCapacity: false)
let standardHeight = UltraVisualLayoutConstants.Cell.standardHeight
let featuredHeight = UltraVisualLayoutConstants.Cell.featuredHeight
var frame = CGRect(x: 0, y: 0, width: 0, height: 0)
var y: CGFloat = 0
for item in 0..<numberOfItems {
let indexPath = NSIndexPath(item: item, section: 0)
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath as IndexPath)
attributes.zIndex = item
var height = standardHeight
if indexPath.item == featuredItemIndex {
let yOffset = standardHeight * nextItemPercentegeOffset
y = collectionView!.contentOffset.y - yOffset
height = featuredHeight
} else if indexPath.item == (featuredItemIndex + 1) && indexPath.item != numberOfItems {
let maxY = y + standardHeight
height = standardHeight + max((featuredHeight - standardHeight) * nextItemPercentegeOffset, 0)
y = maxY - height
}
frame = CGRect(x: 0, y: y, width: width, height: height)
attributes.frame = frame
cache.append(attributes)
y = frame.maxY
}
}
// return all attributes in cache whose frame intersects with the rect passed to the method
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var layoutAttributes = [UICollectionViewLayoutAttributes]()
for attributes in cache {
if attributes.frame.intersects(rect) {
layoutAttributes.append(attributes)
}
}
return layoutAttributes
}
// return true so that layout is continuously invalidated as the user scrolls
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}
答案 0 :(得分:1)
如果您没有初始化器,则不能以编程方式设置布局。来自docs:
布局
用于组织项目的布局对象。集合 视图存储对指定对象的强引用。 一定不能 无。
由于您似乎正在使用故事板,因此必须在此处进行设置。
在代码中创建布局类后,单击情节提要上的集合视图时,它将显示出来。 默认布局将设置为流,当您将其更改为自定义时,将显示一个新的班级字段。当您单击它时,它将列出您的布局类。您可以选择它并从那里进行设置。
但是,如果您以编程方式初始化情节提要,则只需要将其作为参数传递给初始化程序即可。
var collectionView = UICollectionView(frame: yourFrame, collectionViewLayout: customCollectionViewLayout) // pass your custom collection view instance