Невозможно подключить IBOutlet, используя Xcode 4.2.1, iOS 5.0 и раскадровки - PullRequest
0 голосов
/ 28 января 2012

Я пытаюсь подключить IBOutlet в классе (DataViewController) к другому классу (RootViewController), чтобы получить доступ к экземпляру RootViewController в DataViewController.

Нет предупреждений или ошибок компиляцииКогда я выбираю DataViewController в сцене IB, я вижу розетку, которую я определил в Connections Inspector-> Outlets.Но когда я пытаюсь перетащить соединение из розетки в RootViewController, оно не работает.Просто происходит сбой без какой-либо ошибки или указания, что не так.

Я проверил, что сцена RootViewController имеет пользовательский класс "RootViewController".

Вот мой код:

//RootViewController.h
#import <UIKit/UIKit.h>

@interface RootViewController : UIViewController <UIPageViewControllerDelegate>
@property (strong, nonatomic) UIPageViewController *pageViewController;
@end


//DataViewController.h
#import <UIKit/UIKit.h>
@class RootViewController;

@interface DataViewController : UIViewController < UIWebViewDelegate > {
    IBOutlet UIWebView *webView;
}
@property (strong, nonatomic) IBOutlet RootViewController *rvc; //this one won't connect. Why?
@property (strong, nonatomic) IBOutlet UILabel *dataLabel;
@property (strong, nonatomic) id dataObject;
@end

//DataViewController.m
#import "DataViewController.h"
#import "RootViewController.h"

@implementation DataViewController

@synthesize rvc;

//...
@end

Что я делаю не так?

1 Ответ

3 голосов
/ 28 января 2012

Вы не можете этого сделать.Вам нужно настроить протокол делегата.См. Это руководство и найдите слова «новый делегат», и оно объяснит, как это делается.Это шаблон дизайна, который вам нужно использовать.Есть несколько шагов, поэтому следуйте внимательно.Это стоит учиться.Протоколы делегатов распространены в приложениях для iPhone.

В текущем проекте я создал протокол делегатов для связи между двумя контроллерами: SelectNoteViewController (Select) и EditNoteViewController (Edit).Основная идея заключается в том, что Select используется для выбора из списка заметок, а Edit используется для редактирования этих заметок.Теперь мне нужно Edit, чтобы иметь доступ обратно к данным и методам, сохраненным в Select, потому что у меня есть кнопки edit для вызова предыдущей или следующей заметки из списка, который управляется Select, чтобы я реализовал протокол делегата.Select является делегатом для редактирования.Это означает, что Select делает вещи для редактирования.Вот необходимый код.

SelectNoteViewController.h:

// this next statement is need to inform Select of the protocols defined in Edit
#import "EditNoteViewController.h" // STEP 1


@interface SelectNoteViewController : UITableViewController <EditNoteViewControllerDelegate> { ... // STEP 2: this says Select implements the protocol I created
...
// STEP 3: EditNoteViewController Delegate Methods - these are the methods in the protocol
- (Notes *)selectPreviousNote;
- (Notes *)selectNextNote;

SelectNoteViewController.m:

// STEP 4: the protocol methods are implemented
- (Notes *)selectPreviousNote {
    if (isPreviousToSelectedNote) {
        NSIndexPath *indexPath, *previousIndexPath;
        indexPath = [self.tableView indexPathForSelectedRow];
        previousIndexPath = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:0];
        // update the selected row
        self.selectedNote = [self.fetchedResultsController objectAtIndexPath:previousIndexPath];
        [self.tableView selectRowAtIndexPath:previousIndexPath animated:NO scrollPosition:UITableViewScrollPositionMiddle];
        [self setPreviousNote];
        [self setNextNote];
    } 
return selectedNote;
}

- (Notes *)selectNextNote {
    if (isNextToSelectedNote) {
        NSIndexPath *indexPath, *nextIndexPath;
        indexPath = [self.tableView indexPathForSelectedRow];
        nextIndexPath = [NSIndexPath indexPathForRow:indexPath.row-1 inSection:0];
        // update the selected row
        self.selectedNote = [self.fetchedResultsController objectAtIndexPath:nextIndexPath];
        [self.tableView selectRowAtIndexPath:nextIndexPath animated:NO scrollPosition:UITableViewScrollPositionMiddle];
        [self setPreviousNote];
        [self setNextNote];
    }
return selectedNote;
}
...
    ...
if ([[segue identifier] isEqualToString:@"editNote"])  {
    // STEP 5: this is where Edit is told that its delegate is Select
    [[segue destinationViewController] setEditNoteViewControllerDelegate:self]; // STEP 5

У Select теперь есть структура, которая должна быть делегатом для редактирования.,Теперь Edit должен определить протокол на его конце, который он собирается использовать для доступа к этим методам в Select.

EditNoteViewController.h

#import ... // put protocol after import statements
// STEP 6
@protocol EditNoteViewControllerDelegate <NSObject>

- (Notes *)selectPreviousNote;
- (Notes *)selectNextNote;

@end


@interface ...
// STEP7: Edit needs a property to tell it who the delegate is - it was set back in Select.m
@property (weak) id <EditNoteViewControllerDelegate> editNoteViewControllerDelegate; 

EditNoteViewController.m

// STEP 8: the property is synthesized
@synthesize editNoteViewControllerDelegate;

...

// STEP 9: now when any method needs to call selectPreviousNote or selectNext Note it does it like this:
selectedNote = [self.editNoteViewControllerDelegate selectPreviousNote];
// or
selectedNote = [self.editNoteViewControllerDelegate selectNextNote];

Вот и все.Конечно, методы протокола похожи и на другие методы, и им могут передаваться параметры, которые вам нужно сделать, чтобы передать данные обратно, что было вашим вопросом в первую очередь.Обратите внимание, что я могу передавать данные из Select в Edit без протокола, создав свойства в Edit и установив эти свойства в методе prepareForSegue метода Select.Это дает мне один шанс установить некоторые параметры при создании экземпляра Edit.Мое использование протокола делегата восходит к Select и позволяет передать еще одну заметку (предыдущую или следующую) в Edit.Надеюсь, это поможет.Вы можете видеть, что есть несколько шагов для создания протокола делегата.Я пронумеровал их 1-9.Если данные не возвращаются, я обычно забываю один из шагов.

...