0

月ごとに切り替えられるカレンダーを作ろうとしています。私の問題は、次または前のボタンに触れたときに毎日のボタンを削除することです。

今月から前月に切り替える前のボタンのコードは次のとおりです。私の [次へ] ボタンのコードはほぼ同じです。ボタンを初めてタップしたときは問題なく動作しますが、もう一度タップすると、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

問題のコードが機能しない (そして を入れても機能しtable.insertない) 理由は、テーブルif...thenの使用方法によるものです。button

開始するループfor i = 1, math.floor(numYears * 365.25) doは、1 から数百/千までのインデックスを作成します (に応じてnumYears)。

ただし、button[i]=テーブルを埋めるために使用していて、一度に 30 程度しか埋めていないため、作成しているのは、テーブルの途中に nil 以外のエントリがいくつかあるまばらなテーブルです。

実際に何が起こるかというと、ほとんどの「挿入」が挿入されているということtable.insert(buttonTable, button[i])です。これが初めての場合、実際には次の 2 つの理由で問題なく動作します。if..thennil

  • 空のテーブルに挿入しても何も実行されず、テーブルの最後にnil挿入しても実行されませんnil
  • nil 以外のエントリはbutton1 か月分しかないため、1 か月分だけが挿入されます。buttonTable

このようbuttonbuttonTableセットアップすると、前または次の関数への呼び出しの最初の部分が期待どおりに機能removeSelfし、1 か月分のボタンで呼び出されます。ただし、これは実際にはbuttonテーブルからボタンを削除しません。

そのため、numYearsループに戻ったときに、新たに作成したボタンを と の両方に追加するだけでなく、button呼び出したbuttonTableばかりのボタンも残っているため、これらが再度追加されます。ただし、重要なことは、それらは現在単なるテーブルであるため、2 回目に呼び出すと、barfs が発生することです。これがあなたが見たエラーの原因だと思います。removeSelfbuttonbuttonTableremoveSelf

に移動table.insert(buttonTable, button[i])すると、if...then新しく作成されたボタンのみが追加されbuttonTable、次または前が呼び出されるたびに削除されるため、この問題は解決します。

ただし、注意が必要です。テーブルはbuttonちょっとぐちゃぐちゃ。少しナビゲートした後、多数のデッド ボタン (値を弱いと宣言しない限りガベージ コレクションできません) と 1 か月分の動作ボタンが表示されます。それを使って何かをしようとすると、問題が発生する可能性があります。

buttonテーブルが必要かどうかは、コードからは明らかではありません。他の場所で必要ない場合は、ボタンの参照を に保持する方がおそらく安全buttonTableです。

于 2013-04-03T10:31:43.080 に答える