ページ 11

健史

Posted: 2010年9月02日(木) 21:54
by iPhoneアプリ開発 CSVの読み込み
iPhoneで動くアプリを開発しております。
CSVからデータを読み込みテーブルビューに表示するといった簡単なプログラムを作りたいです。
画面下のタブビューを切り替えるとテーブルビューに表示されているものがソートされるようにしたいです。
例)キー2タブが押されたら2項目目を中心にソート

CSVは何とか読み込めたのですが表示しようとすると問題が発生してしまいます。
if( indexPath.row == 0 ) cell.textLabel.text = @"aaa";//[[items objectAtIndex:0] objectAtIndex:0] ;
コメントのほうを使うとスクロール時に強制終了してしまいます。

また、タブバーが2つ表示されてしまっており困っております。
タブを押した時にどこにソートするといったイベントを書けばよいのかもわかりません。
C言語は1年程度いじってきたのですが新しい環境での開発のためあまりなれておりません。

こちらはゲームを作るための掲示板とは思いますが
どなたかお分かりになる方はいらっしゃらないでしょうか?

またこのアプリは販売する予定などはありません。
完全に自分用に作っております。

Re:健史

Posted: 2010年9月03日(金) 01:16
by たかぎ
TitleとNameが逆になっていませんか?

Re:健史

Posted: 2010年9月03日(金) 01:38
by Justy
>スクロール時に強制終了してしまいます
 んー、RootViewControllerの
