前言:
最近遇到一個(gè)磨人的需求狂巢。
背景:我們的首頁用的是 UICollectionView阎曹。在這個(gè)collectionview的底部昙衅,放一個(gè)FooterView,用來寫點(diǎn)提示信息歼捏。
要求:
1稿存、如果collectionview的內(nèi)容比較少(也就是說:collectionView.frame.height > collectionView.contentSize.height),那么這個(gè)FooterView就直接放到collectionview的底部瞳秽。
2瓣履、如果collectionview的內(nèi)容比較多(也就是說:collectionView.frame.height < collectionView.contentSize.height),那么這個(gè)FooterView就需要跟隨collectionview滾動(dòng)练俐。
如果是在UITableView上袖迎,我們可以這么干:
let tableView = UITableView()
tableView.tableFooterView = UIView()
但是在 UICollectionView 上,我沒有點(diǎn)出來這個(gè)footerview的屬性腺晾。這就很尷尬了燕锥。我去網(wǎng)上搜了一下,發(fā)現(xiàn)大家用的都是SectionHeader的辦法悯蝉。那這就有個(gè)問題了脯宿,SectionFooter 也是能寫的,但是在collectionview內(nèi)容比較少的時(shí)候泉粉,這個(gè)SectionFooter并不會(huì)放在collectionview的最底部,會(huì)放在屏幕中間榴芳。我家UI設(shè)計(jì)員肯定不會(huì)提意見
然后,我想了很久。決定偽造一下FooterView主籍。
Swift
代碼地址:https://github.com/gityuency/Autolayout
示例代碼類名 【FakeCollectionViewController】
示例效果
思路:
第一步:使用UIEdgeInsets來給collectionview底部設(shè)置一個(gè)縮進(jìn)鲤嫡。
第二步:給collectionview添加一個(gè)視圖,用來做FooterView柿祈。
第三步:在代理方法里面拿到collectionview的內(nèi)容高度哈误,給這個(gè)FooterView設(shè)置一下Frame哩至。
代碼:
import UIKit
class FakeCollectionViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
/// 復(fù)用 ID
let rid = "rid"
/// 單元格個(gè)數(shù)
var cellcount = 10
/// FooterView的高度
let FooterHeight: CGFloat = 60
/// 記錄 collectionview 的內(nèi)容高度
var contentHeight: CGFloat = 0
/// 放在底部的View
lazy var footerView: UIButton = {
let b = UIButton()
b.setTitle("點(diǎn)擊 FooterView", for: UIControl.State.normal)
b.backgroundColor = UIColor.brown
b.addTarget(self, action: #selector(click), for: .touchUpInside)
return b
}()
@objc func click() {
print("測試是否可以點(diǎn)擊")
}
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 11.0, *) {
collectionView.contentInsetAdjustmentBehavior = .never
} else {
automaticallyAdjustsScrollViewInsets = false
}
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: rid)
collectionView.addSubview(footerView)
collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: FooterHeight, right: 0)
// contentSize 是不包括 EdgeInsets的
}
}
extension FakeCollectionViewController: UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return cellcount
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: rid, for: indexPath)
cell.backgroundColor = UIColor.orange
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
cellcount += 10
collectionView.reloadData()
}
// 在這個(gè)方法里面可以拿到視圖的內(nèi)容高度
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if contentHeight == collectionView.contentSize.height { //如果內(nèi)容高度沒有變化,就不需要設(shè)置footer的位置
return
}
contentHeight = collectionView.contentSize.height
if collectionView.frame.height > collectionView.contentSize.height + FooterHeight { //當(dāng)視圖的高度 比 (內(nèi)容高度 + Footer高度) 大的時(shí)候
DispatchQueue.main.async {
print("直接放到collectionview的底部: \(collectionView.contentSize.height)")
let w = collectionView.bounds.width
let y = collectionView.frame.height - self.FooterHeight
self.footerView.frame = CGRect(x: 0, y: y, width: w, height: self.FooterHeight)
}
} else {
DispatchQueue.main.async {
print("根據(jù)內(nèi)容高度調(diào)整到底部: \(collectionView.contentSize.height)")
let w = collectionView.bounds.width
let y = collectionView.contentSize.height
self.footerView.frame = CGRect(x: 0, y: y, width: w, height: self.FooterHeight)
}
}
}
}
//if (cellcount - 1) == collectionView.indexPathsForVisibleItems.last?.row { // 這里表示要顯示最后一個(gè)cell
//}
結(jié)語:
今天八月二十一號了。我們Team換了座位蜜自。也算的上是個(gè)愜意的位置菩貌,右邊是很大飄窗,窗外是xx辦事中心重荠。好像是個(gè)歐式風(fēng)格的建筑箭阶?想想兩年前我坐在一個(gè)柱子旁邊,有種被遺棄的感覺戈鲁。