0

我有两个视图控制器。CardWallet View Controller 是我的表格视图。然后 AddCard 视图控制器是我为名为 Card 的对象的新实例输入值的地方。到目前为止,我正在使用委托将这些 Card 实例添加到名为 myWallet 的数组中,该数组位于我的 CardWallet 视图控制器中,并且它可以工作。

我想要的是,在我的 AddCard View Controller 中单击按钮后,我的 Card Wallet 视图中将出现一个新的表格单元格,其名称取决于最近添加的 Card 实例。下面是我的代码,请检查为什么当我添加完一个新的 Card 实例后,我的表中没有出现任何内容。我做了一些研究并阅读了一些教程,这个很好, http: //kurrytran.blogspot.com/2011/10/ios-5-storyboard-and.html,它对我有很多关于表格视图控制器的帮助. 但是,本教程并没有满足我的主要关注点,因为它的表值仅来自具有静态值的数组。

谢谢!

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:类继承

每个Objective C 类都必须从层次结构中的某个其他类继承。默认情况下,除非您另有说明,否则您的所有自定义类都将继承自 NSObject,这是目前最通用的对象(如果您做过 Java 编程,则相当于 Object)。更改父类只需:在接口声明之后更改类即可。因此,当您说
@interface CardWalletViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
您所说的是“声明一个CardWallerViewController继承UIViewController并实现UITableViewDelegateandUITableViewDataSource协议的自定义类”时(如果您不知道协议是什么,请询问)。

现在,回到你的问题。现在更改父类应该很容易 - 您只需将其更改: UIViewController为即可: UITableViewController。完成此操作后,您的 CardWallerViewController(也称为“Waller”,真的吗?)将表现得像 a UITableView,而不像 generic UIView。这样做时,您也不需要告诉它实现委托和数据源协议 -UITableViewController默认情况下会这样做。

最后一点,当你向 Xcode 项目添加新文件时,你可以告诉程序你想从哪个类继承。对于视图,它默认为 UIView,但这仅仅是因为这是最通用的视图类。当您开始使用更具体的类(UITableViewControllerUIPickerViewControllerUITableViewCell等)时,立即更改父类将证明是非常有帮助的。

更新 2:UITableViewCells

你要去的那个for循环有很多(相对)你不需要做的工作。由于您的表格直接对应于您的 myWallet 属性,这意味着表格第 N 行中的单元格将代表数组索引 N 处的卡片。你可以利用它来发挥你的优势。在该tableView:cellForRowAtIndexPath:方法中,您告诉程序如何处理特定 indexPath 处的单元格(实际上只是该表的部分 + 行)。诀窍是,此方法一次实例化一个单元格。所以不要做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,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 回答