无法将数据对象传递给视图控制器内的视图控制器

时间:2011-06-14 21:43:19

标签: iphone objective-c ios cocoa-touch

我不确定为什么,但是当该视图控制器在另一个视图控制器中实例化时,我无法将数据对象(NSManagedObject)传递给视图控制器。当我在传递对象之前记录它时,它具有所有数据,但在到达视图控制器后,它是空的。看起来这应该是相当直接的,但由于某种原因,它只是没有到达那里。

将NSManagedObject分配给实现文件中的接受视图控制器的代码是:viewController.thisCard = aCard;

非常感谢任何帮助。提前谢谢。

这是滚动视图控制器的标题:

@interface HandViewController : UIViewController 
<UIScrollViewDelegate>
{
    IBOutlet UIScrollView *scrollView;
    IBOutlet UIPageControl *pageControl;

    BOOL pageControlIsChangingPage;
    NSManagedObjectContext *context;
}

@property (nonatomic, retain) UIView *scrollView;
@property (nonatomic, retain) UIPageControl *pageControl;
@property (nonatomic, retain) NSManagedObjectContext *context;

/* for pageControl */
- (IBAction)changePage:(id)sender;

@end

这是该对象实现中的viewDidLoad

- (void)viewDidLoad
{
    scrollView.delegate = self;

    [self.scrollView setBackgroundColor:[UIColor blackColor]];
    [scrollView setCanCancelContentTouches:NO];

    scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
    scrollView.clipsToBounds = YES;
    scrollView.scrollEnabled = YES;
    scrollView.pagingEnabled = YES;

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Game" inManagedObjectContext:[self context]];
    [fetchRequest setEntity:entity];

    NSError *error;
    NSArray *fetchedGames = [self.context executeFetchRequest:fetchRequest error:&error];

    [fetchRequest release];

    Game *aGame = [fetchedGames objectAtIndex:0];

    CGFloat cx = 0;

    for (Card *aCard in aGame.turnUpcoming.hand) {

        CardViewController *viewController = [[CardViewController alloc] initWithNibName:@"CardViewController" bundle:nil];

        CGRect rect = self.view.frame;
        rect.size.height = scrollView.frame.size.height - 50;
        rect.size.width = scrollView.frame.size.width - 50;
        rect.origin.x = ((scrollView.frame.size.width - rect.size.width) / 2) + cx;
        rect.origin.y = ((scrollView.frame.size.height - rect.size.height) / 2);
        viewController.view.frame = rect;
        viewController.thisCard = aCard;
        [scrollView addSubview:viewController.view];

        cx += scrollView.frame.size.width;

        [viewController release];
    }

    self.pageControl.numberOfPages = [aGame.turnUpcoming.hand count];
    [scrollView setContentSize:CGSizeMake(cx, [scrollView bounds].size.height)];

    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

更新:每个请求,我从视图控制器添加一些代码

这是CardViewController的标题

@interface CardViewController : UIViewController {
    UILabel IBOutlet *cardValue;
    UILabel IBOutlet *cardInstruction;
    UILabel IBOutlet *cardHint;
    UILabel IBOutlet *cardTimer;
    UIButton IBOutlet *playCardButton;

    Card *thisCard;
}

@property (nonatomic, retain) UILabel IBOutlet *cardValue;
@property (nonatomic, retain) UILabel IBOutlet *cardInstruction;
@property (nonatomic, retain) UILabel IBOutlet *cardHint;
@property (nonatomic, retain) UILabel IBOutlet *cardTimer;
@property (nonatomic, retain) UIButton IBOutlet *playCardButton;
@property (nonatomic, retain) Card *thisCard;

@end

这是来自CardViewController

实现的viewDidLoad
- (void)viewDidLoad
{
    [super viewDidLoad];

     if ([thisCard isObjectValid]) {
        cardValue.text = [thisCard.value stringValue];
     }

}

更新:viewDidLoad中的卡片循环新代码和新的CardView代码,按照以下建议

在viewDidLoad中循环:

for (Card *aCard in aGame.turnUpcoming.hand) {

        CGRect rect = scrollView.frame;
        rect.size.height = scrollView.frame.size.height - 50;
        rect.size.width = scrollView.frame.size.width - 50;
        rect.origin.x = ((scrollView.frame.size.width - rect.size.width) / 2) + cx;
        rect.origin.y = ((scrollView.frame.size.height - rect.size.height) / 2);

        tempCardView = [[CardView alloc] initWithFrame:rect];
        tempCardView.thisCard = aCard;

        NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"CardView" owner:self options:nil];

        tempCardView = [nibObjects objectAtIndex:0];

        [scrollView addSubview:tempCardView];

        cx += scrollView.frame.size.width;

        [tempCardView release];
    }

