Как переопределить свойство «вид» в UIViewController? - PullRequest
28 голосов
/ 14 марта 2009

У меня есть пользовательский UIViewController и пользовательский UIView. Я хотел бы переопределить свойство viewcontroller.view, чтобы вернуть MyCustomUIView.

Прямо сейчас у меня есть:

@interface MyViewController : UIViewController {    
    IBOutlet MyView* view;
}

@property (nonatomic, retain) IBOutlet MyView* view;

Компилируется, но я получаю предупреждение: тип свойства view не соответствует типу свойства суперкласса UIViewController.

Как мне смягчить это предупреждение?

Ответы [ 5 ]

23 голосов
/ 07 мая 2013

@ lpaul7 уже разместил ссылку на блог Трэвиса Джеффри в качестве комментария, но он гораздо более корректен, чем все остальные ответы, что ему действительно нужен код для ответа:

ViewController.h:

@interface ViewController : UIViewController

@property (strong, nonatomic) UIScrollView *view;

@end

ViewController.m:

@implementation ViewController

@dynamic view;

- (void)loadView {
  self.view = [[UIScrollView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
}

@end

Если вы используете xib, вместо переопределения loadView измените тип корневого представления вашего контроллера представления и добавьте IBOutlet к свойству.

Подробнее см. Переопределение свойства просмотра UIViewController, Выполнено правильно .

18 голосов
/ 14 марта 2009

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

  • (UIView *) просмотр;
  • (MyView *) представление;

Objective-C не разрешает ковариацию возвращаемого типа.

Что вы можете сделать, это добавить новое свойство "myView" и сделать его просто типизировать свойство "view". Это уменьшит количество типов во всем вашем коде. Просто назначьте свой подкласс view свойству view, и все должно работать нормально.

4 голосов
/ 26 апреля 2012

Извините, но ваш короткий ответ неверен.

Правильная реализация этого заключается в добавлении @property в заголовочный файл с вашим типом возвращаемого значения. Затем вместо @synthesize вы добавляете геттер и сеттер вручную и возвращаете тип приведения из [super view]

например, мой класс PlayerViewController

PlayerViewController.h

@property (strong, nonatomic) IBOutlet PlayerView *view;

PlayerViewController.m

- (PlayerView *)view{
    return (PlayerView*)[super view];
}
- (void)setView:(PlayerView *)view{
    [super setView:view];
}

важно поставить правильный класс в представление.

Помещение UIView туда, где находится PlayerView, вероятно, будет работать в Интерфейсном Разработчике, но не будет правильно работать в коде.

В настоящее время я использую эту реализацию.

4 голосов
/ 14 марта 2009

Свойство / метод представления UIViewController автоматически вернет ваше представление. Я думаю, вам просто нужно привести результат к MyView (или просто использовать тип id):

MyView *myView = (MyView*)controller.view;
id myView = controller.view;

Я думаю, что код, который вы разместили выше, доставит вам неприятности. Вы, вероятно, не хотите создавать элемент представления самостоятельно (потому что тогда контроллер будет хранить 2 вида и может не использовать правильный вид внутри) или переопределять свойство представления (поскольку UIViewController имеет специальную обработку для него.) 1004 * этот вопрос для получения дополнительной информации о последнем.)

0 голосов
/ 14 октября 2015

Если кто-то использует Swift 2.0+, вы можете использовать расширения протокола для многоразовой реализации:

// Classes conforming to this protocol...
protocol CustomViewProvider {

    typealias ViewType
}

// ... Will get customView accessor for free
extension CustomViewProvider where Self: UIViewController, Self.ViewType: UIView {

    var customView: Self.ViewType {
        return view as! Self.ViewType
    }
}


// Example:
extension HomeViewController: CustomViewProvider {
    typealias ViewType = HomeView
}

// Now, we can do something like
let customView: HomeView = HomeViewController().customView
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...