![](/img/trans.png)
[英]Collectionview inside tableview cell not increasing height of collectionView
[英]Can not Select CollectionView in TableView Cell
我正在制作日歷。
我把collection view放在table view中,但是collection view的單元格沒有被選中。
我剛剛將集合視圖添加到表格視圖單元格並設置了所有數據源設置。
TableView allowSelection 關閉,tableViewCell isUserInteractionEnabled 設置為 false。
這里是我的代碼
CalanderView.swift
import Foundation
import UIKit
class CalendarView: UIView {
private var increaseYear: Int = 0
internal lazy var tableView: UITableView = {
let table = UITableView()
table.showsVerticalScrollIndicator = false
table.translatesAutoresizingMaskIntoConstraints = false
// table.allowsSelection = false
table.register(CalendarCell.self, forCellReuseIdentifier: CalendarCell.reuseIdentifier)
table.delegate = self
table.dataSource = self
table.bounces = false
table.tableFooterView = UIView(
frame: CGRect(
x: 0,
y: 0,
width: self.frame.width,
height: 120.calculated
)
)
// table.estimatedRowHeight = 600.calculated
return table
}()
internal lazy var header: CalendarHeader = {
let header = CalendarHeader(frame: self.frame)
header.backgroundColor = .white
return header
}()
override init(frame: CGRect) {
super.init(frame: frame)
setLayoutConstraints()
}
required init(coder: NSCoder) {
super.init(coder: coder)!
setLayoutConstraints()
}
}
// MARK: -CUSTOM FUNCTION
extension CalendarView {
func getCurrentMonth(_ val: Int) -> Int {
let obj = CalendarHelper.today.month + val
let currentMonth = obj % 12 == 0 ? 12 : obj % 12
let floatVal: Float = Float(obj) / 12.0
let ceilVal = ceil(floatVal - 1)
self.increaseYear = Int(ceilVal)
return currentMonth
}
}
// MARK: -DELEGATES, DATASOURCE
extension CalendarView: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 6
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: CalendarCell = tableView.dequeueReusableCell(for: indexPath)
let currentMonth = getCurrentMonth(indexPath.row)
let currentYear = CalendarHelper.today.year + self.increaseYear
let component = DateComponents(year: currentYear, month: currentMonth)
let days = CalendarHelper.shared.daysOfMonth[currentMonth-1]
let dayOfMonth = CalendarHelper.dateFrom(component).isLeapMonth ? days + 1 : days
cell.isUserInteractionEnabled = false
cell.month = currentMonth
cell.year = currentYear
cell.dayOfWeek = CalendarHelper.dateFrom(component).weekday
cell.dayOfMonth = dayOfMonth
cell.separatorInset = UIEdgeInsets(top: 0, left: 20.calculated, bottom: 0, right: 20.calculated)
cell.bringSubviewToFront(cell.dayCollection)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 550
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 550
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("tableView didSelectRowAt")
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if let indexPath = self.tableView.indexPathsForVisibleRows {
if indexPath.indices.contains(1) {
let cell = tableView.cellForRow(at: indexPath[1]) as! CalendarCell
if scrollView.contentOffset.y > cell.frame.origin.y - 10 {
self.header.month = cell.month
self.header.year = cell.year
}
let beforeCell = tableView.cellForRow(at: indexPath[0]) as! CalendarCell
if scrollView.contentOffset.y < cell.frame.origin.y - 10 {
self.header.month = beforeCell.month
self.header.year = beforeCell.year
}
}
}
}
}
// MARK: -SET LAYOUT
extension CalendarView {
func setLayoutConstraints() {
setTableViewLayout()
setHeaderViewLayout()
}
func setTableViewLayout() {
self.addSubview(self.tableView)
self.tableView.snp.makeConstraints({
$0.top.bottom.left.right.equalTo(self)
})
}
func setHeaderViewLayout() {
self.addSubview(self.header)
self.header.snp.makeConstraints({
$0.left.right.top.equalTo(self)
$0.height.equalTo(90.calculated)
})
}
}
class CalendarHeader: UIView {
var year: Int = 0 {
willSet(newVal) {
self._year.attributedText = String(newVal)
.normal(fontSize: 16, color: Color.customer, spacing: -0.07)
}
}
var month: Int = 0 {
willSet(newVal) {
let str = String(newVal) + "."
self._month.attributedText = str
.systemFont(fontSize: 28, weight: .semibold, color: Color.customer, spacing: -0.12)
}
}
private var _year: UILabel = {
let label = UILabel()
label.attributedText = "2019"
.normal(fontSize: 16, color: Color.customer, spacing: -0.07)
return label
}()
private var _month: UILabel = {
let label = UILabel()
label.attributedText = "11."
.systemFont(fontSize: 28, weight: .semibold, color: Color.customer, spacing: -0.12)
return label
}()
private var chevron: UIImageView = {
let imageView = UIImageView()
imageView.image = #imageLiteral(resourceName: "chevron_bottom")
imageView.contentMode = .scaleAspectFit
imageView.clipsToBounds = true
return imageView
}()
override init(frame: CGRect) {
super.init(frame: frame)
setLayoutConstraints()
defer {
self.year = CalendarHelper.today.year
self.month = CalendarHelper.today.month
}
}
required init(coder: NSCoder) {
super.init(coder: coder)!
setLayoutConstraints()
defer {
self.year = CalendarHelper.today.year
self.month = CalendarHelper.today.month
}
}
func setLayoutConstraints() {
self.addSubview(self._year)
self._year.snp.makeConstraints({
$0.left.equalTo(self).offset(20.calculated)
$0.top.equalTo(self).offset(41.calculated)
})
self.addSubview(self._month)
self._month.snp.makeConstraints({
$0.left.equalTo(self._year.snp.right).offset(4.calculated)
$0.top.equalTo(self).offset(28.calculated)
})
self.addSubview(self.chevron)
self.chevron.snp.makeConstraints({
$0.width.height.equalTo(CGSize.ratio(width: 26, height: 14))
$0.right.equalTo(self).offset(-20.calculated)
$0.centerY.equalTo(self._month)
})
}
}
CalanderCell.swift
import Foundation
import UIKit
import SnapKit
class CalendarCell: UITableViewCell {
let weekdays = ["S", "M", "T", "W", "T", "F", "S"]
var dayOfWeek = 0
var dayOfMonth = 0
var day = 0
var year: Int = 0 {
willSet(newVal) {
self._year.attributedText = String(newVal)
.normal(fontSize: 16, color: Color.customer, spacing: -0.07)
}
}
var month: Int = 0 {
willSet(newVal) {
let str = String(newVal) + "."
self._month.attributedText = str
.systemFont(fontSize: 28, weight: .semibold, color: Color.customer, spacing: -0.12)
}
}
internal var _year: UILabel = {
let label = UILabel()
label.attributedText = "2019"
.normal(fontSize: 16, color: Color.customer, spacing: -0.07)
return label
}()
internal var _month: UILabel = {
let label = UILabel()
label.attributedText = "11."
.systemFont(fontSize: 28, weight: .semibold, color: Color.customer, spacing: -0.12)
return label
}()
internal var dayCollection: UICollectionView = {
let collectionViewLayout = UICollectionViewFlowLayout()
collectionViewLayout.scrollDirection = .vertical
let collection = UICollectionView(
frame: CGRect(x: 0, y: 0, width: 0, height: 0),
collectionViewLayout: collectionViewLayout
)
collection.showsVerticalScrollIndicator = false
collection.showsHorizontalScrollIndicator = false
collection.isMultipleTouchEnabled = false
collection.allowsMultipleSelection = false
collection.isScrollEnabled = false
collection.isExclusiveTouch = true
collection.isUserInteractionEnabled = true
collection.backgroundColor = Color.background
collection.register(DayCell.self, forCellWithReuseIdentifier: DayCell.reuseIdentifier)
return collection
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setLayoutConstraints()
dayCollection.delegate = self
dayCollection.dataSource = self
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension CalendarCell {
}
extension CalendarCell: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
/// 지정된 섹션에 표시할 항목의 개수를 묻는 메서드
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if section == 0 {
return 7
} else {
print("dayOfWeek", dayOfMonth)
return dayOfMonth + dayOfWeek - 1
}
}
/// 컬렉션뷰의 지정된 위치에 표시할 셀을 요청하는 메서드.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: DayCell = collectionView.dequeueReusableCell(for: indexPath)
cell.isUserInteractionEnabled = true
if indexPath.section == 0 {
cell.week = weekdays[indexPath.row]
} else {
if dayOfWeek > 1 {
cell.day = ""
dayOfWeek -= 1
} else {
day += 1
cell.day = String(day)
cell.isSunday = indexPath.row % 7 == 0
}
}
return cell
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 2
}
/// 지정된 섹션의 여백을 반환하는 메서드.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 25.calculated, bottom: 25.calculated, right: 25.calculated)
}
/// 지정된 섹션의 행 사이 간격 최소 간격을 반환하는 메서드
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 25
}
/// 지정된 섹션의 셀 사이의 최소간격을 반환하는 메서드.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 25
}
/// 지정된 셀의 크기를 반환하는 메서드
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize.ratio(width: 30, height: 30)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("indexPath: ", indexPath)
}
}
extension CalendarCell {
func setLayoutConstraints() {
setHeaderLayout()
setDayCollectionLayout()
}
func setHeaderLayout() {
self.addSubview(self._year)
self._year.snp.makeConstraints({
$0.left.equalTo(self).offset(20.calculated)
$0.top.equalTo(self).offset(61.calculated)
})
self.addSubview(self._month)
self._month.snp.makeConstraints({
$0.left.equalTo(self._year.snp.right).offset(4.calculated)
$0.top.equalTo(self).offset(48.calculated)
})
}
func setDayCollectionLayout() {
self.addSubview(self.dayCollection)
self.dayCollection.snp.makeConstraints({
$0.height.equalTo(400.calculated)
$0.left.right.equalTo(self)
$0.top.equalTo(self).offset(116.calculated)
})
}
}
DayCell.swift
import Foundation
import UIKit
class DayCell: UICollectionViewCell {
var isSunday: Bool = false {
willSet(newVal) {
self._day.textColor = newVal ? Color.customer : Color.label
}
}
var isReserved: Bool = false {
willSet(newVal) {
self._day.textColor = Color.cancle
}
}
// override var isSelected: Bool {
// willSet(newVal) {
// self.backgroundColor = newVal
// ? Color.customer
// : Color.background
// self._day.textColor = newVal
// ? .white
// : (isSunday ? Color.customer : Color.label)
// }
// }
var day: String = "" {
willSet(newVal) {
self._day.attributedText = newVal
.systemFont(fontSize: 18, weight: .bold, color: Color.label, spacing: -0.07)
}
}
var week: String = "" {
willSet(newVal) {
self._day.attributedText = newVal
.systemFont(fontSize: 20, weight: .medium, color: Color.customer, spacing: -0.08)
}
}
internal var _day: UILabel = {
let label = UILabel()
label.attributedText = "1"
.systemFont(fontSize: 18, weight: .bold, color: Color.label, spacing: -0.07)
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.layer.cornerRadius = 7.calculated
self.addSubview(self._day)
self._day.snp.makeConstraints({
$0.center.equalTo(self)
})
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
這是錯誤的:
class DayCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
self.layer.cornerRadius = 7.calculated
self.addSubview(self._day) // <-- NO
self._day.snp.makeConstraints({
$0.center.equalTo(self)
})
}
}
永遠不要向單元格添加子視圖。 說
self.contentView.addSubview(self._day)
否則無法觸摸_day
界面。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.