Невозможно установить cornerRadius AND shadow на слой, который имеет изображение, растянутое до его границ?
Это толкает меня. У меня есть UIView (назовите его "parent" ). В нижней части этого представления находится UIImageView (назовите его "child" ), чей фрейм занимает всю полноту "родительских" границ.
Я хочу обогнуть углы на "родительском" представлении и установить тень. Я делаю это на CALayer
"родителя", как обычно:
[[parent layer] setShadowOffset:CGSizeMake(5, 5)];
[[parent layer] setShadowRadius:6];
[[parent layer] setShadowOpacity:0.4];
[[parent layer] setCornerRadius:6];
Это показывает тень правильно, но не вокруг углов.
Здесь кикер:
- Если я удаляю представление "дочерний" образ или сокращаю его, чтобы он не занимал все границы "родительского" представления, я получаю закругленные углы и тень правильно на родительском объекте.
- Если я оставляю только "ребенка", но устанавливаю "clipToBounds" в "родительском" представлении, я правильно получаю углы. Но теперь тень ушла.
- Настройка радиуса угла на слое ребенка также не имеет эффекта.
Похоже, что "образ ребенка" просто скрывает закругленные углы на "родительском" представлении, так как он занимает весь прямоугольник, а обрезка на основе родительского представления получает углы, но также маскирует тень. Не знаете, почему № 3 не работает.
Что мне не хватает? Разве я не замечал ничего очевидного, слишком долго смотрел на это?
Спасибо.
(Потрясающе, тег "roundedcorners-dropshadow" уже существует. Awesome.)
Ответы
Ответ 1
Вам понадобятся два вложенных вида, внутренний - с закругленными углами и отсечением для привязки, а внешний вид имеет тень (и, следовательно, не отсекает). В вашем случае внутренний и внешний вид, вероятно, будут "child" и "parent", но я думаю, вы не установили правильные значения отсечения для этих представлений?
См. ответ в Почему masksToBounds = YES предотвращает тень CALayer?.
Ответ 2
Как правило, вы должны установить clipToBounds для округлых углов, но поскольку вы хотите сохранить тень, вы также должны окружать углы тени. Пробовали ли вы установить путь тени, используя путь безье? Держите клипсыToBounds/masksToBounds по умолчанию, NO. Что-то вроде:
[[parent layer] setCornerRadius:6.0f];
[[parent layer] setShadowPath:
[[UIBezierPath bezierPathWithRoundedRect:[parent bounds]
cornerRadius:6.0f] CGPath]];
Ответ 3
Вы пытались установить границы дочернего UIImageView так, чтобы он также имел закругленные углы? Возможно, тогда он не переопределит тень контейнера. Просто мысль, не уверен, что это сработает.
Ответ 4
С помощью Swift 3 вы можете выбрать один из двух следующих фрагментов кода, чтобы установить cornerRadius и тень на изображении или в представлении, содержащем слой изображения.
# 1. Используя UIView
, CALayer
и 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. Используя 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
}
}
Оба фрагмента кода генерируют следующий экран:
![введите описание изображения здесь]()
Вы можете найти больше способов комбинировать изображения с закругленными углами и тенью на этом Github repo.