我有两个视图控制器。 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
答案 0 :(得分:2)
在任何人开始深入研究这个问题之前,我应该先解决一个明显的问题 - 你是否有一些机制在你添加一张新卡后重新加载数据(例如从{调用[tableView reloadData
] {1}})?我没有看到类似的东西,每当我向桌子添加新内容时,我总是使用它。*
*如果表包含太多数据,您可能只想重新加载其中的一部分。
每个Objective C类都必须从层次结构中的其他类继承。默认情况下,除非另有说明,否则所有自定义类都将继承自NSObject,这是最通用的对象(如果您已完成Java编程,则相当于Object)。只需在接口声明中的CardWalletViewController
之后更改类即可更改父类。所以当你说
:
你所说的是“声明一个@interface CardWalletViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
自定义类,它继承自CardWallerViewController
并实现UIViewController
和UITableViewDelegate
协议”(如果你不知道什么是协议,问)。
现在,回到你的问题。现在更改父类应该很简单 - 您只需将UITableViewDataSource
更改为: UIViewController
即可。执行此操作后,您的CardWallerViewController(也称为“Waller”,真的吗?)将表现得像: UITableViewController
,而不像通用UITableView
。执行此操作时,您也无需告诉它实现委托和dataSource协议 - UIView
默认情况下会这样做。
最后要注意的是,当您向Xcode项目添加新文件时,您可以告诉程序您要从哪个类继承。对于视图,它默认为UIView,但这仅仅是因为这是最通用的视图类。当您开始使用更具体的类(UITableViewController
,UITableViewController
,UIPickerViewController
时,仅举几例),更改父级类别将证明不仅仅是有用的。
你已经去过的那个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]];