我正在尝试制作一个日历,以便能够逐月切换。我的问题是在触摸下一个或上一个按钮时删除每一天按钮。
这是我的上一个按钮的代码,可以从当前月份切换到上个月。我的下一个按钮代码几乎完全相同。当我第一次点击按钮时,它工作得非常好,但是当我再次点击它时,我在子项上出现错误:removeSelf()行,并且打印消息告诉我表中有61个元素。每当我去一个尚未见过的月份时,它似乎会在桌面上添加额外的按钮。
这对我来说真的很令人沮丧,因为我没有看到任何理由为什么代码每个月都会制作额外的按钮,即使这样做,每个按钮点击时仍然会被删除。有人可以帮助我吗?
local prev_function = function(event)
if event.phase == "release" then
today.year = 2012
today.month = 3
today.day = 29
today.wday = 5
if monthNum == 1 then
monthNum = 12
yearNum = yearNum - 1
elseif monthNum ~= 1 then
monthNum = monthNum - 1
end
local month = ""
if monthNum == 1 then month = "January"
elseif monthNum == 2 then month = "February"
elseif monthNum == 3 then month = "March"
elseif monthNum == 4 then month = "April"
elseif monthNum == 5 then month = "May"
elseif monthNum == 6 then month = "June"
elseif monthNum == 7 then month = "July"
elseif monthNum == 8 then month = "August"
elseif monthNum == 9 then month = "September"
elseif monthNum == 10 then month = "October"
elseif monthNum == 11 then month = "November"
elseif monthNum == 12 then month = "December"
end
monthText.text = month .. " " .. yearNum
print("Table elements before button deletion: " .. #buttonTable)
for i = #buttonTable, 1, -1 do
--[[if button[i] ~= nil then
table.remove(buttonTable)
button[i]:removeSelf()
button[i] = nil
end--]]
local child = table.remove(buttonTable)
if child ~= nil then
child:removeSelf()
child = nil
end
end
print("Table elements after button deletion: " .. #buttonTable)
next_button.alpha = 1
for i = 1, math.floor(numYears * 365.25) do
dateTable[i] = calendar.getInfo(today) --calculate the next day's date
if dateTable[i].year == yearNum and dateTable[i].month == monthNum then -- create a button if the date's year and month match the desired month
button[i] = ui.newButton{
default = "images/day.png",
over = "images/dayover.png",
text = dateTable[i].day,
size = 30,
font = native.systemFontBold,
textColor = {0, 0, 0, 255},
onEvent = addExpense_function,
offset = -35 }
if dateTable[i].wday == 1 then button[i].x = math.floor(col/2)
elseif dateTable[i].wday == 2 then button[i].x = (col * 1) + math.floor(col/2)
elseif dateTable[i].wday == 3 then button[i].x = (col * 2) + math.floor(col/2)
elseif dateTable[i].wday == 4 then button[i].x = (col * 3) + math.floor(col/2)
elseif dateTable[i].wday == 5 then button[i].x = (col * 4) + math.floor(col/2)
elseif dateTable[i].wday == 6 then button[i].x = (col * 5) + math.floor(col/2)
elseif dateTable[i].wday == 7 then button[i].x = (col * 6) + math.floor(col/2)
end
if dateTable[i].day == 1 then button[i].y = wDayBar.y + wDayBar.height/2 + math.floor(row/2)
elseif dateTable[i].wday == 1 then button[i].y = button[i-1].y + row
else button[i].y = button[i-1].y
end
end
today = dateTable[i]
table.insert(buttonTable, button[i])
--button[i].id = "button_" .. i
end
print("Table elements after button creation: " .. #buttonTable)
end
return true
end
答案 0 :(得分:0)
除了制作一个新表以及像Nicol建议的列坐标之外,我发现我需要将table.insert()命令放在if ... then
结构中。我不确定为什么在if ... then
结构之后立即将其放置不能正常工作,但我猜它是因为按钮是在结构内部创建的。
local prev_function = function(event)
if event.phase == "release" then
--set date to start from
today.year = 2012
today.month = 2
today.day = 29
today.wday = 4
--determine new month number
if monthNum == 1 then
monthNum = 12
yearNum = yearNum - 1
elseif monthNum ~= 1 then
monthNum = monthNum - 1
end
--set month string
local month = monthTable[monthNum]
monthText.text = month .. " " .. yearNum
print("Table elements before button deletion: " .. #buttonTable)
--remove all elements in buttonTable
for i = #buttonTable, 1, -1 do
local child = table.remove(buttonTable)
if child ~= nil then
child:removeSelf()
child = nil
end
end
print("Table elements after button deletion: " .. #buttonTable)
next_button.alpha = 1
--hide prev_button if we get to the month after the month we started from
if monthNum == today.month + 1 and yearNum == today.year then
prev_button.alpha = 0
end
--generate dates for specified number of years
for i = 1, math.floor(numYears * 365.25) do
dateTable[i] = calendar.getInfo(today)
--create a button for each date inside desired month
if dateTable[i].year == yearNum and dateTable[i].month == monthNum then
button[i] = ui.newButton{
default = "images/day.png",
over = "images/dayover.png",
text = dateTable[i].day,
size = 30,
font = native.systemFontBold,
textColor = {0, 0, 0, 255},
onEvent = addExpense_function,
offset = -35 }
--set x and y
button[i].x = colTable[dateTable[i].wday]
if dateTable[i].day == 1 then button[i].y = wDayBar.y + wDayBar.height/2 + math.floor(row/2)
elseif dateTable[i].wday == 1 then button[i].y = button[i-1].y + row
else button[i].y = button[i-1].y
end
table.insert(buttonTable, button[i])
end
--change 'today' for next iteration in the for loop
today = dateTable[i]
end
print("Table elements after button creation: " .. #buttonTable)
end
return true
end
答案 1 :(得分:0)
问题中的代码不起作用(并将table.insert
置于if...then
内部确实有效)的原因是由于您使用button
表的方式
启动for i = 1, math.floor(numYears * 365.25) do
的循环将创建从1到几百/千的索引(取决于numYears
)。
但是,当您使用button[i]=
填充表格并且一次只填充30个左右时,您创建的是一个稀疏表格,其中包含一些非零条目在桌子的中间。
现在在table.insert(buttonTable, button[i])
之外的if..then
实际发生的事情是大多数“插入”都在插入nil
。第一次实际上这可以正常工作有两个原因:
nil
不会做什么,也不会在表的末尾插入nil
button
只有一个月的非零参赛作品,所以只有一个月的价值会被插入buttonTable
如果设置button
和buttonTable
,则对上一个或下一个函数的调用的第一部分将按预期工作,并且将在月份的按钮上调用removeSelf
。但是,这实际上并没有从button
表中删除按钮。
因此,当您再次进入numYears
循环时,不仅会将新创建的按钮添加到button
和buttonTable
,还可以使用按钮我刚刚在removeSelf
中拨打了button
,因此这些内容会再次添加到buttonTable
。但至关重要的是,它们现在只是表格,所以当你第二次给它们调用removeSelf
时就会这样做。我认为这是你看到错误的原因。
将table.insert(buttonTable, button[i])
移至if...then
将解决此问题,因为它只会向buttonTable
添加新创建的按钮,然后在每次调用下一个或上一个按钮时将其删除。
但要谨慎。 button
表格有点混乱。在进行了一些导航后,它会有一堆死按钮(除非你宣布这些值很弱,否则不能进行垃圾收集)加上一个月的工作按钮。如果你试图用它做任何事情,那么你可能会遇到问题。
如果你甚至需要button
表,那么从代码中就不清楚了。如果在其他地方不需要它,那么只需按住buttonTable
中的按钮引用就更安全了。