调整 collection 视图的单元格使其底部对齐
Align Cell of collection view to its bottom on resizing it
我有 collection 包含单元格的视图。我正在 sizeForItemAt 函数中调整该单元格的大小。但问题是,如果高度很小,单元格会居中对齐。我想将所有调整大小的单元格对齐到 collection 视图的底部。
我正在使用 Swift。我尝试通过以编程方式添加视图来对视图使用约束。没结果。我正在尝试在 Canva App 中制作类似于可滚动设计的视图。
请帮忙。
我的 collection 视图目前看起来像这样 Simulator Image and i want to align the cell to the bottom always like canva view that i am trying to make
Code:
CollectionViewController -
import UIKit
class CollectionViewController: UIViewController,UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
@IBOutlet weak var collectionView: UICollectionView!
let columns: CGFloat = 6.0
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(OneCollectionViewCell.self, forCellWithReuseIdentifier: "cellOne")
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return Int(columns)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellOne", for: indexPath) as! OneCollectionViewCell
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width : CGFloat
let height : CGFloat
if indexPath.item == 0 {
width = 100
height = 50
} else if indexPath.item == 1{
width = 80
height = 100
} else if indexPath.item == 2 {
width = 50
height = 70
}else {
width = 80
height = 100
}
return CGSize(width: width, height: height)
}
}
CollectionViewCell-
import UIKit
class OneCollectionViewCell: UICollectionViewCell {
public var view1: UIView = {
let viewView = UIView()
viewView.translatesAutoresizingMaskIntoConstraints = false
viewView.contentMode = .scaleToFill
viewView.clipsToBounds = true
return viewView
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(view1)
view1.backgroundColor = .black
view1.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0).isActive = true
view1.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0).isActive = true
view1.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
view1.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 5).isActive = true
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
//fatalError("init(coder:) has not been implemented")
}
}
class BottomAlignedCollectionViewFlowLayout: UICollectionViewFlowLayout {
override init() {
super.init()
self.scrollDirection = .horizontal
// self.minimumInteritemSpacing = 10.0
// self.minimumLineSpacing = 10.0
self.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 10)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributes = super.layoutAttributesForElements(in: rect)?
.map { [=10=].copy() } as? [UICollectionViewLayoutAttributes]
attributes?
.reduce([CGFloat: (CGFloat, [UICollectionViewLayoutAttributes])]()) {
guard .representedElementCategory == .cell else { return [=10=] }
return [=10=].merging([ceil(.center.y): (.frame.origin.y, [])]) {
([=10=].0 < .0 ? [=10=].0 : .0, [=10=].1 + .1)
}
}
.values.forEach { minY, line in
line.forEach {
[=10=].frame = [=10=].frame.offsetBy(
dx: 0,
dy: minY + [=10=].frame.origin.y
)
}
}
return attributes
}
}
在viewDidLoad中
collectionView.collectionViewLayout = BottomAlignedCollectionViewFlowLayout()
Code:
CollectionViewController -
class CollectionViewController: UIViewController, UICollectionViewDelegate,
UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
@IBOutlet weak var collectionView: UICollectionView!
let columns: CGFloat = 6.0
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(OneCollectionViewCell.self, forCellWithReuseIdentifier: "cellOne")
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return Int(columns)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellOne", for: indexPath) as! OneCollectionViewCell
let height : CGFloat
if indexPath.item == 0 {
height = 50
} else if indexPath.item == 1{
height = 100
} else if indexPath.item == 2 {
height = 70
}else {
height = 100
}
cell.configCell(height: height)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width : CGFloat
let height : CGFloat = 100
if indexPath.item == 0 {
width = 100
}
else if indexPath.item == 1{
width = 100
} else if indexPath.item == 2 {
width = 50
}else {
width = 80
}
return CGSize(width: width, height: height)
}
}
CollectionViewCell-
import UIKit
class OneCollectionViewCell: UICollectionViewCell {
public var view1: UIView = {
let viewView = UIView()
viewView.translatesAutoresizingMaskIntoConstraints = false
viewView.contentMode = .scaleToFill
viewView.clipsToBounds = true
return viewView
}()
var cstHeightAnchor: NSLayoutConstraint!
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(view1)
view1.backgroundColor = .black
cstHeightAnchor = view1.heightAnchor.constraint(equalToConstant: 100)
cstHeightAnchor.isActive = true
view1.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0).isActive = true
view1.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
view1.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 5).isActive = true
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
//fatalError("init(coder:) has not been implemented")
}
func configCell(height: CGFloat) {
cstHeightAnchor.constant = height
}
}
我有 collection 包含单元格的视图。我正在 sizeForItemAt 函数中调整该单元格的大小。但问题是,如果高度很小,单元格会居中对齐。我想将所有调整大小的单元格对齐到 collection 视图的底部。 我正在使用 Swift。我尝试通过以编程方式添加视图来对视图使用约束。没结果。我正在尝试在 Canva App 中制作类似于可滚动设计的视图。 请帮忙。 我的 collection 视图目前看起来像这样 Simulator Image and i want to align the cell to the bottom always like canva view that i am trying to make
Code:
CollectionViewController -
import UIKit
class CollectionViewController: UIViewController,UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
@IBOutlet weak var collectionView: UICollectionView!
let columns: CGFloat = 6.0
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(OneCollectionViewCell.self, forCellWithReuseIdentifier: "cellOne")
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return Int(columns)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellOne", for: indexPath) as! OneCollectionViewCell
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width : CGFloat
let height : CGFloat
if indexPath.item == 0 {
width = 100
height = 50
} else if indexPath.item == 1{
width = 80
height = 100
} else if indexPath.item == 2 {
width = 50
height = 70
}else {
width = 80
height = 100
}
return CGSize(width: width, height: height)
}
}
CollectionViewCell-
import UIKit
class OneCollectionViewCell: UICollectionViewCell {
public var view1: UIView = {
let viewView = UIView()
viewView.translatesAutoresizingMaskIntoConstraints = false
viewView.contentMode = .scaleToFill
viewView.clipsToBounds = true
return viewView
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(view1)
view1.backgroundColor = .black
view1.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0).isActive = true
view1.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0).isActive = true
view1.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
view1.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 5).isActive = true
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
//fatalError("init(coder:) has not been implemented")
}
}
class BottomAlignedCollectionViewFlowLayout: UICollectionViewFlowLayout {
override init() {
super.init()
self.scrollDirection = .horizontal
// self.minimumInteritemSpacing = 10.0
// self.minimumLineSpacing = 10.0
self.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 10)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributes = super.layoutAttributesForElements(in: rect)?
.map { [=10=].copy() } as? [UICollectionViewLayoutAttributes]
attributes?
.reduce([CGFloat: (CGFloat, [UICollectionViewLayoutAttributes])]()) {
guard .representedElementCategory == .cell else { return [=10=] }
return [=10=].merging([ceil(.center.y): (.frame.origin.y, [])]) {
([=10=].0 < .0 ? [=10=].0 : .0, [=10=].1 + .1)
}
}
.values.forEach { minY, line in
line.forEach {
[=10=].frame = [=10=].frame.offsetBy(
dx: 0,
dy: minY + [=10=].frame.origin.y
)
}
}
return attributes
}
}
在viewDidLoad中
collectionView.collectionViewLayout = BottomAlignedCollectionViewFlowLayout()
Code:
CollectionViewController -
class CollectionViewController: UIViewController, UICollectionViewDelegate,
UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
@IBOutlet weak var collectionView: UICollectionView!
let columns: CGFloat = 6.0
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(OneCollectionViewCell.self, forCellWithReuseIdentifier: "cellOne")
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return Int(columns)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellOne", for: indexPath) as! OneCollectionViewCell
let height : CGFloat
if indexPath.item == 0 {
height = 50
} else if indexPath.item == 1{
height = 100
} else if indexPath.item == 2 {
height = 70
}else {
height = 100
}
cell.configCell(height: height)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width : CGFloat
let height : CGFloat = 100
if indexPath.item == 0 {
width = 100
}
else if indexPath.item == 1{
width = 100
} else if indexPath.item == 2 {
width = 50
}else {
width = 80
}
return CGSize(width: width, height: height)
}
}
CollectionViewCell-
import UIKit
class OneCollectionViewCell: UICollectionViewCell {
public var view1: UIView = {
let viewView = UIView()
viewView.translatesAutoresizingMaskIntoConstraints = false
viewView.contentMode = .scaleToFill
viewView.clipsToBounds = true
return viewView
}()
var cstHeightAnchor: NSLayoutConstraint!
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(view1)
view1.backgroundColor = .black
cstHeightAnchor = view1.heightAnchor.constraint(equalToConstant: 100)
cstHeightAnchor.isActive = true
view1.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0).isActive = true
view1.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
view1.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 5).isActive = true
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
//fatalError("init(coder:) has not been implemented")
}
func configCell(height: CGFloat) {
cstHeightAnchor.constant = height
}
}