1

@TXによって解決されます。コード内の「//SOLUTION」で変更をマークしました!!!

次の問題があります。presentModalViewControllerを使用すると、NSMutableArray"projectsArray"がリセットされます。

これが私のコードです:

ここに.hファイルがあります:

    // ViewController.h
#import <UIKit/UIKit.h>

@class AddProject;

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
    IBOutlet UITableView *projectsTableView;
    UIAlertView *reallyDelete;

    BOOL candelButtonClicked;
    NSIndexPath *actualIndexPath;

    NSMutableArray *projectsArray;
    NSInteger ID;
    NSString *NAME;

    AddProject *addProject;
    **ViewController *viewContr; // SOLUTION**
}
- (IBAction)addNewProject:(id)sender;

- (void)addToTableView:(NSString *)projectName;

@property (nonatomic, retain) UIAlertView *reallyDelete;
@property (nonatomic) NSInteger cancelButtonIndex;

@property IBOutlet UITableView *projectsTableView;

@property (nonatomic, retain) AddProject *addProject;
**@property (nonatomic, retain) ViewController *viewContr; // SOLUTION**

@end

ここに.mファイルがあります:

    // ViewController.m
#import "ViewController.h"
#import "CustomTableCell.h"
#import "AddProject.h"

@interface ViewController ()

@end

@implementation ViewController

**@synthesize viewContr; // SOLUTION**

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    projectsArray = [[NSMutableArray alloc] init];
    ViewController *element = [[ViewController alloc] init];

    element->ID = 1;
    element->NAME = @"Demo project";
    NSLog(@"viewdidload");
    [projectsArray addObject:element];

    NSLog(@"1. Array length: %d", [projectsArray count]);
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if ([projectsArray count] < 1) {
        NSLog(@"2. Array length: 0");
        return 0;
    } else {
        NSLog(@"2. Array length: %d", [projectsArray count]);
        return [projectsArray count];
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 78;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *customTableCellIdentifier = @"CustomTableCell";

    CustomTableCell *cell = (CustomTableCell *)[tableView dequeueReusableCellWithIdentifier:customTableCellIdentifier];
    if (cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomTableCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }

    ViewController *element = [[ViewController alloc] init];
    element = [projectsArray objectAtIndex:indexPath.row];
    cell.nameLabel.text = element->NAME;
    cell.prepTimeLabel.text = [NSString stringWithFormat:@"%i", element->ID];

    NSLog(@"3. Array length: %d", [projectsArray count]);

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source

        reallyDelete = [[UIAlertView alloc] initWithTitle:@"Deleting" message:@"Do your really want to delete that row?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes", nil];
        [reallyDelete show];

        actualIndexPath = indexPath;
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {

    if (buttonIndex != [reallyDelete cancelButtonIndex])
    {
        //If "Yes" clicked delete
        [projectsArray removeObjectAtIndex:actualIndexPath.row];
        NSLog(@"delete row");

        [self.projectsTableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObjects:actualIndexPath, nil] withRowAnimation:YES];
        [self.projectsTableView reloadData];
    }
}

#pragma mark Edit

- (IBAction)addNewProject:(id)sender {
    NSLog(@"4. Array length: %d", [projectsArray count]);

    AddProject *addProjectView = [[AddProject alloc] initWithNibName:@"AddProject" bundle:nil];
    NSLog(@"4.1 Array length: %d", [projectsArray count]);
    addProjectView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    NSLog(@"4.2 Array length: %d", [projectsArray count]);
    addProjectView.modalPresentationStyle = UIModalPresentationFormSheet;
    NSLog(@"4.3 Array length: %d", [projectsArray count]);
    **addProjectView.viewContr = self; // SOLUTION**
    [self presentModalViewController:addProjectView animated:YES];
    NSLog(@"4.4 Array length: %d", [projectsArray count]);
    addProjectView.view.superview.frame = CGRectMake(addProjectView.view.center.x/2.5, addProjectView.view.center.y/3, 800, 600);
    NSLog(@"4.5 Array length: %d", [projectsArray count]);
}

- (void)addToTableView:(NSString *)projectName
{
    NSLog(@"Project Array: %@", projectsArray);
    NSLog(@"addToTableView: %@", projectName);    
    NSLog(@"5. Array length: %d", [projectsArray count]);

    ViewController *element = [[ViewController alloc] init];

    element->ID = 2;
    element->NAME = projectName;

    [projectsArray addObject:element];

    NSLog(@"6. Array length: %d", [projectsArray count]);

    [self.projectsTableView reloadData];
    [self.projectsTableView setNeedsDisplay];
}

