2017-01-17 6 views
1

私のビューコントローラは3つのボタンを持つスタックビューを持っています。 1つは中央に固定幅で固定され、スタックビューは他の2つのボタンが対称になるように比例して設定されます。Swift 3 - カスタムUIButton半径で制約が削除されますか?

しかし、ボタンのコーナー半径をカスタマイズしていて、アプリケーションがロードするとすぐにボタンが望ましくない形でサイズ変更されます。

Iveは、多数のスタックビューの配布と埋め込み設定を試みました。スタックビューからボタンを削除し、単純に通常のUIViewのエッジに拘束しようとしているようですが、制約が削除されるかどうかわかりません。

視覚的には、ボタンは画面の右下隅にあり、エッジとボタンの間に0のスペースがあります。現在は、複数のデバイスに見えるような制約がないような方法でレイアウトされ、大きなディスプレイにスペースがあり、シミュレータ内の小さなディスプレイで画面を終了します。

@IBOutlet fileprivate weak var button: UIButton! { didSet { 
    button.round(corners: [.topRight, .bottomLeft], radius: 50 , borderColor: UIColor.blue, borderWidth: 5.0) 
    button.setNeedsUpdateConstraints() 
    button.setNeedsLayout() 
} } 

override func viewDidLayoutSubviews() { 
    button.layoutIfNeeded() 
} 

ovverride func updateViewContraints() { 
    button.updateConstraintsIfNeeded() 
    super.updateViewConstraints() 
} 

使用されているUIViewの拡張子はここで見つけることができます: https://stackoverflow.com/a/35621736/5434541

適切にボタンのコーナー半径を調整するために利用されどのような解決策必要な角を丸めるための努力をコーディングしようとしました

制約がボタンを必要に応じて更新できるようにします。

+0

両方の方法で同じ動作をしますか? – Ben

+0

@Benはい、私は試みられたすべてのメソッドで同じ動作をします。現在のところ、これはシミュレータで発生しており、iPhone 5でテストしたところ、私が望むように動作しているように見えますが、このような予期せぬ動作によって、他のデバイスで発生する可能性があるかどうかわからなくなってしまいました。また、私はこれらのメソッドを実装するとすぐに、アプリケーションは現在多くの遅れている!私は特定の質問には関係ないと知っていますが、viewDidlayoutのサブビューを別のスレッドで実行する必要があるのか​​不思議です。ありがとう! – lifewithelliott

答えて

0

あなたの完全なコードを見ることなく、私はあなたが境界を持つ複数のレイヤーを描いているので、あなたがこれを得ていると思う!ボタンのサイズが変更されると、古いレイヤーはそのまま残ります。ここでは、再描画時に古いレイヤーを取り除くことができるスナップがあります。私はこれをスタックビューの中でテストし、ローテーション時にも正しく動作します。

class RoundedCorner: UIButton { 

    var lastBorderLayer:CAShapeLayer? 
    override func layoutSubviews() { setup() } 

    func setup() { 
     let r = self.bounds.size.height/2 
     let path = UIBezierPath(roundedRect: self.bounds, 
           byRoundingCorners: [.topLeft, .bottomRight], 
           cornerRadii: CGSize(width: r, height: r)) 
     let mask = CAShapeLayer() 
     mask.path = path.cgPath 
     addBorder(mask: mask, borderColor: UIColor.blue, borderWidth: 5) 
     self.layer.mask = mask 
    } 

    func addBorder(mask: CAShapeLayer, borderColor: UIColor, borderWidth: CGFloat) { 
     let borderLayer = CAShapeLayer() 
     borderLayer.path = mask.path 
     borderLayer.fillColor = UIColor.clear.cgColor 
     borderLayer.strokeColor = borderColor.cgColor 
     borderLayer.lineWidth = borderWidth 
     borderLayer.frame = bounds 
     if let last = self.lastBorderLayer, let index = layer.sublayers?.index(of: last) { 
      layer.sublayers?.remove(at: index) 
     } 
     layer.addSublayer(borderLayer) 
     self.lastBorderLayer = borderLayer 
    } 
} 

また、アプリラグについてのコメントでも触れました。レイアウトごとに更新が何度も呼び出されることがあり、毎回新しいレイヤーを作成しているので、私は驚くことではありません。これを回避するには、ボトルトンフレームの最後のサイズを保存して比較します。同一の場合は、レイヤーを再作成しないでください。

+0

私はあなたのRoundedCornerクラスを実装しようとしていましたが、元の質問で私の最後に何か間違っているかもしれないというあなたのコードを読んだ後に感じました。そこで私はもう少し研究して、上記の質問を編集して結果を更新しました。あなたの答えが私を正しい方向に導いてくれるので、私は助けに非常に感謝します。 – lifewithelliott

+0

編集した内容が不明な場合は、ボタンクラス全体を共有できますか? – Ben

+0

ボタンは、ビューコントローラに接続されたストーリーボードボタンです。カスタムサブクラス化されたボタンは作成されません。アプリケーションが実行され、ボタンがセットされるとすぐにdidSetは 'round()'メソッドを呼び出し、 'setNeeds()'メソッドは 'viewDidUpdateLayoutSubviews()'が呼び出されたときにレイアウトを更新するようコントローラに指示します。私はそのことがどうなるかを信じています。 – lifewithelliott

関連する問題