iOS, как добавить не из исходного кода умножить viewsControllers на один ViewController - PullRequest
3 голосов
/ 09 февраля 2012

У меня проблемы, потому что я не знаю, как это можно сделать. Кто-нибудь, помогите мне, пожалуйста.

Проблема:

У меня есть проект с классом UIViewController, который создается все время, когда я создаю новый проект в XCode. В этом viewController у меня есть XIB-файл для проектирования в XCode.

start new project

Мне нужно создать несколько видов и спроектировать их в Интерфейсном Разработчике так:

some views

Но мне нужно, чтобы эти представления были UIViewControllers, а не UIViews.

Проект должен выглядеть так: enter image description here

Так что я не знаю, как я могу сделать это в IB, но я могу сделать это из исходного кода в ViewController.m

tab  = [[TabBarController alloc] initWithNibName:@"mytestview" bundle:nil];
    [tab.view setFrame:CGRectMake(100, 100, 400, 600)];
    [self.view addSubview:tab.view];

Но это не мои взгляды, это другой объект, и если я хочу изменить положение или размер, я должен сделать это из кода. Как я могу делать то же самое в Интерфейсном Разработчике?

Ответы [ 3 ]

3 голосов
/ 23 февраля 2012

Рассмотрим следующий пример, основанный только на Master-Detail Application для iPhone.

Итак, добавьте новый контроллер представления во вновь созданном проекте в Xcode: enter image description here

Я назвал его NewInsideViewController.Создайте его без xib: enter image description here

Откройте DetailViewController.xib.Перетащите объекты View Controller и View (*) из библиотеки в область Objects следующим образом (я изменил цвет представления на LightGray): enter image description here

Выберите этот View Controller и измените его класс с UIViewController на NewInsideController в Identity Inspector: enter image description here

Назначить наш View (*) для NewInsideController как представление: enter image description here

Теперь все основные действия в IB завершены.Нам нужно создать экземпляр NewInsideController в нашем DetailViewController.Вы можете сделать это вручную, но у Xcode есть хорошая функция - drag-n-drop;) enter image description here

Я назвал это свойство как myNewInsideController, а DetailViewController.h выглядит следующим образом:

#import <UIKit/UIKit.h>
#import "NewInsideController.h"

@interface DetailViewController : UIViewController

@property (strong, nonatomic) id detailItem;
@property (strong, nonatomic) IBOutlet NewInsideController *myNewInsideController;

