0

私は2つのView Controllerを持っています。CardWallet ビュー コントローラーは、私のテーブル ビューです。次に、AddCard ビュー コントローラーに、Card という名前のオブジェクトの新しいインスタンスの値を入力します。これまでのところ、デリゲートを使用して CardWallet View Controller にある myWallet という名前の配列にこれらの Card インスタンスを追加していますが、機能します。

私が欲しいのは、AddCard ビュー コントローラーのボタンをクリックした後、カードの最近追加されたインスタンスに応じた名前で、新しいテーブル セルがカード ウォレット ビューに表示されることです。以下は私のコードです。 Card の新しいインスタンスの追加が完了したときに、テーブルに何も表示されない理由を確認してください。私はいくつかの調査を行い、いくつかのチュートリアルを実行しました。これは良いものです。 . ただし、チュートリアルは、テーブルの値が静的な値を持つ配列からのみ取得されるため、私の主な関心事には対応していません。

ありがとう!

CardWalletViewController.h

#import <UIKit/UIKit.h>

@interface CardWalletViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {

}

@property (nonatomic, strong) NSMutableArray *myWallet;

-(void) printArrayContents;
@end

CardWalletViewController.m

#import "CardWalletViewController.h"
#import "AddCardViewController.h"
#import "Card.h"

@interface CardWalletViewController () <AddCardDelegate>

@end

@implementation CardWalletViewController


@synthesize myWallet = _myWallet;

- (NSMutableArray *) myWallet
{
    if (_myWallet == nil) _myWallet = [[NSMutableArray alloc] init]; 
    return _myWallet;
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"showAddCardVC"]) {
        AddCardViewController *addCardVC = (AddCardViewController *)segue.destinationViewController;

        addCardVC.delegate = self;

    }
}

- (void)printArrayContents 
{
    // I want to show the name of each instance of card

    for ( int i = 0; i < self.myWallet.count; i++) {
        Card *cardDummy = [self.myWallet objectAtIndex:i];
        NSLog(@"Element %i is %@", i,cardDummy.name );
    }

}

- (void)addCardViewController:(AddCardViewController *)sender didCreateCard:(Card *)newCard
{
    // insert a new card to the array

    [self.myWallet addObject:newCard];

    [self printArrayContents];
}





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

- (void)viewDidUnload
{
  // Release any retained subviews of the main view.
}

- (void)viewWillAppear:(BOOL)animated 
{

}

- (void)viewWillDisappear:(BOOL)animated
{

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    //this method will return the number of rows to be shown

    return self.myWallet.count;   
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

    }
    // Configure the cell...

    //---------- CELL BACKGROUND IMAGE -----------------------------
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:cell.frame];
    UIImage *image = [UIImage imageNamed:@"LightGrey.png"];
    imageView.image = image;
    cell.backgroundView = imageView;
    [[cell textLabel] setBackgroundColor:[UIColor clearColor]];
    [[cell detailTextLabel] setBackgroundColor:[UIColor clearColor]]; 


    //this will show the name of the card instances stored in the array

    //

    for ( int i = 0; i < self.myWallet.count; i++) {
        Card *cardDummy = [self.myWallet objectAtIndex:i];
        cell.textLabel.text = cardDummy.name;
    }

    //Arrow 
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    return cell;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

@end

AddCardViewController.h

#import <UIKit/UIKit.h>
#import "Card.h"

@class AddCardViewController;

@protocol AddCardDelegate <NSObject>

- (void)addCardViewController:(AddCardViewController *)sender
                didCreateCard:(Card *) newCard;

@end


@interface AddCardViewController : UIViewController <UITextFieldDelegate>


@property (strong, nonatomic) IBOutlet UITextField *cardNameTextField;
@property (strong, nonatomic) IBOutlet UITextField *pinTextField;
@property (strong, nonatomic) IBOutlet UITextField *pointsTextField;

@property (nonatomic, strong) id <AddCardDelegate> delegate;

@end

AddCardViewController.m

#import "AddCardViewController.h"
#import "Card.h"
#import "CardWalletViewController.h"

@interface AddCardViewController ()

@end

@implementation AddCardViewController 

@synthesize cardNameTextField = _cardNameTextField;
@synthesize pinTextField = _pinTextField;
@synthesize pointsTextField = _pointsTextField;

@synthesize delegate = _delegate;

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

- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.cardNameTextField becomeFirstResponder];
}

- (void) viewWillDisappear:(BOOL)animated
{

}

- (BOOL) textFieldShouldReturn:(UITextField *)textField{

    if ([textField.text length]) {
    [self.cardNameTextField resignFirstResponder];

    [self.pinTextField resignFirstResponder];

    [self.pointsTextField resignFirstResponder];

    return YES;
    }

    else {
        return NO;
    }
}

