こんにちは、私は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];
IBの編集テキストにいくつかの制約を設定して、デバイスを回転させると、それに応じてテキストフィールドの幅が調整されるようにします。私の問題は、編集テキストに設定したCALayerの幅を調整せずに、編集テキストの幅を調整することです。したがって、CALayerアイテムにもいくつかの制約を設定する必要があると思います。しかし、私はそれを行う方法を知りません。これについて知っている人はいますか?助けが必要。ありがとうございました。
自動サイズ変更ビジネス全体がビュー固有です。レイヤーは自動サイズ変更されません。
コードで行う必要があるのは、自分でレイヤーのサイズを変更することです
例えば.
あなたがするviewControllerで
- (void) viewDidLayoutSubviews {
[super viewDidLayoutSubviews]; //if you want superclass's behaviour...
// resize your layers based on the view's new frame
self.editViewBorderLayer.frame = self.editView.bounds;
}
または使用できるカスタムUIViewで
- (void)layoutSubviews {
[super layoutSubviews]; //if you want superclass's behaviour... (and lay outing of children)
// resize your layers based on the view's new frame
layer.frame = self.bounds;
}
このソリューションをチェックしてください。以下に示すように、パス「YourView.bounds」にKVOを使用します。
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)
}
詳細については、次のリンクを参照してください。
カスタムビューのメソッドlayoutSubviewsを実装しました。このメソッド内では、サブビューのレイヤーの現在の境界に一致するように各サブレイヤーのフレームを更新するだけです。
-(void)layoutSubviews{
sublayer1.frame = self.layer.bounds;
}
this answerによると、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;
}
破線枠で作成するときの私の解決策
class DashedBorderView: UIView {
let dashedBorder = CAShapeLayer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
//custom initialization
dashedBorder.strokeColor = UIColor.red.cgColor
dashedBorder.lineDashPattern = [2, 2]
dashedBorder.frame = self.bounds
dashedBorder.fillColor = nil
dashedBorder.cornerRadius = 2
dashedBorder.path = UIBezierPath(rect: self.bounds).cgPath
self.layer.addSublayer(dashedBorder)
}
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
dashedBorder.path = UIBezierPath(rect: self.bounds).cgPath
dashedBorder.frame = self.bounds
}
}
Swift 3.x KVO Solution(@ arango_86の回答を更新)
オブザーバーを追加
self.addObserver(
self,
forKeyPath: "<YOUR_VIEW>.bounds",
options: .new,
context: nil
)
値を監視
override open func observeValue(
forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?
) {
if (keyPath == "<YOUR_VIEW.bounds") {
updateDashedShapeLayerFrame()
return
}
super.observeValue(
forKeyPath: keyPath,
of: object,
change: change,
context: context
)
}