18

これは私を困惑させています。UIView があります(「親」と呼びます)。そのビューの一番下のサブビューは UIImageView (「子」と呼びます) であり、そのフレームは「親」境界全体を占有します。

「親」ビューの角を丸くして、ドロップシャドウを設定したい。CALayerいつものように「親」でこれを行います:

[[parent layer] setShadowOffset:CGSizeMake(5, 5)];
[[parent layer] setShadowRadius:6];
[[parent layer] setShadowOpacity:0.4];    
[[parent layer] setCornerRadius:6];

これにより、影が正しく表示されますが、角が丸くなりません。

キッカーは次のとおりです。

  1. 「子」イメージ ビューを削除するか、縮小して「親」ビューの境界全体を占有しないようにすると、親で丸みを帯びた角と影が正しく表示されます。
  2. 「子」をそのままにして「親」ビューに「clipsToBounds」を設定すると、コーナーが正しく表示されます。でも今は影がなくなった。
  3. のレイヤーにコーナー半径を設定しても効果がないようです。

「子」画像ビューは、「親」ビューの丸みを帯びた角を覆い隠しているように見えます。これは、四角形全体を占有し、親ビューに基づくクリッピングが角を取得するだけでなく、影をマスクするためです。#3が機能しない理由がわかりません。

私は何が欠けていますか?あまりにも長い間これを見つめて、何か明白なことを見落としていませんか?

ありがとう。

(驚いたことに、「roundedcorners-dropshadow」というタグは既に存在します。素晴らしいです。)

4

5 に答える 5

22

2 つの入れ子になったビューが必要です。内側のビューは角を丸くしてクリッピングを境界に設定し、外側のビューには影を付けます (したがって、クリッピングは行いません)。あなたの場合、内側と外側のビューはおそらく「子」と「親」になりますが、これらのビューに適切なクリッピング値を設定していないと思いますか?

答えは、masksToBounds = YES で CALayer のシャドウが妨げられる理由を参照してください。.

于 2011-09-29T19:56:38.607 に答える
5

通常は clipsToBounds を設定して角を丸くする必要がありますが、影を保持したいので影の角も丸くする必要があります。ベジエ パスを使用してシャドウ パスを設定しようとしましたか? clipsToBounds/masksToBounds をデフォルトの NO のままにします。何かのようなもの:

  [[parent layer] setCornerRadius:6.0f];
  [[parent layer] setShadowPath:
             [[UIBezierPath bezierPathWithRoundedRect:[parent bounds] 
                   cornerRadius:6.0f] CGPath]];
于 2010-09-20T15:45:46.293 に答える
0

Have you tried setting the bounds of the child UIImageView so that it also has rounded corners? Perhaps then it wouldn't override the shadow of the container view. Just a thought, not sure if it will work.

于 2010-09-26T13:36:34.867 に答える
0

Swift 3 では、次の 2 つのコード スニペットのいずれかを選択して、イメージ ビューまたはイメージ レイヤーを含むビューで cornerRadius とシャドウを設定できます。


#1。UIViewCALayerおよび Spring と Strutsの使用

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // constants
        let radius: CGFloat = 20, dimension: CGFloat = 200, offset = 8
        let frame = CGRect(x: 0, y: 0, width: 200, height: 200)

        // custom view
        let customView = UIView(frame: frame)
        customView.contentMode = .scaleAspectFill

        // image layer
        let imageLayer = CALayer()
        imageLayer.contentsGravity = kCAGravityResizeAspectFill
        imageLayer.contents = UIImage(named: "image")!.cgImage
        imageLayer.masksToBounds = true
        imageLayer.frame = frame
        imageLayer.cornerRadius = radius
        imageLayer.masksToBounds = true

        // rounded layer
        let roundedLayer = CALayer()
        roundedLayer.shadowColor = UIColor.darkGray.cgColor
        roundedLayer.shadowPath = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: dimension, height: dimension), cornerRadius: radius).cgPath
        roundedLayer.shadowOffset = CGSize(width: offset, height: offset)
        roundedLayer.shadowOpacity = 0.8
        roundedLayer.shadowRadius = 2
        roundedLayer.frame = frame

        // views and layers hierarchy
        customView.layer.addSublayer(imageLayer)
        customView.layer.insertSublayer(roundedLayer, below: imageLayer)
        view.addSubview(customView)

        // layout
        customView.center = CGPoint(x: view.bounds.midX, y: view.bounds.midY)
        customView.autoresizingMask = [UIViewAutoresizing.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin, .flexibleBottomMargin]
    }

}

#2。UIViewUIImageViewCALayerおよび自動レイアウトの使用

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // constants
        let radius: CGFloat = 20, dimension: CGFloat = 200, offset = 8

        // image view
        let imageView = UIImageView(image: UIImage(named: "image"))
        imageView.contentMode = .scaleAspectFill
        imageView.layer.cornerRadius = radius
        imageView.layer.masksToBounds = true

        // rounded view
        let roundedView = UIView()
        roundedView.layer.shadowColor = UIColor.darkGray.cgColor
        roundedView.layer.shadowPath = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: dimension, height: dimension), cornerRadius: radius).cgPath
        roundedView.layer.shadowOffset = CGSize(width: offset, height: offset)
        roundedView.layer.shadowOpacity = 0.8
        roundedView.layer.shadowRadius = 2

        // views hierarchy
        roundedView.addSubview(imageView)
        view.addSubview(roundedView)

        // layout
        imageView.translatesAutoresizingMaskIntoConstraints = false
        roundedView.translatesAutoresizingMaskIntoConstraints = false
        roundedView.widthAnchor.constraint(equalToConstant: dimension).isActive = true
        roundedView.heightAnchor.constraint(equalToConstant: dimension).isActive = true
        imageView.widthAnchor.constraint(equalTo: roundedView.widthAnchor).isActive = true
        imageView.heightAnchor.constraint(equalTo: roundedView.heightAnchor).isActive = true
        roundedView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        roundedView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        imageView.centerXAnchor.constraint(equalTo: roundedView.centerXAnchor).isActive = true
        imageView.centerYAnchor.constraint(equalTo: roundedView.centerYAnchor).isActive = true
    }

}

どちらのコード スニペットも、次の表示を生成します。

ここに画像の説明を入力


このGithub repoで、角の丸い画像と影を組み合わせる方法をさらに見つけることができます。

于 2016-01-03T22:01:57.393 に答える