1

私の問題は、コントローラー(たまたま私のrootViewController)から別のビューに情報を取得することです。アプリデリゲートを介してアクセスしようとしても、機能させることができませんでした。これを行う方法を見つけましたが、このインターンにより、モーダルビューコントローラー内のビューを実際にデータを表示するという別の問題が発生しました。以下に、appDelegate 情報と、支援が必要な場合に備えて NSMutable Dictionary ソリューション コードの両方を投稿しました。

私はこの問題を自分で解決するために1週間以上試みました. 私の問題は、appDelegate にアクセスする方法でした。そのため、NSDictionary に問題がありました。結局、問題は NSDictionary ではありませんでした。

まず、私がプログラミングをやり過ぎていることに気づき、正しい方向に向けてくれた TechZen に感謝します。

これが私が学んだことです。

appDelegate で変数を割り当てます。

AppDelegate.h

 @interface AppDelegate : NSObject  < UIApplicationDelegate, UINavigationControllerDelegate >
{   
    UIWindow *window;
    UINavigationController *navController;

    // Array to store the Makers Objects
    NSMutableArray *makers;

}

@property (nonatomic, retain) IBOutlet UIWindow *window; 
@property (nonatomic, retain) IBOutlet UINavigationController *navController;

@property (retain, nonatomic) NSMutableArray *makers;
@end

AppDelegate.m

    - (void)applicationDidFinishLaunching:(UIApplication *)application 
{

    makers = [[NSMutableArray alloc] init] ;
}

ViewController.m で、変数を appDelegate に割り当てます。これは、tableView 関数の didSelectRowAtIndexPath 内で行いました。

        AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

// The line below loads it into the variable, the one above takes it and makes it available for other view Controllers.

       Maker *maker = (Maker *)[appDelegate.makers objectAtIndex:indexPath.row];

// the combination of the above and below also loads the information into another array in this view controller, defined in an NSObject Controller called Maker (.h and .m files)

      maker = [self.Makers objectAtIndex:indexPath.row];

ビューコントローラーで、appDelegate から変数をロードしたいので、次のように設定します。

#import <UIKit/UIKit.h>

#import "AppDelegate.h"
#import "Maker.h"

@class AppDelegate;

@interface DetailsViewController : UIViewController
{

        AppDelegate *dappDelegate;
    DetailsViewController *detailsView;

    IBOutlet UITextView *makerDescription;

}

@property (retain, nonatomic) AppDelegate *dappDelegate;

@property (nonatomic, retain) DetailsViewController *detailsView; 

@property (nonatomic, retain) IBOutlet UITextView *makerDescription;

@end

およびviewController.mファイル内。

#import "DetailsViewController.h"
#import "AppDelegate.h"

@synthesize dappDelegate;

- (void)viewWillAppear:(BOOL)animated // or ViewDidLoad not sure which is better.

    dappDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
    NSString *newLocalVariable = [dappDelegate.makers description];

NSLog(@"newLocalVariable: %@", [dappDelegate.makers description]);
// This is for verifying you have it loaded. 'description' is defined in the Maker NSObject, see below for those files, and above for where it was assigned originally

.....そして、あなたが今欲しいものにそれを割り当ててください!

これがすべての人に役立つことを願っています。この時点で、そこから NSArray を NSDictionary にドロップできますが、アクセスはキーと値を使用するようになったため、この時点でのアクセスは少し複雑になりますが、もちろん利点があります。私はまだそれを完全にダウンさせることはできず、そのメソッドから離れて、今のところ NSArray を使用するだけです。

以下は、Maker の h および m ファイルのサンプルです。

Maker.h

@interface Maker : NSObject 
{
    NSString *name;
    NSString *address;
    NSString *city;
    NSString *postalcode;
    NSString *country;
    NSString *phonenumber;
    NSString *email;
    NSString *description;
    NSString *services;
    NSString *website;
}

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *address;
@property (nonatomic, copy) NSString *city;
@property (nonatomic, copy) NSString *postalcode;
@property (nonatomic, copy) NSString *country;
@property (nonatomic, copy) NSString *phonenumber;
@property (nonatomic, copy) NSString *email;
@property (nonatomic, copy) NSString *description;
@property (nonatomic, copy) NSString *services;
@property (nonatomic, copy) NSString *website;

- (id)initWithName:(NSString *)n address:(NSString *)a city:(NSString *)c postalcode:(NSString *)z country:(NSString *)o phonenumber:(NSString *)p email:(NSString *)e description:(NSString *)d services:(NSString *)s website:(NSString *)w;

@end

およびその Maker.m ファイル。

#import "ViolinMaker.h"

@implementation Maker
@synthesize name, address, city, postalcode, country, phonenumber, email, description, services, website;

