Rápido

// corner radius
blueView.layer.cornerRadius = 10
// border
blueView.layer.borderWidth = 1.0
blueView.layer.borderColor = UIColor.black.cgColor
// shadow
blueView.layer.shadowColor = UIColor.black.cgColor
blueView.layer.shadowOffset = CGSize(width: 3, height: 3)
blueView.layer.shadowOpacity = 0.7
blueView.layer.shadowRadius = 4.0
Explorando as opções





Problema 1: a sombra é cortada
E se houver subcamadas ou subvisões (como uma imagem) cujo conteúdo queremos recortar nos limites de nossa visão?

Podemos conseguir isso com
blueView.layer.masksToBounds = true
(Como alternativa, blueView.clipsToBounds = true
fornece o mesmo resultado .)

Mas oh não! A sombra também foi cortada porque está fora dos limites! O que fazer? O que fazer?
Solução
Use vistas separadas para a sombra e a borda. A vista base é transparente e tem a sombra. A vista de borda recorta qualquer outro subcontente que possui em suas bordas.
// add the shadow to the base view
baseView.backgroundColor = UIColor.clear
baseView.layer.shadowColor = UIColor.black.cgColor
baseView.layer.shadowOffset = CGSize(width: 3, height: 3)
baseView.layer.shadowOpacity = 0.7
baseView.layer.shadowRadius = 4.0
// add the border to subview
let borderView = UIView()
borderView.frame = baseView.bounds
borderView.layer.cornerRadius = 10
borderView.layer.borderColor = UIColor.black.cgColor
borderView.layer.borderWidth = 1.0
borderView.layer.masksToBounds = true
baseView.addSubview(borderView)
// add any other subcontent that you want clipped
let otherSubContent = UIImageView()
otherSubContent.image = UIImage(named: "lion")
otherSubContent.frame = borderView.bounds
borderView.addSubview(otherSubContent)
Isso fornece o seguinte resultado:

Problema 2: Baixo desempenho
Adicionar cantos e sombras arredondados pode ser um sucesso. Você pode melhorar o desempenho usando um caminho predefinido para a sombra e também especificando que ela seja rasterizada. O código a seguir pode ser adicionado ao exemplo acima.
baseView.layer.shadowPath = UIBezierPath(roundedRect: baseView.bounds, cornerRadius: 10).cgPath
baseView.layer.shouldRasterize = true
baseView.layer.rasterizationScale = UIScreen.main.scale
Veja este post para mais detalhes. Veja aqui e aqui também.
Esta resposta foi testada com Swift 4 e Xcode 9.