• 締切済み

iphoneアプリの開発

電卓アプリを作っています。 今困っているのは 1.割り算で小数点以下の計算ができない。 2.3つ以上の計算が(2×3×4のような)足し算しかできない。 3.間違えて数値を入力した場合に使うバックスペース的なボタンの作り方。 です。 どれか一つでもいいのでアドバイスいただけたらありがたいです。 #import "myViewController.h" @implementation myViewController // The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad. /* - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization. } return self; } */ // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)viewDidLoad { [super viewDidLoad]; startInput = YES; currentValue = 0; } -(IBAction)numberButtonPressed:(id)sender { UIButton *b = (UIButton *)sender; if( startInput ){ // 最初の1桁目が0なら表示しない if( b.tag == 0 ) return; // 新しく表示する文字列を作成 label.text = [NSString stringWithFormat:@"%d", b.tag]; startInput = NO; } else { // すでに表示されている文字列に連結 label.text = [NSString stringWithFormat:@"%@%d", label.text, b.tag]; } NSString *path = [[NSBundle mainBundle] pathForResource:@"button5" ofType:@"wav"]; NSURL *url = [NSURL fileURLWithPath:path]; AVAudioPlayer *audio = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; [audio play]; } -(IBAction)equalButtonPressed:(id)sender { currentValue = sum; sum = sum-sum; // 直前に押された演算子で場合分け if( operation == 0 ){ currentValue += [label.text intValue]; } else if( operation == 1 ){ currentValue -= [label.text intValue]; } else if( operation ==2){ currentValue *= [label.text intValue]; } else if (operation ==3){ currentValue /= [label.text intValue]; } // 表示の更新 label.text = [NSString stringWithFormat:@"%d", currentValue]; startInput = YES; label2.text =@"="; NSString *path = [[NSBundle mainBundle] pathForResource:@"button5" ofType:@"wav"]; NSURL *url = [NSURL fileURLWithPath:path]; AVAudioPlayer *audio = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; [audio play]; } -(IBAction)opButtonPressed:(id)sender { UIButton *b = (UIButton *)sender; // 現在値の保存 if( operation == 0 ){ currentValue= [label.text intValue]; sum +=currentValue; label.text =[NSString stringWithFormat:@"%d", sum]; } // 演算の保存 operation = b.tag; startInput = YES; if( operation == 0 ){ label2.text =@"+"; } if( operation == 1 ){ label2.text =@"-"; } if( operation == 2 ){ label2.text =@"×"; } if( operation == 3 ){ label2.text =@"÷"; } NSString *path = [[NSBundle mainBundle] pathForResource:@"button5" ofType:@"wav"]; NSURL *url = [NSURL fileURLWithPath:path]; AVAudioPlayer *audio = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; [audio play]; } -(IBAction)clearButtonPressed:(id)sender { label.text = @"0"; startInput = YES; label2.text =@""; NSString *path = [[NSBundle mainBundle] pathForResource:@"button5" ofType:@"wav"]; NSURL *url = [NSURL fileURLWithPath:path]; AVAudioPlayer *audio = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; [audio play]; } /* // Override to allow orientations other than the default portrait orientation. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations. return (interfaceOrientation == UIInterfaceOrientationPortrait); } */ - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc. that aren't in use. } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (void)dealloc { [super dealloc]; } @end

みんなの回答

  • harawo
  • ベストアンサー率58% (3742/6450)
回答No.1

