I am using RubyMotion and have a calendar implemented using CKCalendarView and I have the following code highlighting days on which events occur.
The following method is called from layoutSubviews
def calendarDidLayoutSubviews(calendar)
_events_array = []
if self.events
self.events.reverse.each do |ev|
mdy = ev.date.month_date_year
_events_array << mdy unless _events_array.include?(mdy)
end
end
Dispatch::Queue.main.async do
today = NSDate.date.month_date_year
if calendar.dateButtons && calendar.dateButtons.length > 0
calendar.dateButtons.each do |db|
db.backgroundColor = "f4f2ee".to_color
if db.date && db.date >= calendar.minimumDate && db.date <= calendar.maximumDate
if _events_array && _events_array.length > 0
db.setTitleColor("c7c3bb".to_color, forState:UIControlStateNormal)
db.backgroundColor = "f4f2ee".to_color
if _events_array.include?(db.date.month_date_year)
db.setTitleColor(UIColor.blackColor, forState:UIControlStateNormal)
db.backgroundColor = "9ebf6c".to_color
_events_array.delete(db.date.month_date_year)
end
end
end
if db.date && db.date.month_date_year == today
if calendar.minimumDate <= db.date && calendar.maximumDate >= db.date
db.setTitleColor(UIColor.blackColor, forState:UIControlStateNormal)
else
db.setTitleColor("f4f2ee".to_color, forState:UIControlStateNormal)
end
end
end
end
end
end
As it is, this freezes the UI for a .5 - 1.5s when drawing. If I move it in to a background thread, it takes 4 or 5 times as long to draw, but doesn't freeze the UI.
Question: Is there a way to give the background thread a higher priority, or a way to incrementally draw and highlight the dateButtons so that it doesn't look like nothing is happening in the half dozen seconds it takes to draw(when not in the main thread)?
The method I posted was getting called in the main thread, so I switched it to be called in a background thread, and then called the main thread for all drawing operations inside my loop.
def calendarDidLayoutSubviews(calendar)
_events_array = []
if self.events
self.events.reverse.each do |ev|
mdy = ev.date.month_date_year
_events_array << mdy unless _events_array.include?(mdy)
end
end
today = NSDate.date.month_date_year
if calendar.dateButtons && calendar.dateButtons.length > 0
calendar.dateButtons.each do |db|
Dispatch::Queue.main.async do
db.backgroundColor = "f4f2ee".to_color
end
if db.date && db.date >= calendar.minimumDate && db.date <= calendar.maximumDate
if _events_array && _events_array.length > 0
Dispatch::Queue.main.async do
db.setTitleColor("c7c3bb".to_color, forState:UIControlStateNormal)
db.backgroundColor = "f4f2ee".to_color
end
if _events_array.include?(db.date.month_date_year)
Dispatch::Queue.main.async do
db.setTitleColor(UIColor.blackColor, forState:UIControlStateNormal)
db.backgroundColor = "9ebf6c".to_color
end
_events_array.delete(db.date.month_date_year)
end
end
end
if db.date && db.date.month_date_year == today
if calendar.minimumDate <= db.date && calendar.maximumDate >= db.date
Dispatch::Queue.main.async do
db.setTitleColor(UIColor.blackColor, forState:UIControlStateNormal)
end
else
Dispatch::Queue.main.async do
db.setTitleColor("f4f2ee".to_color, forState:UIControlStateNormal)
end
end
end
end
end
end