0

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

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

2 回答 2

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
于 2013-04-02T05:38:36.657 回答
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,然后在每次调用 next 或 previous 时将其删除。

不过要注意一点。button桌子有点乱。经过一番浏览后,它将有一堆死按钮(除非您将值声明为弱,否则这些按钮不能被垃圾收集)加上一个月的工作按钮。如果你试图用它做任何事情,你很可能会遇到问题。

button如果您甚至需要表格,则从代码中不清楚。如果在其他地方不需要它,那么将按钮引用保存在buttonTable.

于 2013-04-03T10:31:43.080 回答