• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:iPhoneアプリプログラミングButtonの削除)

iPhoneアプリプログラミングButtonの削除

このQ&Aのポイント
  • iPhoneアプリ開発の勉強のため、Objective-Cを用いてカレンダーを作成しています。
  • 前月、来月のボタンを押した時、カレンダーに表示される月を更新したいのですが、うまくいきません。
  • ボタンの削除方法をいろいろと検索したのですが、なかなか解決に至る処理を見つけられませんでした。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

No.1です。 あぁ、ごめんなさい。 removeFromSuperViewじゃなくて removeFromSuperviewです。(vが小文字) と思ったら後にあるsetTitleというメソッドの方は removeFromSuperview使ってますね。 自分で間違えておいてアレですが、大文字/小文字が 違うと別のメソッドになりますので、注意してください。 ちなみに、そのsetTitleの中にある [_YearMonth removeFromSuperview]; は不要です。 これを実行すると、xxxx年xx月のラベル表示が消えてしまうと思います。 > @property (strong,nonatomic) IBOutlet UILabel *YearMonth; と書いた行で[Thred 1: breakpoint1.2]と緑色> で表示され、実行できませんでした。 これは、単純にYearMonthプロパティのアクセスにブレークポイントが 設定されていて、そのアクセスのタイミングで一時停止しているだけ だと思います。Debug - Continueで実行再開できると思いますし、 そもそもここで一時停止が不要ならブレークポイントの設定を削除すれば よいと思います。 あと、日付ボタンを一旦削除する処理ですが、 [[self.view viewWithTag:1] removeFromSuperview]; だけじゃダメですよ。 これだと、1番のタグを持つボタンがたくさんある中で 最初に見つかったボタン1個しか削除されません。 1番のタグを持つボタンが見つからなくなるまで 何度もremoveFromSuperviewを繰り返す必要があります。

ifonesapp
質問者

お礼

早い回答ありがとうございます! 小文字に直したらすんなり実行できました。こういうミスは気付きにくいですね; この警告文はよく覚えて無くてはいけませんね。 タグもWhileで回して全てのボタンが消えるようにできました。 ボタンを削除せずにどんどん上書きされる方法だと、消費メモリがどんどん膨れていき、月移動が飛び飛びになるのに対して 月移動のたびにボタンを削除する方法で記述したところ、消費メモリが11MB程度に落ち着くようになりました。 ボタンをいちいち更新せず、数値だけを変更する形で、どれだけ消費メモリが削減できるのか試してみようとも思います! ブレークポイントに関しては自分で設定したはずは無い(そもそも設定の仕方をしらない^^;)ので、何かの拍子に間違ったボタンを押してしまったのでしょうかね。continueすれば実行できるので無視しておきました。

すると、全ての回答が全文表示されます。

その他の回答 (1)

回答No.1

まず、ボタンを削除する方法ですが、 削除したいボタンに対して「removeFromSuperView」を 実行することで削除できます。 removeFromSuperViewの説明や使用例はたぶん入門書の どこかに書かれていると思います。 ただ、今のままでは削除したいボタンがどこにあるのかを 探すのがちょっと面倒なので、案としては日付ボタンに タグを設定して、カレンダーを更新するときは、タグが ついているボタン(=日付ボタン)を一旦全部削除するような処理を 入れれればよいと思います。 タグについては以下の説明が参考になると思います。 http://hiiro-game.seesaa.net/article/305166744.html しかし、現状前月ボタンを押しても何も反応しないのは、 それとは別の問題があると思います。 元のボタンを削除してないだけなら、そのボタンの上に新しいボタンが 乗っかって表示されて、カレンダーの表示は更新されるはずです。 ソースをざっと見たところ、前月ボタンを押すとpreviewメソッドが呼び出され その中で_monthを減算してcalendarViewを呼び出す構造になっていますが、 calendarViewの中で_monthを参照している箇所が一つもありません。 これでは_monthを減算しても表示か変化するわけありません。 どうやって月によって表示を変えているのかなと思ってcalendarViewを見たところ _firstDayWeekと_nowMonthLastDayという変数を参照して、月の始まりの曜日と 最終日で表示を変えるようになっていますね。 ということは、calendarViewを呼び出す前に_firstDayWeekと_nowMonthLastDay を更新していないのが、表示が変わらない原因だと思います。 _firstDayWeekはgetFirstWeekを呼び出すことで簡単に更新できるように していますが、_nowMonthLastDayはviewDidLoadの中に書いているコードを 月が変わった時にもう一度実行する必要がありますね。ここも別メソッド にして切り出せばよいと思いますが、そもそも_firstDayWeekと_nowMonthLastDay はcalendarViewメソッドの表示のためだけに使っているのだったら、 calendarViewメソッドの内の先頭で月初曜日と月最終日を求めてから処理すれば よいのではないかと思います。そうすれば_firstDayWeekと_nowMonthLastDayは プロパティ宣言する必要もなくcalendarViewメソッド内のローカル変数で処理して コードをわかりやすくできると思います。 あと、以前に意味不明として指摘していた、previewメソッド内で 「_month = 12;」の後に「_month--;」している処理ですが、 これ、「_month--;」じゃなくて「_year--;」の誤りじゃないですか? 1月の前月は、12月にして年を1年減らしたかったのを誤って月を減らして しまっているのではないですか? > この方法でカレンダーのレイアウトを描画していては、 > この先日付ごとにデータを管理する場合、どうなるんだろうと悩んでいます。 日付ごとにデータを管理するには、今のボタン表示とは別に 年月日に対応した管理オブジェクトを作成し、表示月に対応する ボタン表示と関連付ければいいのだと思います。 現状の構造で少し気になるのは、月の表示を切り替える際に、元のボタンを削除して ボタンを作り直そうとしていますが、ボタンを作り直すより、今表示されている ボタンの表示タイトル(+将来は関連する日付データオブジェクト)だけ 更新した方が処理効率はよさそうだなと思います。 ただボタン30個程度の更新でさほど気にする必要はないのかもしれません。 このあたりは実際に実装してみて体感上問題ないかを見て考えればよいと 思います。

