Не можете установить cornerRadius AND shadow для слоя, изображение которого растянуто до границ? - PullRequest
18 голосов
/ 14 сентября 2010

Это ставит меня в тупик. У меня есть UIView (назовите это «родитель»). Самым нижним подвидом этого представления является UIImageView (назовите его «child»), чей фрейм занимает все границы «parent».

Я хочу скруглить углы на «родительском» виде и установить тень. Я делаю это на CALayer «родителя» как обычно:

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

Это правильно показывает тень, но не закругляет углы.

Вот кикер:

  1. Если я удаляю «дочернее» представление изображения или сжимаю его, чтобы он не занимал все границы «родительского» представления, я получаю закругленные углы и тень правильно на родительском.
  2. Если я оставлю "child" в покое, но установлю "clipsToBounds" в представлении "parent", я получу правильные углы. Но теперь тень ушла.
  3. Установка углового радиуса для слоя child также, похоже, не имеет никакого эффекта.

Кажется, что «дочернее» представление изображения просто затеняет скругленные углы на «родительском» представлении, поскольку оно занимает весь прямоугольник, а отсечение, основанное на родительском представлении, получает углы, но также маскирует тень. Не уверен, почему # 3 не работает.

Что мне не хватает? Я слишком долго упускал из виду что-то очевидное?

Спасибо.

(Шокирующе, тег "округлые углы-капли" уже существует. Отлично.)

Ответы [ 5 ]

21 голосов
/ 29 сентября 2011

Вам понадобятся два вложенных вида, внутренний из которых задает закругленные углы и обрезает до границы, а внешний вид имеет тень (и, следовательно, не обрезает).В вашем случае внутреннее и внешнее представление, вероятно, будут «child» и «parent», но я думаю, вы не установили правильные значения отсечения для этих представлений?

См. Ответ в Why masksToBounds =ДА предотвращает CALayer тень? .

5 голосов
/ 20 сентября 2010

Обычно вы должны установить clipsToBounds на закругленные углы, но, поскольку вы хотите сохранить тень, вы должны также закруглить углы тени. Вы пытались установить путь тени, используя путь Безье? Держите clipsToBounds / masksToBounds по умолчанию, НЕТ. Что-то вроде:

  [[parent layer] setCornerRadius:6.0f];
  [[parent layer] setShadowPath:
             [[UIBezierPath bezierPathWithRoundedRect:[parent bounds] 
                   cornerRadius:6.0f] CGPath]];
0 голосов
/ 06 января 2019

Если вам нужен теневой слой с угловым радиусом для просмотра изображений, то лучшим решением будет поместить представление изображений в виде подпредставления с полем в 1 точку .. и

 imgBrandLogo.backgroundColor = UIColor.blue
    imgBrandLogo.layer.cornerRadius = imgBrandLogo.frame.height/2
    imgBrandLogo.clipsToBounds = true
    viewBrandLogo.layer.shadowColor = UIColor(rgb:0x262626,alpha:0.24).cgColor
    viewBrandLogo.layer.shadowOffset = CGSize(width: 0, height: 1)
    viewBrandLogo.layer.shadowOpacity = 1
    viewBrandLogo.layer.shadowPath = UIBezierPath(roundedRect:imgBrandLogo.bounds , cornerRadius: imgBrandLogo.frame.height/2).cgPath
    viewBrandLogo.backgroundColor = UIColor.clear.withAlphaComponent(0.0)
0 голосов
/ 04 января 2016

С помощью Swift 3 вы можете выбрать один из двух следующих фрагментов кода, чтобы установить cornerRadius и тень на виде изображения или на виде, который содержит слой изображения.


# 1.Использование UIView, CALayer и Spring and 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.Используя UIView, UIImageView, CALayer и автоматическое расположение

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
    }

}

Оба фрагмента кода генерируют следующий экран:

enter image description here


В этом Github repo .

вы можете найти больше способов комбинировать изображения со скругленными углами и тенью.
0 голосов
/ 26 сентября 2010

Вы пытались установить границы дочернего UIImageView, чтобы он также имел закругленные углы?Возможно, тогда это не заменит тень контейнера.Просто мысль, не уверен, сработает ли это.

...