- (void)viewDidLoad
{
    self.cardNameTextField.delegate = self;
    self.pinTextField.delegate = self;
    self.pointsTextField.delegate = self;
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

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

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

- (IBAction)addCard:(id)sender 
{
    Card *myNewCard = [[Card alloc] init];

    myNewCard.name = self.cardNameTextField.text;

    myNewCard.pin = self.pinTextField.text;

    myNewCard.points = [self.pointsTextField.text intValue];

    // to check if the text fields were filled up by the user
    if ([self.cardNameTextField.text length] && [self.pinTextField.text length] && [self.pointsTextField.text length]) 
    {

        [[self presentingViewController] dismissModalViewControllerAnimated:YES];

        NSLog(@"name saved %@", myNewCard.name);
        NSLog(@"pin saved %@", myNewCard.pin);
        NSLog(@"points saved %i", myNewCard.points);

        [self.delegate addCardViewController:self didCreateCard:myNewCard];

        // to check if there is a delegate
         if (self.delegate){
            NSLog(@"delegate is not nil");
        }

    }
}

@end

カード.h

#import <Foundation/Foundation.h>

@interface Card : NSObject

    @property (nonatomic, strong) NSString *name;
    @property (nonatomic, strong) NSString *pin;
    @property (nonatomic) int points;

@end

カード.m

#import "Card.h"

@implementation Card

@synthesize name = _name;
@synthesize pin = _pin;
@synthesize points = _points;

@end
4

2 に答える 2

2

誰かがこれに深く入り込む前に、明白な質問を邪魔にならないようにする必要があります-新しいカードを追加した後にデータをリロードするメカニズムがありますか(たとえばtableView reloadData、から[]を呼び出すCardWalletViewController)?そのようなものは見当たりませんでした。テーブルに何か新しいものを追加するときはいつもこれを使用していました。*

*テーブルに含まれるデータが多すぎる場合は、その一部のみをリロードすることをお勧めします。

更新1:クラスの継承

すべてのObjectiveCクラスは、階層内の他のクラスから継承する必要があります。デフォルトでは、特に断りのない限り、すべてのカスタムクラスはNSObjectを継承します。NSObjectは、最も一般的なオブジェクトです(Javaプログラミングを行った場合はObjectと同等です)。:親クラスの変更は、インターフェイス宣言の後にあるクラスを変更するだけで実行できます。したがって、あなたが言っていることは、「 andプロトコルを継承して実装するカスタムクラスを
@interface CardWalletViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
宣言する」ということです(プロトコルが何であるかわからない場合は、尋ねてください)。 CardWallerViewControllerUIViewControllerUITableViewDelegateUITableViewDataSource

さて、あなたの質問に戻りましょう。親クラスの変更は今では簡単なはずです。これをに変更するだけ: UIViewController: UITableViewController完了です。これを行うと、CardWallerViewController(また、「Waller」、本当に?)はUITableView、一般的なのではなく、のように動作しUIViewます。これを行うとき、デリゲートおよびdataSourceプロトコルを実装するように指示する必要もありません-UITableViewControllerデフォルトでそれを行います。

最後に、Xcodeプロジェクトに新しいファイルを追加するときに、継承するクラスをプログラムに指示できます。ビューのデフォルトはUIViewですが、これは単にこれが最も一般的なビュークラスであるためです。より具体的なクラス(いくつか例を挙げると、、、、)を使い始めるとUITableViewControllerUIPickerViewControllerUITableViewCellクラスをすぐに変更することが役立つことがわかります。

アップデート2:UITableViewCells

あなたが行っているforループには、(比較的)多くの作業を行う必要がありません。テーブルはmyWalletプロパティに直接対応しているため、これは、テーブルの行Nのセルが、配列のインデックスNにあるカードを表すことを意味します。あなたはそれをあなたの利益のために使うことができます。このtableView:cellForRowAtIndexPath:メソッドでは、特定のindexPath(実際にはそのテーブルのセクション+行)のセルをどのように処理するかをプログラムに指示します。秘訣は、このメソッドはセルを一度に1つずつインスタンス化することです。したがって、forループを実行する代わりに、(最後に)と言うことができます。
cell.textLabel.text = [self.myWallet objectAtIndex:indextPath.row].name;

行Nのセルの場合、これは内部のN番目のCardオブジェクトを調べ、myWalletその名前を使用してセルのを設定しtextLabel.textます。問題が発生した場合は[self.myWallet objectAtIndex:indextPath.row]、tempCardオブジェクトを保存してから、を実行してくださいcell.textLabel.text = tempCard.name。これは、tableViewにセルを設定するための適切な方法でもあります。とにかくメソッドが機能する方法であるため、一度に1つのセルのみを気にします。配列内に1,000,000枚のカードがあると想像してください。forループを実行すると、プログラムはセルごとに1,000,000回配列を通過するようになります。1,000,000,000,000回の操作に挨拶します:)

于 2012-04-18T03:23:44.947 に答える
0

イメージビューをサブビューとしてセルに追加できると思います

      UIImageView *imageView = [[UIImageView alloc] initWithFrame:cell.frame]; 

UIImage *image = [UIImage imageNamed:@"LightGrey.png"];

imageView.image = image;


 [cell addSubview:imageView];  

[[cell textLabel] setBackgroundColor:[UIColor clearColor]];

[[cell detailTextLabel] setBackgroundColor:[UIColor clearColor]];
于 2012-04-18T04:53:18.537 に答える