Нарисуйте тень только с трех сторон UIView
Я успешно реализовал рисование тени вокруг моего UIView
следующим образом:
block1.layer.masksToBounds = NO;
block1.layer.shadowOffset = CGSizeMake(0, 0);
block1.layer.shadowRadius = 1;
block1.layer.shadowOpacity = 0.7;
Что происходит, у меня есть прямоугольник UIView
, и я бы хотел нарисовать тень вокруг него с трех сторон, оставив нижнюю сторону без тени.
Я знаю, что я должен указать block1.layer.shadowPath
, создав новый UIBezierPath
, но я не уверен, как это сделать.
Очевидно, что установка layer.shadowOffset
не сделает трюк для меня.
Спасибо заранее!
Ответы
Ответ 1
Я знаю, что вы говорите, что настройка layer.shadowOffset
не сработает для вас, но вам разрешено указывать отрицательные значения, поэтому установка layer.shadowOffset = CGSizeMake(0.0, -2.0)
будет близка к тому эффекту, который вы ищете, но, конечно, я ожидаю, что вы хотите, чтобы он был даже с трех сторон.
Итак, перейдем к layer.shadowPath
!
UIView *block1 = [[UIView alloc] initWithFrame:CGRectMake(32.0, 32.0, 128.0, 128.0)];
[block1 setBackgroundColor:[UIColor orangeColor]];
[self.view addSubview:block1];
block1.layer.masksToBounds = NO;
block1.layer.shadowOffset = CGSizeMake(0, 0);
block1.layer.shadowRadius = 1;
block1.layer.shadowOpacity = 0.7;
UIBezierPath *path = [UIBezierPath bezierPath];
// Start at the Top Left Corner
[path moveToPoint:CGPointMake(0.0, 0.0)];
// Move to the Top Right Corner
[path addLineToPoint:CGPointMake(CGRectGetWidth(block1.frame), 0.0)];
// Move to the Bottom Right Corner
[path addLineToPoint:CGPointMake(CGRectGetWidth(block1.frame), CGRectGetHeight(block1.frame))];
// This is the extra point in the middle :) Its the secret sauce.
[path addLineToPoint:CGPointMake(CGRectGetWidth(block1.frame) / 2.0, CGRectGetHeight(block1.frame) / 2.0)];
// Move to the Bottom Left Corner
[path addLineToPoint:CGPointMake(0.0, CGRectGetHeight(block1.frame))];
// Move to the Close the Path
[path closePath];
block1.layer.shadowPath = path.CGPath;
И чтобы дать вам представление о том, что происходит, вот реальный теневой путь, который вы только что нарисовали:)
![enter image description here]()
Его можно просто сдвинуть эту дополнительную среднюю точку до или после других строк, чтобы выбрать, какая сторона будет опущена.
Ответ 2
Обновление Ryan Poolos Ответ на Swift 3.0
Благодаря Ryan Poolos
class sampleViewController: UIViewController {
var block1: UIView! = nil
override func viewDidLoad() {
super.viewDidLoad()
block1 = UIView(frame: CGRect(x: 32.0, y: 32.0, width: 128.0, height: 128.0))
block1.backgroundColor = UIColor.orange
self.view.addSubview(block1)
block1.layer.masksToBounds = false
block1.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
block1.layer.shadowRadius = 1.0
block1.layer.shadowOpacity = 0.7
let path = UIBezierPath()
// Start at the Top Left Corner
path.move(to: CGPoint(x: 0.0, y: 0.0))
// Move to the Top Right Corner
path.addLine(to: CGPoint(x: block1.frame.size.width, y: 0.0))
// Move to the Bottom Right Corner
path.addLine(to: CGPoint(x: block1.frame.size.width, y: block1.frame.size.height))
// This is the extra point in the middle :) Its the secret sauce.
path.addLine(to: CGPoint(x: block1.frame.size.width/2.0, y: block1.frame.size.height/2.0))
// Move to the Bottom Left Corner
path.addLine(to: CGPoint(x: 0.0, y: block1.frame.size.height))
path.close()
block1.layer.shadowPath = path.cgPath
}
}
Результат:
![введите описание изображения здесь]()
Ответ 3
Несколько улучшений для других ответов, благодаря Ashok R для быстрого кода.
Поскольку мы создавали треугольный вид на фоне представления с тенью со всех сторон, а белый треугольник на тенях сторон не нужен.
Он разбивается в случае представлений с шириной, сравнительно большей, чем высота.
![введите описание изображения здесь]()
Обходной путь будет состоять в том, чтобы переместить путь для линии, где тень не нужна немного по направлению к этой стороне представления, вместо того, чтобы полностью создать треугольный вид..
Я создал расширение для этого -
extension UIView {
func addshadow(top: Bool,
left: Bool,
bottom: Bool,
right: Bool,
shadowRadius: CGFloat = 2.0) {
self.layer.masksToBounds = false
self.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
self.layer.shadowRadius = shadowRadius
self.layer.shadowOpacity = 1.0
let path = UIBezierPath()
var x: CGFloat = 0
var y: CGFloat = 0
var viewWidth = self.frame.width
var viewHeight = self.frame.height
// here x, y, viewWidth, and viewHeight can be changed in
// order to play around with the shadow paths.
if (!top) {
y+=(shadowRadius+1)
}
if (!bottom) {
viewHeight-=(shadowRadius+1)
}
if (!left) {
x+=(shadowRadius+1)
}
if (!right) {
viewWidth-=(shadowRadius+1)
}
// selecting top most point
path.move(to: CGPoint(x: x, y: y))
// Move to the Bottom Left Corner, this will cover left edges
/*
|☐
*/
path.addLine(to: CGPoint(x: x, y: viewHeight))
// Move to the Bottom Right Corner, this will cover bottom edge
/*
☐
-
*/
path.addLine(to: CGPoint(x: viewWidth, y: viewHeight))
// Move to the Top Right Corner, this will cover right edge
/*
☐|
*/
path.addLine(to: CGPoint(x: viewWidth, y: y))
// Move back to the initial point, this will cover the top edge
/*
_
☐
*/
path.close()
self.layer.shadowPath = path.cgPath
}
и установите логическое значение true для той стороны, в которой вы хотите, чтобы тень отображалась
myView.addshadow(top: false, left: true, bottom: true, right: true, shadowRadius: 2.0)
//теневой радиус является необязательным выше и устанавливается по умолчанию на 2.0
![введите описание изображения здесь]()
или
myView.addshadow(top: true, left: true, bottom: true, right: true, shadowRadius: 2.0)
![введите описание изображения здесь]()
или
myView.addshadow(top: false, left: false, bottom: true, right: true, shadowRadius: 2.0)
![введите описание изображения здесь]()