Не удается передать объект данных для просмотра контроллера внутри контроллера представления - PullRequest
0 голосов
/ 15 июня 2011

Я не уверен, почему, но у меня возникают проблемы при передаче объекта данных (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

Вот viewDidLoad из реализации CardViewController

- (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 Ответ

1 голос
/ 15 июня 2011

Похоже, ваш CardViewController должен быть на самом деле UIView.Как говорит Apple: «Один контроллер представления обычно управляет представлениями, связанными с ценностью контента одного экрана, хотя в приложениях для iPad это не всегда так».

(после изменения UIView) в цикле вы создаете одну карту tempCard, а затем загружаете другую.Если вы связали tempCardView в IB (см. Ниже), то все, что вам нужно:

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:

   -(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. Создать CardView.xibс одним UIView с, но установите FileOwner на ваш VC, а не на CardView, потому что это тот, кто собирается его загрузить (и у кого есть свойство tempCardView).
  2. Установите тип представления в CardView, затем подключите его к свойству thetempCardView FileOwner (он же HandViewController)
  3. Поместите все остальные части вашей карты в это CardView и подключите их к свойствам этого CardView.

У вас все должно быть в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...