@property (strong, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
@end

Что ж, теперь наш NewInsideController готов работать и управлять своим видом.Давайте добавим кнопку и действие в это представление, чтобы проверить это: enter image description here

Напишите некоторый код в IBAction в NewInsideController.

- (IBAction)insideButtonClick:(id)sender {
    float rPart = arc4random()%100/100.0f;
    float gPart = arc4random()%100/100.0f;    
    self.view.backgroundColor = [UIColor colorWithRed:rPart green:gPart blue:0.5f alpha:1.0f];
}

Запустите программу.

0 голосов
/ 23 февраля 2012

Вы никогда, НИКОГДА не хотите брать представления, которые уже находятся под контролем определенного контроллера представления, и делать их подпредставлениями другого представления контроллера представления.

Контроллеры представления являютсяC часть в шаблоне проектирования MVC - они отвечают за управление представлением (и его подпредставлениями).Вы не можете взять представление, которым управляет контроллер, и прикрепить его как подпредставление представления другого контроллера. Если вы это сделаете, то становится неясным, кто отвечает за управление этим представлением.

Дажехотя это «прилипание» может быть технически возможным, оно создает код, который трудно понять, трудно поддерживать и, что самое главное, приведет к ошибкам из-за неясности того, кто отвечает за управление представлением, а также из-за того, что AppleКаркас View / Controller не поддерживает это.

Например: если на устройстве недостаточно памяти, Apple обязательно выгрузит представления, которые в данный момент не отображаются.Apple полагается на иерархию контроллеров представления, чтобы знать, когда она может выгружать представления.Если вы прикрепите представление контроллера представления к представлению другого контроллера представления, очень вероятно, что представление никогда не будет выгружено, даже если оно невидимо.

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

  1. Просто добавьте подпредставления к вашему представлению обычным образом, либо в конструкторе интерфейса, либо в -viewDidLoad:, чтобы добавить их программно, либо (реже) переопределить -loadView.
  2. Использовать представлениесдерживание контроллера, либо с помощью готовых контроллеров Apple (UINavigationController, UISplitViewController и т. д.), либо с вашими собственными контроллерами представления контейнера (iOS> 5).
  3. Отображение контроллеров представления модально.

Плохая идея нарушить иерархию контроллера представления действительно очень распространена и часто встречается у сторонних разработчиков, вероятно, потому, что это так просто и на первый взгляд просто.К сожалению, это вызывает вышеупомянутые ошибки: - (

Я настоятельно рекомендую всем, кто участвует в этой теме и комментариях, прочитать руководство по программированию Apple Controller и посмотреть WWDC 2011 "View ControllerСдерживание " видео.

0 голосов
/ 22 февраля 2012

Если я ясно понимаю вопрос:

  1. У вас есть родительское представление и контроллер, исходящий из XIB.
  2. Вы поместили подпредставления в родительское представление.
  3. Вы хотите, чтобы каждое подпредставление, помещенное в родительское представление, имело собственный (пользовательский) контроллер, но вы не знаете, как добавить контроллеры представления в вашу иерархию (XCode не позволит вам перетаскивать контроллеры представления на холст представления).

Итак, чтобы ответить на вопрос кратко: предположим, у вас есть несколько пользовательских UIViewController в вашем проекте (каждый контроллер представления состоит из .h и .m).Помните, что если вы размещаете их в контексте родителя, у них не должно быть своих собственных XIB (вы не можете вкладывать XIB в IB).Здесь важно отметить, что вы должны «размещать» интерфейс только в одном месте.Если вы хотите иметь XIB для каждого подпредставления, это неправильный подход.Однако то, что вы можете (не должен) делать, - это иметь несколько пользовательских viewControllers, каждый из которых подключен к своему собственному представлению, расположенному внутри вашего parentView, и вы можете настроить выходы вашего контроллера подчиненного представления на объекты в этомparentView.Фу, немного грязно.Еще одна вещь, о которой вам нужно знать, это то, что вашему родительскому контроллеру представления потребуется ссылка на каждый из его контроллеров подчиненного представления, чтобы вы могли программно получать доступ к этим подчиненным контроллерам и их выходам, поэтому для каждого подчиненного контроллераКонтроллер представления, который вы добавляете, вам также необходимо добавить IBOutlet в родительский контроллер представления, указывающий на каждый subviewController:

 ParentViewController.h
 @property (nonatomic, weak) IBOutlet CustomUIViewController *firstCustomController;

И затем, например, установить цвет фона для представления вашего первого пользовательского подпредставления /контроллер:

ParentViewController.m
[[[self firstCustomController] view] setBackgroundColor:[UIColor whiteColor]];

Откройте свой родительский контроллер представления в IB.Если вы посмотрите в своем ящике доступных объектов, вы найдете универсальный объект UIViewController.Перетащите это в свой родительский контроллер представления (НЕ на его холст представлений, а в сам родительский объект UIViewController, как видно в левом столбце компоновщика IB).Выберите универсальный контроллер представления, который вы добавили, и установите для его класса желаемый подкласс UIViewController.Теперь, когда ваша XIB загружается, он будет создавать экземпляр вашего пользовательского контроллера представления вместе со всем, что вы добавили к его холсту.

Наконец, перетащите универсальный UIView на ваш холст, поместив его в существующий контроллер.просмотреть (ваш скриншот уже показывает это как сделано).Щелкните правой кнопкой мыши по своему пользовательскому контроллеру представления и подключите его выход «view» к добавленному представлению.

Теперь, когда вы запускаете, ваш пользовательский контроллер представления имеет на экране вид, который равен представлению вашего пользовательского подкласса контроллера, и вы не делали ничего из этого в коде.

Итак, теперь, когда вы это сделали, подумайте, будет ли это лучшим выбором: встроенные контроллеры представления сложны (как вы видели) и не обязательно являются хорошим дизайнерским решением:http://blog.carbonfive.com/2011/03/09/abusing-uiviewcontrollers/

Хотя iOS5 поддерживает вложенные контроллеры представления, лично я бы не стал их использовать.Я ценю лучшую практику, диктующую один экран = один контроллер представления.

enter image description here

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