Бесконечный цикл, пытающийся создать пользовательский вид из xib в IB

это продолжение этого вопроса (пользовательское руководство UIView с IB/Xcode 4.5.1 и iOS Simulator 6.0), но не обязательно читать - это мой первый раз, пытаясь создать пользовательский UIView, и есть явно то, что я не получаю так заранее, за любую помощь, которую вы можете предоставить.

У меня есть пользовательский UIView, который получен из Interface Builder. Я хочу установить для параметра размер 200w x 200h, а backgroundColor - Green. Когда я создал, я сделал следующее:

  • Создал новый пользовательский UIView через файл → Новый → Objective-C Класс под названием Tview
  • Создал новый вид через File → New → Пользовательский интерфейс → Просмотреть и назвать его tnib
  • в Canvas я удалил View и добавил новый View от инспектора объектов и установил имя класса в Tview. Кроме того, в инспекторе атрибутов я задал размер Freeform и цвет фона Green. В Инспекторе размеров я устанавливаю ширину 200 и высоту 200.

В моем Tview.m я создал следующее (я сделал некоторые обновления на основе других вопросов SO, но неясно, все ли они актуальны или точны):

@implementation Tview

-(id) initWithCoder:(NSCoder *)aDecoder
{
  NSLog(@"in initWithCoder");
  if((self = [super initWithCoder:aDecoder])) {
    [self setUpView];
    }
  return self;
}

-(void)awakeFromNib
{
  NSLog(@"in awakeFromNib");
  [self setUpView];
}

-(void)setUpView
{
    NSLog(@"I am in setUpView");
    NSArray *subviewArray=[[NSBundle mainBundle] loadNibNamed:@"tnib" owner:self options:nil];
    UIView *mainView = [subviewArray objectAtIndex:0];
    [self addSubview:mainView];
}

@end

В моем ViewController.xib я вытащил UIView и установил имя пользовательского класса в Tview. я # import файл Tview.h и перетащите из ViewController.xib в Tview.h и создайте следующее свойство:

@property (strong, nonatomic) IBOutlet Tview *myTview;

Я создаю и запускаю и получаю бесконечный цикл hte:

2013-03-04 06:49:05.452 Nibtest2[44524:11303] in initWithCoder
2013-03-04 06:49:05.455 Nibtest2[44524:11303] I am in setUpView
2013-03-04 06:49:05.456 Nibtest2[44524:11303] in initWithCoder
2013-03-04 06:49:05.458 Nibtest2[44524:11303] I am in setUpView
2013-03-04 06:49:05.459 Nibtest2[44524:11303] in initWithCoder
2013-03-04 06:49:05.460 Nibtest2[44524:11303] I am in setUpView

до тех пор, пока он не выйдет из строя.

Что я здесь делаю неправильно?

спасибо заранее

Ответ 1

Ваш код устанавливает бесконечную рекурсию: initWithCoder: вызывает setUpView, которая создает экземпляр нового UIView из пакета, тем самым косвенно вызывая initWithCoder: и завершая цикл.

Вы не должны обращаться к NIB в коде, который вызывается при чтении одного и того же NIB. Вы должны прочитать NIB в коде содержащего объекта, а не в коде самого объекта Tview. В противном случае вы получите бесконечный цикл.

Вам необходимо полностью удалять setUpView вместе со своими вызовами из awakeFromNib и initWithCoder:. Похоже, что соединение, которое вы создали в построителе интерфейсов путем перетаскивания из инспектора объекта, уже вызывает загрузку файла NIB правильно, о чем свидетельствует вызов initWithCoder:. Единственная строка, которая вам может понадобиться, следующая:

[self addSubview:mainView];

Однако он не должен быть в коде Tview: его нужно перенести в родительский контроллер, у которого есть свойство myTview, и его следует изменить на

[self.view addSubview:_myTview];

Добавьте эту строку в viewDidLoad. Он должен заботиться о проблеме.

Ответ 2

На самом деле мое решение этой проблемы состояло в том, чтобы загрузить представление в viewDidLoad в моем CustonViewController, где я хотел использовать такое представление:

myAccessoryView = NSBundle.mainBundle().loadNibNamed("MyAccessoryView", owner: self, options: nil)[0] as! MyAccessoryView

Не загружать представление в метод loadView()! Метод loadView служит для загрузки представления для вашего пользовательского ViewController.