Когда я могу начать использовать настройки свойств, используя UIAppearance?
У меня есть некоторые пользовательские свойства внешнего вида в моем классе вида (потомок UIView
). Я хочу настроить внешний вид вида в соответствии с этими свойствами, но я не могу сделать это внутри инициализатора, так как значения, установленные с помощью [[MyClass appearance] setFoo:…]
arent, действуют в этой точке:
@interface View : UIView
@property(strong) UIColor *someColor UI_APPEARANCE_SELECTOR;
@end
@implementation View
@synthesize someColor;
// Somewhere in other code before the initializer is called:
// [[View appearance] setSomeColor:[UIColor blackColor]];
- (id) initWithFrame: (CGRect) frame
{
self = [super initWithFrame:frame];
NSLog(@"%@", someColor); // nil
return self;
}
@end
Они уже установлены в layoutSubviews
, но это не очень хорошо для выполнения настроек вида, так как некоторые настройки могут снова запускать layoutSubviews
, что приводит к бесконечному циклу.
Итак, что хорошего для выполнения настроек? Или есть способ инициировать код, который применяет значения внешнего вида?
Ответы
Ответ 1
Возможным обходным путем является захват значения непосредственно из прокси:
- (id) initWithFrame: (CGRect) frame
{
self = [super initWithFrame:frame];
NSLog(@"%@", [[View appearance] someColor); // not nil
return self;
}
Конечно, это убивает возможность изменять внешний вид в соответствии с контейнером вида и, как правило, уродливым. Второй параметр, который я нашел, - выполнить настройки в сеттере:
- (void) setSomeColor: (UIColor*) newColor
{
someColor = newColor;
// do whatever is needed
}
Еще один идентификатор имеет некоторый крючок, который вызывается после того, как будут установлены свойства внешнего вида.
Ответ 2
Почему бы не подождать
- (void)willMoveToSuperview:(UIView *)newSuperview {
[super willMoveToSuperview:newSuperview];
if (newSuperview) {
... code here ...
}
}
если это дает вам проблемы?
Ответ 3
Предостережение: я использую Swift 2, поэтому не уверен в более ранних версиях Swift/ Objective-C. Но я обнаружил, что didMoveToSuperview()
не будет работать. Свойства доступны в layoutSubviews()
, но это не отличное место, чтобы делать что-либо подобное (поскольку его можно вызвать более одного раза). Лучшее место для доступа к этим свойствам в жизненном цикле вида, которое я нашел, это didMoveToWindow()
.
Ответ 4
Я бы подумал, что viewDidLoad было бы лучше, если бы это была единая вещь. В противном случае viewWillAppear.
EDIT:
Если вы хотите сделать это в представлении, а не в контроллере, я бы создал пользовательский init для представления по строкам:
-(id) initWithFrame:(CGRect) frame andAppearanceColor:(UIColor)theColor;
тем самым передавая цвет в представление во время создания.
Ответ 5
Я полагаю, что свойства UIAppearance
применяются к представлению, когда оно добавляется в иерархию представлений. Предположительно, вы можете получить доступ к заданным свойствам в UIView didMoveToSuperview
.