在表视图单元格中添加值

时间:2012-04-18 02:12:22

标签: iphone objective-c ios5 uitableview

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

我想要的是,点击我的AddCard View Controller中的按钮后,我的Card Wallet View中会出现一个新的表格单元格,其名称取决于最近添加的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

Card.h

#import <Foundation/Foundation.h>

@interface Card : NSObject

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

@end

Card.m

#import "Card.h"

@implementation Card

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

@end

2 个答案:

答案 0 :(得分:2)

在任何人开始深入研究这个问题之前,我应该先解决一个明显的问题 - 你是否有一些机制在你添加一张新卡后重新加载数据(例如从{调用[tableView reloadData] {1}})?我没有看到类似的东西,每当我向桌子添加新内容时,我总是使用它。*

*如果表包含太多数据,您可能只想重新加载其中的一部分。

更新1:类继承

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

现在,回到你的问题。现在更改父类应该很简单 - 您只需将UITableViewDataSource更改为: UIViewController即可。执行此操作后,您的CardWallerViewController(也称为“Waller”,真的吗?)将表现得像: UITableViewController,而不像通用UITableView。执行此操作时,您也无需告诉它实现委托和dataSource协议 - UIView默认情况下会这样做。

最后要注意的是,当您向Xcode项目添加新文件时,您可以告诉程序您要从哪个类继承。对于视图,它默认为UIView,但这仅仅是因为这是最通用的视图类。当您开始使用更具体的类(UITableViewControllerUITableViewControllerUIPickerViewController时,仅举几例),更改父级类别将证明不仅仅是有用的。

更新2:UITableViewCells

你已经去过的那个for循环有一个(相对)很多你不需要做的工作。由于您的表直接对应于myWallet属性,这意味着表的第N行中的单元格将代表数组索引N处的卡。您可以利用它来获得优势。在UITableViewCell方法中,您告诉程序如何处理特定indexPath处的单元格(实际上只是该表的section + row)。诀窍是,此方法一次一个地实例化单元格。所以,不要做for-loop,你可以说(最后) tableView:cellForRowAtIndexPath:

对于行N中的任何单元格,这将查看cell.textLabel.text = [self.myWallet objectAtIndex:indextPath.row].name;内的第N个卡对象,并使用其名称来设置单元格的myWallet。如果它给您带来问题,请将textLabel.text保存在某个tempCard对象中,然后执行[self.myWallet objectAtIndex:indextPath.row]。这也是在tableView中填充单元格的正确方法 - 您一次只关心一个单元格,因为无论如何该方法都是如此。想象一下,如果您的阵列中有1,000,000张卡片 - 执行for循环会强制程序为每个单元格通过阵列1,000,000次。向1,000,000,000,000次操作问好:)

答案 1 :(得分:0)

我想你可以将imageview作为子视图添加到单元格

      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]];