- (void)viewDidUnload
{
    [self setProjectsTableView:nil];
    self.projectsTableView = nil;
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

@end

ここに、モーダル表示ビューの.hファイルがあります。

    // AddProject.h
#import <UIKit/UIKit.h>

@class ViewController;

@interface AddProject : UIViewController
{    
    IBOutlet UITextField *projectName;

    ViewController *viewContr;
}

- (IBAction)back:(id)sender;
- (IBAction)next:(id)sender;

@property (nonatomic, retain) ViewController *viewContr;

@end

モーダル提示ファイルの.mファイル:

    // AddProject.m
#import "AddProject.h"
#import "ViewController.h"

@interface AddProject ()

@end

@implementation AddProject

**@synthesize viewContr; // SOLUTION I've mist to synthesize it**

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    **// SOLUTION no new allocation/init of ViewController**
}

- (IBAction)back:(id)sender
{
    [self dismissModalViewControllerAnimated:YES];
}

- (IBAction)next:(id)sender
{
    [viewContr addToTableView:projectName.text];
    [viewContr.projectsTableView reloadData];
    [viewContr.projectsTableView setNeedsDisplay];
    [self dismissModalViewControllerAnimated:YES];
}

- (void)viewDidUnload
{
    projectName = nil;
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

@end

ブレークポイントを使用してコードをテストしましたが、AddProjectクラス「viewDidLoad」の読み込みが開始されたときに問題を見つけることができました。しかし、なぜそれがアレイをリセットするのかわかりません。

4

3 に答える 3

1

projectsArrayは、viewDidLoadではなく、ViewControllerのinitメソッドに割り当てる必要があります。projectsArray = [[NSMutableArray alloc] init];ビューがロードされるときに、新しい空の配列が割り当てられました。

于 2012-08-25T12:24:05.213 に答える
1

ViewController画面から画面に移動しAdd projectます。Add ProjectScreenで、新しいプロジェクトを追加し、この情報を元のScreenに委任しますViewController

ここで、メソッドで新たにインスタンス化したのインスタンスを作成しようとしていますViewController。プロジェクトが追加されたら、それを呼び出して情報を提供します。これは機能しません。-割り当てたインスタンスは新しいインスタンスであり、移動元のインスタンスではありません。あなたがそうするとき、あなたは新しいオブジェクトを手に入れます。したがって、で呼び出されても、このメッセージを受信して​​いるインスタンスは新しいインスタンスであり、移動元のインスタンスではないため、機能しません。AddProjectviewDidLoad- (void)addToTableView:(NSString *)projectNameViewControlleralloc + initaddToTableView:ViewControllerViewController

したがって、あなたがする必要があるのは-あなたがナビゲートする前にあなたが設定するであろうViewControllerあなたの中にプロパティを持っていることだけです。Add Projectそして、このプロパティにメッセージを送信できます-このトランスクリプトで説明されているように。

言いたいのですが、これは機能しますが、2つのコントローラー間の緊密な結合を提供します。

理想的には、この杖は、 (ナビゲートする場所ViewController)の代理人としてAdd Project(ナビゲートする場所)を作成することによって実行されます。そしてAdd Project、追加されたプロジェクトをのようなものによってそのデリゲートに委任することができ- (void) addProjectController:(AddProjectViewController *) controller didAddProject:(NSString *) projectNameます。これにより、2つのViewController間の結合が失われます。委任の概念を理解するには、委任とデータソースを参照してください。または、他のStackオーバーフロー投稿を検索します。

于 2012-08-25T16:25:53.403 に答える
0

さて、私の問題はstackoverflowチャットで修正されました。最終的な解決策のヒントは、ユーザー@TXから提供されました。質問のコードにヒントを追加しました。それらは「//SOLUTION」でマークされています。

Add Project ViewコントローラーのviewDidLoadメソッドで、行を削除します viewContr = [[ViewController alloc] init];viewContr次に、ViewControllerクラスの変数 をプロパティにします。また、それを合成します。そして最後に、- (IBAction)addNewProject:(id)senderメソッドで、コントローラーを提示する前に、を実行します- addProjectView.viewContr = self;。それはあなたの問題を解決します。

chat.stackoverflowからの引用| @TX

于 2012-08-25T12:46:44.607 に答える