- (id)initWithName:(NSString *)n address:(NSString *)a city:(NSString *)c postalcode:(NSString *)z country:(NSString *)o phonenumber:(NSString *)p email:(NSString *)e description:(NSString *)d services:(NSString *)s website:(NSString *)w; 
{
    self.name = n;
    self.address = a;
    self.city = c;
    self.postalcode = z;
    self.country = o;
    self.phonenumber = p;
    self.email = e;
    self.description = d;
    self.services = s;
    self.website = w;
    return self;
}
@end

私は本当に多くの時間を費やしたので、これが他の人がこれを理解するのに役立つことを願っています.

カーク

4

1 に答える 1

2

アプリデリゲートの`selectedMaker'からのデータをselectedMakerivarに入力するポイントはありません。DetailsViewController同じ名前だからといって、同じデータを共有しているわけではありません。

アプリデリゲートからViewControllerに値を割り当てるかコピーする必要があります。迅速で汚い方法は、次のようなことを行うことです。

@implementation DetailsViewController

...

-(void) viewDidLoad{
//selectedMaker=[[UIApplication sharedApplication] selectedMaker]; <-- this is wrong
//Edit, this is the correct call to app delegate
selectedMaker=[[[UIApplication sharedApplication] delegate] selectedMaker]; 
}

Edit01:

だから...TechZenの提案で、私はNSDictionaryをRootViewControllerから移動しようとしました。

(1)なぜあなたがSelectedMakerそれが成し遂げるべきことのクラスを持っているのか分かりません。クラスを。と混同しているようですNSMutableDictionary。クラスには、それ自体のiVarの値を含むディクショナリを返す明確な理由はありません。これは完全に冗長です。ViolinMaker各バイオリンメーカーのレコードのすべてのデータをカプセル化するというクラスがすでにあるようです。

(2)の初期化メソッドSelectedMakerが正しく実装されていません。電話をかける-[SelectedMaker initWithsName:..]前に電話をかけなければならないようです-[SelectedMaker init]。そうしないと、initにはキーが何であるかわかりません。

(3)いずれの場合も、didSelectRowメソッドでは、のインスタンスを実際に初期化することはありません SelectedMaker。この行:

SelectedMaker *selectedMaker = [[[NSMutableDictionary alloc]retain] initWithObjects: objects forKeys: keys];

のインスタンスを作成するのではSelectedMakerなく、NSMutableDictionary多かれ少なかれそれをSelectedMakerクラスにキャストします。これが、forループからコンパイラ警告を受け取る理由です。

SelectedMaker(4)授業の必要性は全くないと思います。これらの行:

ViolinMakerAppDelegate *appDelegate = (ViolinMakerAppDelegate *)[[UIApplication sharedApplication] delegate];
ViolinMaker *violinMaker = (ViolinMaker *)[appDelegate.violinMakers objectAtIndex:indexPath.row];
violinMaker = [self.filteredViolinMakers objectAtIndex:indexPath.row];

テーブルまたは詳細ビューの特定の行に入力するために必要なすべての情報を提供するように見えます。これらの3行は、バイオリンメーカーのデータにアクセスする必要がある任意のビューで使用できますappDelegate.violinMakers'. The。`オブジェクトには、必要なすべてのデータが含まれています。

あなたはこれを必要以上に複雑にしていると思います。必要なのは(A)SQLからフェッチされた各レコードのデータをカプセル化するクラスです。この場合、ViolinMakerがこれを行っているように見えます。(B)複数のViolinMakerインスタンスを保存するには、アプリデリゲートに配列(または他のコレクション)が必要です。(C)ビューコントローラーが必要なViolinMakerインスタンスを選択できるように、アプリデリゲートの配列/コレクションにアクセスする各ビューコントローラーのコードが必要です。

Edit02:

'objectAtIndex:indexPath.row'はdidSelectRow関数内でのみ使用できるため、これらの3行は使用できません。つまり、テーブルとそのすべてのデータを再構築する必要があります。

辞書をアプリデリゲートのインスタンス変数として一度定義するだけです。したがって、各値がViolinMakerあり、各キーが名前などのバイオリン製作者の属性である可変辞書があります。それを呼び出しましょうviolinMakersDict。次に、アプリのどこからでも、最初にアプリデリゲートを呼び出し、violinMakersDictにアクセスすることで辞書にアクセスします。

テーブルにデータを入力するには、いくつかの値を配列として抽出する必要があります。ほとんどの場合、あなたはバイオリン製作者の名前である鍵を取ります。次に、配列をアルファベット順に並べ替えてから、各行にindex.row値の配列の値を入力します。

同様に、あるビューにデータを追加する必要がある場合は、に書き込みを行ってviolinMakersDictから、アプリデリゲートを再度呼び出すことで別のビューからそのデータにアクセスできます。

于 2009-11-24T14:46:45.130 に答える