質問1に対してですが、数値を整数(int)で計算している以上、小数点以下は切り捨てられます。小数点以下を計算するなら、浮動小数点数(float、double)で計算しなければなりません。 質問2、3に対しては、それ以前にプログラム全体の見直しと、再設計が必要なため、現時点で考えても意味がないことだと思います。 まず、数値を整数でなく、浮動小数点数で処理すると決まった時点で、いくつもの処理すべき項目が出てきます。画面に表示する最大桁数と、内部で計算する際の有効桁数をどうするか?具体的に説明すると、「10÷3=3.333333……」の計算をする場合、小数点何位まで表示し、有効桁数をどうするか、ということです。有効桁数を適切に決めないと、「10÷3×3」と計算した場合に、答えが「10」にならず、「9.9999999」などとなることがあります。その場合、それでもかまわないのか、10にならなければならないのか、プログラム設計の指針を、決めておかなければなりません。 有効桁数の問題に対処するために、計算過程を記憶しておくプログラムが必要でしょう。先の例でいえば、「10÷3×3」を、「10×3÷3」と計算すれば、有効桁数に起因する誤差を、最小限に抑えることができます。計算過程を記憶するということは、質問3のUndo機能を持たせることにも通じるでしょう。 単純な計算機を作るだけでも、一筋縄ではいかないことがわかると思います。 ※本題と関係なく、気になったこと: AVAudioPlayer *audio = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; [audio play]; ボタンを押すたびに「audio」インスタンスを生成していますが、それを開放するコードが見受けられません。インスタンスは再利用されるのではなく、そのつど新しいインスタンスが生成されます。ボタンはひんぱんに押されるわけですから、「audio」インスタンスが、そのうちメモリを食いつぶしてしまうかもしれません。 iOSでは、ガベージコレクションが無効なので、インスタンス(オブジェクト)のライフ期間をつねに意識しておく必要があります。 NSString *path = [[NSBundle mainBundle] pathForResource:@"button5" ofType:@"wav"]; NSURL *url = [NSURL fileURLWithPath:path]; 上のコードでは、「path」、「[NSBundle mainBundle]」、「url」と、3つのインスタンスを生成していますが、いずれもautoreleaseが暗黙にセットされているので、適宜開放されます。が、「init~」で始まる初期化メソッドでインスタンスを生成すると、「暗黙のautorelease」はきかないので、「release」か「autorelease」を呼ばないと、開放されません。 今回のプログラムでは、インターフェイス部に、インスタンス変数として、すべての音声のインスタンスを宣言しておき、「viewDidLoad」メソッド内で、すべての音声のインスタンスを生成し、「dealloc」メソッド内で開放してやるのが、適切であろうと思います。