[color=#d0d0ff" face="monospace]
items = [NSMutableArray array];
[/color]

[color=#d0d0ff" face="monospace]
items = [[NSMutableArray alloc] init];
[/color]
にしたらどうなりますか?


>また、タブバーが2つ表示されてしまっており困っております
 2つというのは上下に、ということですか?
 
 それならそうです。
[color=#d0d0ff" face="monospace]
self.tabBarController.viewControllers = [NSArray arrayWithObjects:tab1,tab2,tab3,ni[/url];
[/color]

 この行でやっていることはタブの中のボタンを設定しているのではなく、
それぞれのタブを押したときに表示されるそれぞれのタブに対応した ViewControllerを指定しています。

 このコードですと対応したタブを押す毎に tab1などが表示されるというわけです……おかしいですよね。
 この NSArrayには RootViewControllerなどの ViewControllerを入れるのが正しい挙動では
ないかと思います。

 タブのボタン名はそれぞれで表示される ViewControllerの initメンバ関数の中で self.tabBarItemに対して
オブジェクトを割り当てて指定して下さい。


>タブを押した時にどこにソートするといった
 どこで、ということなら testAppDelegateクラスに UITabBarControllerDelegateプロトコルを追加、
didSelectViewController関数を書けばタブを押したときに呼ばれるようになります。

Re:健史

Posted: 2010年9月03日(金) 02:56
by 健史
すみません。タイトルと質問が逆になっておりました。
不快になった方がおりましたら申し訳ございません。



お分かりになる方がいましたか!!
ありがとうございます。

1つ目の問題は修正できました。
初期化が原因だったのですね・・・。
objective-cは厄介ですね。

2つ目の問題について
ビューを3つ用意しなければいけないということなのでしょうか?
これからの為にもIBを出来れば使いたくないのですが手書きでの実装は難しいのでしょうか?

3つ目の問題について
自分なりに追加してみたのですが添付したソースであっておりますでしょうか?
また別のソースで定義しているitemsをソートしたいのですがextern的なことは出来ないのでしょうか?

Re:健史

Posted: 2010年9月04日(土) 00:07
by Justy
>ビューを3つ用意しなければいけないということなのでしょうか?
 だと思いますよ。
 同じ ViewControllerを指定してもうまくはいかないと思いますし。

 タブでうまくやるには下の階層にRootViewControllerをおいてリストを表示し、
その上にタブをおき、そのタブは3つの空のビューコントローラーをセットしておきます。
 後はタブの切り替わりを検知したらリストを持つRootViewControllerにソートの指示を出せばいいのでは
ないでしょうか。

 或いはタブをすっぱり諦めて別の手にするのもいいのかもしれません。
・ タブでの実装を止めて、画面に下にツールバーをおいて、その上に幾つかボタンを作成します。
 そのボタンが押されたら、ソートを切り替える
・ 1つだけボタンをおいて、順繰りにソート方式を切り替える
・ 頻繁にソートしないのであれば、アクションシートを出して選ばせる
とか。


>これからの為にもIBを出来れば使いたくないのですが手書きでの実装は難しいのでしょうか
 難しいというより面倒なだけです。
 まぁIBに慣れてしまうといろいろ弊害もあるでしょうから、両方使えるようにしておくのがベストかと。


>自分なりに追加してみたのですが添付したソースであっておりますでしょうか?
 合ってるかどうか訊く前に試しましたか?
 tabBarController.delegateが接続されていないので、タブがセレクトされても呼び出されないと思います。


>また別のソースで定義しているitemsをソートしたいのですがextern的なことは出来ないのでしょうか?
 itemsがグローバル変数ならできますよ、externで。
 メンバであるなら、そのメンバを返すようなプロパティなりメンバ関数なりを作って渡せばいいかと。

 今のファイル構成で考えるなら、設計的には itemsを(csvから読み込んで)生成するクラスを新規で作って
それを testAppDelegateのメンバとしてオブジェクトを作った後、RootViewControllerに引き渡せばいいかと。

無題

Posted: 2010年9月06日(月) 16:25
by 健史
返信が遅れてしまいすみません。
頂いたアドバイスを元に修正してみます。
多分、また質問をしてしまうかと思いますが何卒よろしくお願いいたします。

Re:無題

Posted: 2010年9月06日(月) 17:05
by 健史
自分なりにCSV読み込み用のクラスを作ってみたのですが
戻り値をのNSMutableArray型にしてしまうとエラーになってしまう為実装できません。
////.h

#import <UIKit/UIKit.h>

@interface csvLoad : NSObject {

}

-(void)Load:(NSString*)path;


@end

/////.m
#import "csvLoad.h"

@implementation csvLoad

-(void)Load:(NSString*)path{
    
    NSError* error = nil;
    int enc = NSUTF8StringEncoding;
    NSString* text = [NSString stringWithContentsOfFile:path encoding:enc error:&erro[/url];
    
    // ファイルの分割
    NSArray* lines = [text componentsSeparatedByString:@"\n"];
    NSMutableArray* items;
    
    items = [[NSMutableArray alloc] init];
    for(int i=0; i<[lines count]; i++){ 
        [items addObject:[[lines objectAtIndex:i] componentsSeparatedByString:@","]]; 
    }
}

@end
質問ばかりで申し訳ないです・・・。

Re:無題

Posted: 2010年9月06日(月) 21:16
by Justy
>戻り値をのNSMutableArray型にしてしまうとエラーになってしまう為実装できません
 具体的に、どこで何のエラーが出るのですか?

Re:無題

Posted: 2010年9月07日(火) 00:25
by 健史
-(void)Load:(NSString*)path;

-(NSMutableArray)Load:(NSString*)path;
と書いてしまうと
キャンノットパーマネントとでてしまいます。
書き方が悪いのでしょうか?

Re:無題

Posted: 2010年9月07日(火) 01:07
by Justy
 NSMutableArray *じゃないですか?

Re:無題

Posted: 2010年9月08日(水) 03:50
by 健史
回答ありがとうございます。
そのように変更したら問題なく動きました・・・。
ありがとうございます。

>>今のファイル構成で考えるなら、設計的には itemsを(csvから読み込んで)生成するクラスを新規で作って
それを testAppDelegateのメンバとしてオブジェクトを作った後、RootViewControllerに引き渡せばいいかと。
アドバイスを頂いた上記のように作ってみようと思っております。
何とかRootViewControllerに値を渡す専用の関数を作ってみました。

testAppDelegateを編集したいのですが
・どのようにオブジェクトを作るのか
・Rootへの引き渡し方
がわかりません。
何度も質問ばかりで申し訳ないです。

クラスを理解しろと言われそうな質問で申し訳ないです。
クラスについては簡単なゲーム関連なら実装できる程度しか理解しておりません。

Re:無題

Posted: 2010年9月09日(木) 01:50
by Justy
 結局、タブ周りの設計はどうしたんでしょう?


>何とかRootViewControllerに値を渡す専用の関数を作ってみました。
 csvLoadの Loadメソッドで allocした itemsはどこで解放していますか?
 
 RootViewController側の itemSetも問題があります。
 今のコードですと itemsが既にセットされていた場合、下記のように itemsを解放しておかないと
リークします。
[color=#d0d0ff" face="monospace]
-(void)itemSet:(NSMutableArray*)srcItems
{
if(items == srcItems)
return;

[items release];
items = [srcItems copy]
}
[/color]



>どのようにオブジェクトを作るのか
 ??
 普通は alloc / initを呼んで作ります。
 例えば今の csvLoadなら
[color=#d0d0ff" face="monospace] csvLoad *csv = [[csvLoad alloc] init];
[/color]
とか
[color=#d0d0ff" face="monospace] rootViewController = [[[RootViewController alloc] init];
[/color]
とか。
 他にもクラスメソッドによる autorelease付きの生成方法もあったりしますので、そのあたりは
解説本などを参考にして下さい。


>Rootへの引き渡し方
 その為に itemSetを作ったんですよね?
[color=#d0d0ff" face="monospace] [rootViewController itemSet: xxxx];
[/color]
です。

Re:無題

Posted: 2010年9月13日(月) 11:34
by 健史
過去ログに入ってしまった為、別スレにて質問させて下さい。
Justy様、たかぎ様ありがとうございました。