Reputation: 5003
I am trying to build a timeline of sorts. I have a view controller which contains a collectionView. Each collectionView cell represents a month's worth of data. In each cell I have a stackView. This stackView contains 30 subviews which each represent a day of data.
The full project is here if you wanna try it out: https://github.com/AlexMarshall12/iOS-timeline
My current approach for coloring each dayCell subview is to create all the subviews in the cell initially in the awakeFromNib of the custom cell.
class MonthCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var stackView: UIStackView!
var dayViews: [Int:UIView] = [:]
override func awakeFromNib() {
super.awakeFromNib()
for i in 1...30 {
let tick = UIView()
dayViews[i] = tick
self.stackView?.addArrangedSubview(tick)
}
}
}
Note that I also build a dictionary that indexes each subview in the cell from 1-30.
Then in my viewController, in my cellForItemAt method for my collectionView, I look to see for that month which days are in the data using my "dates" function. I then lookup this view with the dictionary I build earlier and color it red.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MonthCollectionViewCell", for: indexPath) as! MonthCollectionViewCell
cell.backgroundColor = UIColor.gray
let dayViews = cell.dayViews
let firstDate = dates.first
let index = indexPath.item
let monthDate = Calendar.current.date(byAdding: .month, value: index, to: firstDate as! Date)
let monthInt = Calendar.current.component(.month, from: monthDate!)
let yearInt = Calendar.current.component(.year, from: monthDate!)
let monthDates = dates(self.dates as! [Date], withinMonth: monthInt, withinYear: yearInt)
for date in monthDates {
let dayInt = date.interval(ofComponent: .day, fromDate: (monthDate?.startOfMonth())!)
let tick = dayViews[dayInt]
print(tick,"tick")
tick?.backgroundColor = UIColor.red
}
return cell
}
func dates(_ dates: [Date], withinMonth month: Int, withinYear year: Int) -> [Date] {
let calendar = Calendar.current
let components: Set<Calendar.Component> = [.month,.year]
print(components,"components")
let filtered = dates.filter { (date) -> Bool in
let monthAndYear = calendar.dateComponents(components, from: date)
return (monthAndYear.month == month && monthAndYear.year == year)
}
return filtered
}
Currently, everything shows up just as grey month cells that can be scrolled right to left. Even though my console tells me its finding matches to color, it doesn't appear to be coloring them. What am I doing wrong in this approach/implementation?
Upvotes: 0
Views: 110
Reputation: 535850
When you have a case of "I don't see the view I expect to see", run your app in the simulator and, back in Xcode, fire up the View Debugger.
In this case, when you do that, you'll see your error immediately: all your "ticks" are invisible because you are sending zero-size plain vanilla UIViews to your "Fill distribution" stack view as arranged subviews. The stack view has no idea what do with these. So they end up with no size, which makes them invisible.
Change the "Fill distribution" to "Fill Equally distribution" in the xib editor, run the app again, and presto, you'll start to see some ticks!
Upvotes: 2