ifonesapp
質問者

補足

回答ありがとうございます! さまざまなアドバイス感謝です。1つずつ乗り越えて行きたいです。 _nowMonthlastDay,_lastMonthDayの値を変化させるメソッドをcalendarViweメソッドの前に組むことで、無事に前月ボタンを押してカレンダーの描画が移り変わるようになりました。 ついでに、来月ボタンも正常に動作させることができました。 確かに、_nowMonthlastDay,_lastMonthDay変数は_calendarViewメソッドでしか使わないので、1つのメソッドにまとめてしまっても良いかもしれませんね。見やすいプログラムを書く習慣を身に着けるためにも書き換えてみます。 previwメソッド内の_monthやら_yearがごちゃごちゃだったのはテストとして試しに弄っていたものが残ったままでした。これも今回直しました。 しかし、ボタンの削除がなかなかうまくいきません。 日付ボタンには1をtagとしてつけていて、previwメソッドが呼び出された時にその中で[[self.view viewWithTag:1] removeFromSuperView];を実行し日付ボタンを削除してから、calendarViewメソッドを実行し新たな日付ボタンを作成する処理を組んだのですが、[[self.view viewWithTag:1] removeFromSuperView];に対して 「No visible @interface for'UIView' declares the selector 'removeFromSuperView'」とエラーが出てしまいます。 また、[[self.view viewWithTag:1] removeFromSuperView];の行を一旦コメント文としてカレンダー上部に表示するタイトルでremoveFromSuperViewの処理をテストしようとコードを組み実行したところ、 @property (strong,nonatomic) IBOutlet UILabel *YearMonth; と書いた行で[Thred 1: breakpoint1.2]と緑色で表示され、実行できませんでした。 YearMonthのラベルはstoryboardにラベルを貼り付け、outletでstorong接続しました。 もともとはStoryBoardを使わずにプログラムを書いて年月表示をしていたのですが、プログラムで書いたラベルをプロパティ宣言したように扱う方法が分からなかったので、一度プログラムで作った年月のラベルをコメントアウトしてStoryBoardを用いて組み直したところ、上記の「Thread~」のエラー?が出てしまいました。 検索してみると、入力待ちのようなことが書かれていますが・・・なぜこうなったのか分かりません。 以下にコードを晒します。 ■ViewController.h http://www.dotup.org/uploda/www.dotup.org4899904.txt ■ViewController.m http://www.dotup.org/uploda/www.dotup.org4899907.txt 実際どうなるのか分かりませんが、毎回ボタンを作り直すのは重くなりそうに思いますね。特に数ヶ月前に移動したいときなんかは重いと煩わしくなりそうです。 オブジェクトに関しても勉強しておこうと思います。 数値だけを変化させて済むのであれば、そうした方が良さそうに思いますが、ボタンの削除についても勉強したいので、とりあえず毎回ボタンを描画しなおす方法で作り上げたいと思います。

すると、全ての回答が全文表示されます。

関連するQ&A