头文件CardView.h

@interface CardView : UIView {
    UILabel IBOutlet *cardValue;
    UILabel IBOutlet *cardInstruction;
    UILabel IBOutlet *cardHint;
    UILabel IBOutlet *cardTimer;
    UIButton IBOutlet *playCardButton;

    Card *thisCard;
}

@property (nonatomic, retain) UILabel IBOutlet *cardValue;
@property (nonatomic, retain) UILabel IBOutlet *cardInstruction;
@property (nonatomic, retain) UILabel IBOutlet *cardHint;
@property (nonatomic, retain) UILabel IBOutlet *cardTimer;
@property (nonatomic, retain) UIButton IBOutlet *playCardButton;
@property (nonatomic, retain) Card *thisCard;

@end

实施文件CardView.m

@implementation CardView

@synthesize cardHint;
@synthesize cardTimer;
@synthesize cardValue;
@synthesize cardInstruction;
@synthesize playCardButton;
@synthesize thisCard;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        if ([thisCard isObjectValid]) {
            cardValue.text = [thisCard.value stringValue];
            cardInstruction.text = thisCard.instruction;
            cardHint.text = thisCard.hint;
            cardTimer.text = [thisCard.time stringValue];
        }
    }
    return self;
}

@end

更新:6月16日 - 添加了XIB屏幕截图

CardView.xib

CardView.xib

1 个答案:

答案 0 :(得分:1)

看起来你的CardViewController实际上应该是一个UIView。正如Apple所说:“单个视图控制器通常管理与单个屏幕内容相关的视图,但在iPad应用程序中,情况可能并非总是如此。”

循环中的

(在更改UIView之后),您正在创建一个tempCard,然后加载另一个。如果你已经在IB中链接了tempCardView(见下文),那么你只需要:

for (Card *aCard in aGame.turnUpcoming.hand) {
    CGRect rect;
    rect.size.width = scrollView.frame.size.width - 50;
    rect.size.height = scrollView.frame.size.height - 50;
    rect.origin.x = ((scrollView.frame.size.width - rect.size.width) / 2) + cx;
    rect.origin.y = ((scrollView.frame.size.height - rect.size.height) / 2);
    [[NSBundle mainBundle] loadNibNamed:@"CardView" owner:self options:nil];  //magically connected to tempCardView.
    self.tempCardView.frame = rect;
    self.tempCardView.thisCard = aCard;

    [scrollView addSubview:tempCardView];
    cx += scrollView.frame.size.width;
    self.tempCardView = nil;
}

所以,你有两个XIB,你的主要一个用你的viewController加载,一个(CardView)为每个卡加载一次。

现在,在CardView内部,您正试图过早设置标签。在initWithFrame(在上面的情况下由loadFromNib调用)期间,您还没有访问thisCard。你需要一个setCard的setter,只要为thisCard属性赋值,就会调用它:

   -(void) setThisCard: (Card *) newCard {
       if (thisCard == newCard) return;
       [newCard retain];
       [thisCard release];
       thisCard = newCard;
       self.cardValue.text = [thisCard.value stringValue];
       self.cardInstruction.text = thisCard.instruction;
       self.cardHint.text = thisCard.hint;
       self.cardTimer.text = [thisCard.time stringValue];
    }

现在在Interface Builder中,

  1. 使用单个UIView创建CardView.xib,但将FileOwner设置为VC,而不是CardView,因为那是谁将加载它(以及谁具有tempCardView属性)。
  2. 将视图的类型设置为CardView,然后将其挂钩到FileOwner(又名HandViewController)的thetempCardView属性
  3. 将所有其他卡片部件放入CardView中,并将它们连接到CardView的属性。
  4. 你应该全力以赴。