Хорошо, есть десятки сообщений в StackOverflow об этом, но ни одно из них не является особенно ясным для решения. Я хотел бы создать пользовательский UIView
с сопроводительным xib файлом. Требования:
- Никакой отдельный
UIViewController
- полностью автономный класс - Выходные данные в классе, позволяющие мне устанавливать/получать свойства представления
Мой текущий подход к этому:
-
Переопределить
-(id)initWithFrame:
-(id)initWithFrame:(CGRect)frame { self = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] objectAtIndex:0]; self.frame = frame; return self; }
-
Проигрывать программно с помощью
-(id)initWithFrame:
в моем контроллере просмотраMyCustomView *myCustomView = [[MyCustomView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)]; [self.view insertSubview:myCustomView atIndex:0];
Это прекрасно работает (хотя никогда не называть [super init]
и просто устанавливать объект, используя содержимое загруженного nib, кажется немного подозрительным - здесь есть совет добавить subview в этом case, который также отлично работает). Тем не менее, я хотел бы также создать экземпляр представления из раскадровки. Поэтому я могу:
- Поместите a
UIView
в родительском представлении в раскадровке - Задайте свой собственный класс
MyCustomView
-
Переопределить
-(id)initWithCoder:
- код, который я видел чаще всего, соответствует шаблону, например:-(id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { [self initializeSubviews]; } return self; } -(id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self initializeSubviews]; } return self; } -(void)initializeSubviews { typeof(view) view = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] objectAtIndex:0]; [self addSubview:view]; }
Конечно, это не сработает, так как я использую вышеприведенный подход или создаю ли я программную реализацию, и заканчивая рекурсивным вызовом -(id)initWithCoder:
при входе -(void)initializeSubviews
и загрузке файла из файла.
Несколько других вопросов SO касаются этого, например здесь, здесь, здесь и здесь. Однако ни один из ответов не удовлетворительно устраняет проблему:
- Общепринятое предложение состоит в том, чтобы внедрить весь класс в UIViewController и выполнять там загрузку nib, но это кажется субоптимальным для меня, поскольку для этого требуется добавить другой файл, как оболочку
Может ли кто-нибудь дать совет о том, как решить эту проблему, и получить рабочие точки в пользовательском UIView
с минимальной суматохой/без тонкой оболочки контроллера? Или есть альтернативный, более чистый способ делать вещи с минимальным шаблоном кода?