繁体   English   中英

无法通过数据 object 在视图 controller 中查看 controller

[英]Can't pass a data object to view controller inside a view controller

我不知道为什么,但是当视图 controller 在另一个视图中实例化时,我无法将数据 object (NSManagedObject) 传递给视图 controller。 当我在 object 被通过之前记录它时,它有它的所有数据,但是在它到达视图 controller 之后,它是空的。 看起来这应该是相当直截了当的,但由于某种原因,它只是没有到达那里。

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

任何帮助深表感谢。 提前致谢。

这是 header 视图 controller 滚动:

@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

这是 object 的实现中的 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.
}

更新:根据请求,我从 controller 视图中添加了一些代码

这是 CardViewController 的 header

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

header 文件 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

似乎您的 CardViewController 实际上应该是 UIView。 正如 Apple 所说:“单个视图 controller 通常管理与单个屏幕的内容相关的视图,尽管在 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 的权限。 您将需要 thisCard 的 setter,只要将值分配给 thisCard 属性,就会调用该 setter:

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

现在在界面生成器中,

  1. 使用单个 UIView 创建 CardView.xib,但将 FileOwner 设置为您的 VC,而不是 CardView,因为这将由谁来加载它(并且谁拥有 tempCardView 属性)。
  2. 将视图的类型设置为 CardView,然后将其连接到 FileOwner(又名 HandViewController)的 tempCardView 属性
  3. 将所有其他卡片部件放入该 CardView 并将它们连接到该 CardView 的属性。

你应该准备好了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM