日历按钮未正确删除 - Lua

时间:2013-04-01 20:55:57

标签: mobile calendar lua corona

我正在尝试制作一个日历,以便能够逐月切换。我的问题是在触摸下一个或上一个按钮时删除每一天按钮。

这是我的上一个按钮的代码,可以从当前月份切换到上个月。我的下一个按钮代码几乎完全相同。当我第一次点击按钮时,它工作得非常好,但是当我再次点击它时,我在子项上出现错误: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

2 个答案:

答案 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

如果设置buttonbuttonTable,则对上一个或下一个函数的调用的第一部分将按预期工作,并且将在月份的按钮上调用removeSelf。但是,这实际上并没有从button表中删除按钮。

因此,当您再次进入numYears循环时,不仅会将新创建的按钮添加到buttonbuttonTable,还可以使用按钮我刚刚在removeSelf中拨打了button,因此这些内容会再次添加到buttonTable。但至关重要的是,它们现在只是表格,所以当你第二次给它们调用removeSelf时就会这样做。我认为这是你看到错误的原因。

table.insert(buttonTable, button[i])移至if...then将解决此问题,因为它只会向buttonTable添加新创建的按钮,然后在每次调用下一个或上一个按钮时将其删除。

但要谨慎。 button表格有点混乱。在进行了一些导航后,它会有一堆死按钮(除非你宣布这些值很弱,否则不能进行垃圾收集)加上一个月的工作按钮。如果你试图用它做任何事情,那么你可能会遇到问题。

如果你甚至需要button表,那么从代码中就不清楚了。如果在其他地方不需要它,那么只需按住buttonTable中的按钮引用就更安全了。