関連するQ&A

  • iPhone開発について

    初歩的な質問ですが、お願い致します。 ボタンをタップで音が鳴り、再びタップで音を止めるという動きを AVAudioPlayerを利用し実装したいと考えておりますがストップが思い通りに動きません。 プレイは正常に動作しております。 xCode4 で xib を利用しております。 該当部分だけコードを以下に抜粋させていただきます。 hogeController.m - (IBAction)btn{ NSString *path = [[NSBundle mainBundle] pathForResource:@"hoge" ofType:@"mp3"]; NSURL *url = [NSURL fileURLWithPath:path]; AVAudioPlayer *oto = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; if (hogeFlg == NO){ hogeFlg = YES; [oto play]; }else{ hogeFlg = NO; [oto stop]; } } デバッグでは、2回目のタップで、[oto stop];は通過しております。 基本的なところが理解できていないためということはわかっているのですが、解決策がわかりません。 また、xib を利用しておりますので、起動時に、- (void)viewDidload を読み込むのかな? と思い、入れてみたのですが通っておりません。 本当は、ここでセットして、ボタンタップじでは、再生と停止の処理だけを入れたいのですが、そういうことは可能なのでしょうか。 どうぞ、よろしくお願い致します。

  • xcodeの音を鳴らすのを遅らせる方法

    xcodeで音を鳴らしたいんですけど、 ボタンを押して数秒したら音が鳴るようにしたいんですけどどうしたらいいでしょうか? ループさせるので音源の最初を空白にするわけにはいきません。 あとAVAudioPlayerを使ったやり方だと助かります。 NSString *bgmPath = [[NSBundle mainBundle] pathForResource:@"music"ofType:@"mp3"]; NSURL *bgmUrl = [NSURL fileURLWithPath:bgmPath]; sound = [[AVAudioPlayer alloc] initWithContentsOfURL:bgmUrl error:nil]; [sound setNumberOfLoops:0]; //ここに指定した時間遅らせるというのを入れたい// [sound play]; どうかよろしくお願いします。

  • iPhoneアプリの開発についてです。

    ウェブサイトをローカルに保存しオフラインでUIWebViewに表示したいです。 http://blog.livedoor.jp/sionami/archives/3551091.htmlのサイトを参考にし実行してみましたが、オフラインでは表示されませんでした。また、表示されたサイトは(オンライン時)スマートフォン向けだったページがPC版の表示で表示されました。 以下が実行したプログラムです。コードの一部が間違っているのでしょうか。それともやり方そのものが間違っているのでしょうか。ご指摘お願いします。(エラー時のプログラムは省略しました) NSString *filePath; - (void)downloadHTML:(NSString *)html { NSString *directoryPath = [NSHomeDirectory() stringByAppendingPathComponent:@"tmp"]; //ダウンロードファイルの保存先 NSString *fileName = [html lastPathComponent]; filePath = [[directoryPath stringByAppendingPathComponent:fileName] stringByStandardizingPath];//保存したファイルへのパス NSURL *url = [NSURL URLWithString:html]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; NSURLResponse *response = nil; NSError *error = nil; NSData *data = [ NSURLConnection sendSynchronousRequest : request returningResponse : &response error : &error ]; //ファイル書き込み NSFileManager *fm = [NSFileManager defaultManager]; [fm createFileAtPath:filePath contents:[NSData data] attributes:nil]; NSFileHandle *file = [NSFileHandle fileHandleForWritingAtPath:filePath]; [file writeData:data]; } - (IBAction)refresh:(UIButton *)sender { NSString *htmlStr = [NSString stringWithContentsOfFile:filePath]; [_myWebView loadHTMLString:htmlStr baseURL:nil]; } また、http://qiita.com/EntreGulss/items/8da6847e4dae59bfb1ebのサイトの方法も試しましたが同じくオフラインで表示されませんでした。

  • iPhoneアプリ開発 ファイル書き込み

    iPhoneアプリ開発につきまして、質問させて頂きます。 csvファイルへのデータの出力を試みているのですが上手くできません。 プログラムとログ内容を以下に記述しました。 「abc」と予め書いてある「hoge.csv」ファイルに「stringaaaaaaaaaaa」を書き込み保存しておきたいのですが、上手くいきません。 ログ内容を見る限り、「abc」が読み込めているので、パスは合っていると思っています。また、writeToFileをしてから読み込むと「stringaaaaaaaaaaa」が読み込めるため、どこかには書き込めているような気がします。 しかし、毎回同じ処理をしても、最初に読み込まれるのは「abc」です。「hoge.csv」をテキストエディタで読み込んでも表示されるのは「abc」です。 また、iPhoneシミュレーターで実行した結果は以下のログ内容なのですが、iPhone実機で動作させると、writeToFileを行ったあとでも「abc」が出力されます。 何か原因を思い当たる方、教えて頂ければ幸いです。 - (void)viewDidLoad { [super viewDidLoad]; [self setTitle:@"Stress Application"]; printf("viewdidload"); NSString *text = [[NSString alloc] initWithFormat:@"stringaaaaaaaaaaaaaaa"]; NSString *_path = [[NSBundle mainBundle] pathForResource:@"hoge" ofType:@"csv"]; //atomicallyは補助ファイルを使ってファイルの破損を防止するかどうか NSLog(@"%@",[NSString stringWithContentsOfFile:_path encoding:NSUTF8StringEncoding error:nil]); [text writeToFile:_path atomically:YES encoding:NSUTF8StringEncoding error:nil]; NSLog(@"%@",[NSString stringWithContentsOfFile:_path encoding:NSUTF8StringEncoding error:nil]); NSLog(@"%@",text); } <ログ内容> 2012-10-31 12:35:10.187 ThinkGearTouch[17182:1a903] FinishLaunching viewdidload2012-10-31 12:35:10.204 ThinkGearTouch[17182:1a903] abc 2012-10-31 12:35:10.212 ThinkGearTouch[17182:1a903] stringaaaaaaaaaaaaaaa 2012-10-31 12:35:10.212 ThinkGearTouch[17182:1a903] stringaaaaaaaaaaaaaaa

  • NSTimerカウントダウンで音楽を停止するには?

    Xcodeで iPhoneアプリ作りに奮闘している初心者です。 NSTimerでカウントダウンタイマーを設定しましたが、タイマー終了とともに BGM音楽を停止したいのですが、.p ファイルに #import <AVFoundation/AVFoundation.h> と追加して、.m ファイルに タイマー終了時にイベントとして、 if (RestTime == 0) { timeflag = false; NSString *bgmPath = [[NSBundle mainBundle] pathForResource:@"xxxx"ofType:@"mp3" ]; NSURL *bgmUrl = [NSURL fileURLWithPath:bgmPath]; sound = [[AVAudioPlayer alloc] initWithContentsOfURL:bgmUrl error:nil]; [sound setNumberOfLoops:-1]; [sound stop]; とコードをいれてみましたが、タイマーは終了しても音楽は止まらず鳴りっぱなしです。 NSTimer周辺に詳しい方で、カウントダウンタイマー終了と同時に他の作動をとめる設定(プログラムコード)をお知りのかたお助けねがいます。 また、すでに鳴っている(他のページ又は同じページ,controller内の)音楽をタイマーに合わせて止めることが不可能なら、タイマースタートボタンを押すと同時に音楽をスタートし、タイマー終了とともに音楽を停止するプログラムコードを教えていただけたら助かります。 よろしくお願いします。

  • objective-Cについてご相談があります。

    現在objective-cを勉強中なのですが、 jsonについて教えて頂きたい事があります。 jsonのファイル・データ・オブジェクトそれぞれを 取得する必要があると習ったのですが、それらの違いが 今ひとつ分かりません。 下記のような記述なのですが、それぞれの違いをどなたか ご教示頂けないでしょうか。 // 対象Jsonファイル取得 NSBundle *bnd = [NSBundle mainBundle]; NSString *ptn = [bnd pathForResource:@"Test01" ofType:@"json"]; NSURL *url = [NSURL fileURLWithPath:ptn]; // Jsonオブジェクトの取得 NSURLRequest *req =[NSURLRequest requestWithURL:url]; NSData *dat = [NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil]; // Jsonデータの取得 NSDictionary *dick01 = (NSDictionary *) [NSJSONSerialization JSONObjectWithData:dat options:NSJSONReadingMutableContainers error:nil]; 以上、何卒宜しくお願い致します。

  • AVAudioPlayer インスタン

    iPhone の自作アプリで音声に関する場所を作成しているのですが AVAudioPlayerのインスタン作成場所について知りたいことがあります touchesMoved内 もしくは別クラスで音声を再生させる際 [ABC play];の上にコードを書き込み NSString *_ABC = [[NSBundle mainBundle] pathForResource:@"ABC" ofType:@"caf"]; ABC = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:_ABC] error:NULL]; [ABC play]; このようなコードになりました ここで思ったのですが 処理を実行する際、playだけを行ってくれればいいのに 上記コードだと2回目3回目の処理で毎回cafファイルを読み込みインスタンを生成する といった処理内容になってしまうのでしょうか? ツールを使用しメモリ使用率を確認したところAVAudioPlayerで メモリリークしているみたいです ログにはerror = 24 (Too many open files)と表示されます releaseもしていないのでそれも原因と考えられますが複数の音声を同時 もしくはバラバラ、もしくは同じ音声を連続で再生することもあるので releaseをどこに入れたらうまくいくのか理解できていません コードを書き込む位置も含めて簡潔でいいのでアドバイスをいただけるとありがたいです

  • iPhoneのアプリ開発についてお伺い致します。

    Xcodeの実装をお伺いしたいのですが,あるアプリ開発の本を参考にして、クイズアプリをつくりました。クイズの問題、選択肢のデータファイルはテキストファイルでResourceに作成します。問題文をテキストビューに、選択肢をボタンに記載し、選択肢のボタンを押す事で回答させるシステムです。正解のボタンをタップすると、ボタンの文字の先頭に○を、不正解だと×を表示するのですが、これに、不正解時に正解のボタンの先頭に★等の印をつける為のソースコードをご教示いただければ幸いです。因に、テキストファイルには、1行目;問題文、2行目;正解の選択肢、3~5行目;不正解の選択肢、となっております。 //選択肢のボタンがタップされたときの処理 - (IBAction)answer:(id)sender { //正解か不正解かを見せる間、タップできない様に、ボタンを無効表示に変更する。 self.answerButton1.enabled = NO; self.answerButton2.enabled = NO; self.answerButton3.enabled = NO; self.answerButton4.enabled = NO; //タップされたボタンのラベルを取得する NSString *str = [[sender titleLabel] text]; //出題された問題の情報を取得する QuizItem *item = [self.quiz.usedQuizItems lastObject]; //正解か判定する if ([item checkIsRightAnswer:str]) { //正解なので、○を先頭に追加する [sender setTitle:[NSString stringWithFormat:@"○ %@", str] forState:UIControlStateNormal]; //効果音を再生する AudioServicesPlaySystemSound(_rightSound); } else { //不正解なので×を先頭に追加する [sender setTitle:[NSString stringWithFormat:@"× %@", str] forState:UIControlStateNormal]; }

    • 締切済み
    • Mac
  • iPhoneのアプリ開発についてお伺い致します。

    Xcodeの実装をお伺いしたいのですが,あるアプリ開発の本を参考にして、クイズアプリをつくりました。クイズの問題、選択肢のデータファイルはテキストファイルでResourceに作成します。問題文をテキストビューに、選択肢をボタンに記載し、選択肢のボタンを押す事で回答させるシステムです。正解のボタンをタップすると、ボタンの文字の先頭に○を、不正解だと×を表示するのですが、これに、不正解時に正解のボタンの先頭に★等の印をつける為のソースコードをご教示いただければ幸いです。因に、テキストファイルには、1行目;問題文、2行目;正解の選択肢、3~5行目;不正解の選択肢、となっております。 //選択肢のボタンがタップされたときの処理 - (IBAction)answer:(id)sender { //正解か不正解かを見せる間、タップできない様に、ボタンを無効表示に変更する。 self.answerButton1.enabled = NO; self.answerButton2.enabled = NO; self.answerButton3.enabled = NO; self.answerButton4.enabled = NO; //タップされたボタンのラベルを取得する NSString *str = [[sender titleLabel] text]; //出題された問題の情報を取得する QuizItem *item = [self.quiz.usedQuizItems lastObject]; //正解か判定する if ([item checkIsRightAnswer:str]) { //正解なので、○を先頭に追加する [sender setTitle:[NSString stringWithFormat:@"○ %@", str] forState:UIControlStateNormal]; //効果音を再生する AudioServicesPlaySystemSound(_rightSound); } else { //不正解なので×を先頭に追加する [sender setTitle:[NSString stringWithFormat:@"× %@", str] forState:UIControlStateNormal]; }

  • iphoneアプリ開発での変数の受け渡し

    最近iPhoneアプリ開発を始めた者です。 変数の受け渡しについて質問があり、投稿させていただきました。 以下のコード内で、 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 以下で設定したIDに入ったデータを、 -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)senderの中のIDに受け渡したいのですが、どうやら2つのIDが繋がっていません。 自分自身あまりまだ理解できていないこともあり、ざっくりとした聞き方で申し訳ありません。 初歩的な質問だとは思うのですが、なにとぞご教授お願いします。 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 2; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if(cell == nil){ cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } if (indexPath.row == 0){ cell.textLabel.text = @"東京"; }else{ cell.textLabel.text = @"大阪"; } int ID = indexPath.row; return cell; } -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [self performSegueWithIdentifier:@"mySegue" sender:self]; } -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"mySegue"]) { SecondTableViewController *viewCon = segue.destinationViewController; viewCon.myValue = ID; } }

専門家に質問してみよう