重ねて表示されるビューにドロップシャドウを追加しようとしています。ビューが折りたたまれて、他のビューのコンテンツが表示されます。このように、ビューが折りたたまれたときにview.clipsToBounds
ONを維持しますそれらのコンテンツはクリップされます。
これにより、clipsToBounds
をオンにすると影もクリップされるため、レイヤーにドロップシャドウを追加することが困難になったようです。
フレームにドロップシャドウを追加するためにview.frame
とview.bounds
を操作しようとしましたが、境界がそれを囲むのに十分な大きさになるようにしましたが、これには運がありませんでした。
以下は、シャドウを追加するために使用しているコードです(これは、示されているclipsToBounds
OFFでのみ機能します)
view.clipsToBounds = NO;
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowOffset = CGSizeMake(0,5);
view.layer.shadowOpacity = 0.5;
これは、最も明るい灰色のレイヤーに適用される影のスクリーンショットです。 clipsToBounds
がOFFの場合、これが私のコンテンツがどのようにオーバーラップするかのアイデアを与えてくれることを願っています。
UIView
に影を追加して、コンテンツをクリップしたままにするにはどうすればよいですか?
編集:影付きの背景画像を使用して遊んだことを追加したかっただけですが、これはうまく機能しますが、これに最適なコード化されたソリューションを知りたいです。
これを試して:
UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:view.bounds];
view.layer.masksToBounds = NO;
view.layer.shadowColor = [UIColor blackColor].CGColor;
view.layer.shadowOffset = CGSizeMake(0.0f, 5.0f);
view.layer.shadowOpacity = 0.5f;
view.layer.shadowPath = shadowPath.CGPath;
まずは:UIBezierPath
として使用されるshadowPath
は重要です。それを使用しない場合、最初は違いに気付かないかもしれませんが、鋭い目は、デバイスの回転などのイベント中に発生する特定の遅延を観察します。これは重要なパフォーマンス調整です。
特に問題に関して:重要な行はview.layer.masksToBounds = NO
です。ビューの境界よりも遠くに広がるビューのレイヤーのサブレイヤーのクリッピングを無効にします。
masksToBounds
(レイヤー上)とビュー自身のclipToBounds
プロパティの違いは何なのか疑問に思う人のために:実際には何もありません。一方を切り替えると、もう一方に影響があります。異なるレベルの抽象化。
Swift 2.2:
override func layoutSubviews()
{
super.layoutSubviews()
let shadowPath = UIBezierPath(rect: bounds)
layer.masksToBounds = false
layer.shadowColor = UIColor.blackColor().CGColor
layer.shadowOffset = CGSizeMake(0.0, 5.0)
layer.shadowOpacity = 0.5
layer.shadowPath = shadowPath.CGPath
}
スウィフト3:
override func layoutSubviews()
{
super.layoutSubviews()
let shadowPath = UIBezierPath(rect: bounds)
layer.masksToBounds = false
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0.0, height: 5.0)
layer.shadowOpacity = 0.5
layer.shadowPath = shadowPath.cgPath
}
Swift 2.3のWasabiiの回答:
let shadowPath = UIBezierPath(rect: view.bounds)
view.layer.masksToBounds = false
view.layer.shadowColor = UIColor.blackColor().CGColor
view.layer.shadowOffset = CGSize(width: 0, height: 0.5)
view.layer.shadowOpacity = 0.2
view.layer.shadowPath = shadowPath.CGPath
Swift 3/4で:
let shadowPath = UIBezierPath(rect: view.bounds)
view.layer.masksToBounds = false
view.layer.shadowColor = UIColor.black.cgColor
view.layer.shadowOffset = CGSize(width: 0, height: 0.5)
view.layer.shadowOpacity = 0.2
view.layer.shadowPath = shadowPath.cgPath
AutoLayoutを使用している場合、このコードをlayoutSubviews()に配置します。
UIViewの拡張機能を作成して、デザインエディターでこれらの値にアクセスできます。
extension UIView{
@IBInspectable var shadowOffset: CGSize{
get{
return self.layer.shadowOffset
}
set{
self.layer.shadowOffset = newValue
}
}
@IBInspectable var shadowColor: UIColor{
get{
return UIColor(cgColor: self.layer.shadowColor!)
}
set{
self.layer.shadowColor = newValue.cgColor
}
}
@IBInspectable var shadowRadius: CGFloat{
get{
return self.layer.shadowRadius
}
set{
self.layer.shadowRadius = newValue
}
}
@IBInspectable var shadowOpacity: Float{
get{
return self.layer.shadowOpacity
}
set{
self.layer.shadowOpacity = newValue
}
}
}
ViewWillLayoutSubviewsの場合:
override func viewWillLayoutSubviews() {
sampleView.layer.masksToBounds = false
sampleView.layer.shadowColor = UIColor.darkGrayColor().CGColor;
sampleView.layer.shadowOffset = CGSizeMake(2.0, 2.0)
sampleView.layer.shadowOpacity = 1.0
}
UIViewの拡張機能を使用:
extension UIView {
func addDropShadowToView(targetView:UIView? ){
targetView!.layer.masksToBounds = false
targetView!.layer.shadowColor = UIColor.darkGrayColor().CGColor;
targetView!.layer.shadowOffset = CGSizeMake(2.0, 2.0)
targetView!.layer.shadowOpacity = 1.0
}
}
使用法:
sampleView.addDropShadowToView(sampleView)
そのため、パフォーマンスのためにshadowPathプロパティを優先する必要がありますが、以下も必要です:CALayer.shadowPathのヘッダーファイルから
このプロパティを使用してパスを明示的に指定すると、通常、同じパスを共有する*複数のレイヤーで参照を行うため、レンダリングのパフォーマンスが向上します。
あまり知られていないトリックは、複数のレイヤー間で同じ参照を共有することです。もちろん同じ形状を使用する必要がありますが、これはテーブル/コレクションビューのセルで一般的です。
インスタンスを共有するとなぜ高速になるのかわかりませんが、シャドウのレンダリングをキャッシュし、ビュー内の他のインスタンスに再利用できると推測しています。私はこれがさらに速くなるのだろうか