Ограничение автоматической компоновки на CALayer IOS
Привет, Я разрабатываю приложение для iPhone, в котором я попытался установить одну сторону границы для edittext. Я сделал это следующим образом:
int borderWidth = 1;
CALayer *leftBorder = [CALayer layer];
leftBorder.borderColor = [UIColor whiteColor].CGColor;
leftBorder.borderWidth = borderWidth;
leftBorder.frame = CGRectMake(0, textField.frame.size.height - borderWidth, textField
.frame.size.width, borderWidth);
[textField.layer addSublayer:leftBorder];
Я установил некоторые ограничения на мой edittext в IB, так что, когда я поворачиваю свое устройство, он будет регулировать ширину текстового поля в соответствии с этим. Моя проблема в том, что настройка ширины edittext не регулирует ширину CALayer, которую я установил для своего текста редактирования. Поэтому я думаю, что я должен установить некоторые ограничения для моего объекта CALayer. Но я не знаю, как это сделать. Кто-нибудь знает об этом? Нужна помощь. Спасибо.
Ответы
Ответ 1
весь бизнес авторезистентности зависит от вида. слои не авторезистируются.
что вам нужно сделать - в коде - изменить размер слоя самостоятельно
например.
в viewController вы бы сделали
- (void) viewDidLayoutSubviews {
[super viewDidLayoutSubviews]; //if you want superclass behaviour...
// resize your layers based on the view new frame
self.editViewBorderLayer.frame = self.editView.bounds;
}
или в пользовательском UIView вы можете использовать
- (void)layoutSubviews {
[super layoutSubviews]; //if you want superclass behaviour... (and lay outing of children)
// resize your layers based on the view new frame
layer.frame = self.bounds;
}
Ответ 2
Оформить это решение.
Используйте KVO для пути "YourView.bounds", как показано ниже.
self.addObserver(self, forKeyPath: "YourView.bounds", options: .New, context: nil)
Затем обработайте его, как показано ниже.
override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
if (keyPath == "YourView.bounds") {
YourLayer.frame = YourView.bounds
return
}
super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
}
Для получения дополнительной информации см. следующую ссылку.
https://theswiftdev.com/2015/03/28/auto-layout-with-layers/
Ответ 3
Я реализовал метод layoutSubviews моего пользовательского представления; внутри этого метода я просто обновляю каждый подслойный фрейм, чтобы соответствовать текущим границам моего уровня subview.
-(void)layoutSubviews{
sublayer1.frame = self.layer.bounds;
}
Ответ 4
В соответствии с ответом this layoutSubviews
не вызывается во всех необходимых случаях. Я нашел этот метод делегата более эффективным:
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self != nil) {
[self.layer addSublayer:self.mySublayer];
}
return self;
}
- (void)layoutSublayersOfLayer:(CALayer*)layer
{
self.mySublayer.frame = self.bounds;
}
Ответ 5
У меня была аналогичная проблема: мне нужно установить кадр "CALayer" при использовании автоматической компоновки с представлениями (в коде, а не в IB).
В моем случае у меня была слегка свернутая иерархия, имеющая контроллер вида в контроллере представления. Я закончил этот вопрос SO и рассмотрел подход использования viewDidLayoutSubviews
. Это не сработало. На всякий случай ваша ситуация похожа на мою, вот что я нашел...
Обзор
Я хотел установить фрейм для CAGradientLayer
для UIView
, который я позиционировал как subview внутри UIViewController
с использованием ограничений автоматического макета.
Вызовите subview gradientView
и контроллер вида child_viewController
.
child_viewController
был контроллером представления, который я бы установил как своего рода повторно используемый компонент. Таким образом, view
of child_viewController
составлялся в родительский контроллер представления - вызывают это parent_viewController
.
Когда был вызван viewDidLayoutSubviews
of child_viewController
, frame
of gradientView
еще не установлен.
(В этот момент я бы рекомендовал разбрызгивать некоторые операторы NSLog
, чтобы получить представление о последовательности создания представлений в вашей иерархии и т.д.)
Итак, я перешел к использованию viewDidAppear
. Однако из-за вложенности child_viewController
я обнаружил, что viewDidAppear
не вызывался.
(См. этот вопрос SO: viewWillAppear, viewDidAppear не вызывается, а не стреляет).
Мое текущее решение
Я добавил viewDidAppear
в parent_viewController
и оттуда я звоню viewDidAppear
в child_viewController
.
Для начальной загрузки мне нужно viewDidAppear
, как это было до тех пор, пока в child_viewController
не будет вызвано, что все подзадачи имеют свои фреймы. Затем я могу установить рамку для CAGradientLayer
...
Я сказал, что это мое текущее решение, потому что я не очень доволен этим.
После первоначальной установки фрейма CAGradientLayer
- этот кадр может стать недействительным, если изменяется макет. вращение устройства.
Чтобы справиться с этим, я использую viewDidLayoutSubviews
в child_viewController
-, чтобы сохранить кадр CAGradientLayer
внутри gradientView
, исправить.
Он работает, но не чувствует себя хорошо.
(Есть ли лучший способ?)