Что это лучший способ, чтобы добавить тень, чтобы мой наследник UIView



Я пытаюсь добавить тень к представлениям, которые накладываются друг на друга, представления сворачиваются, позволяя видеть контент в других представлениях, в этом ключе я хочу сохранить view.clipsToBounds ВКЛ так, что при сворачивании представлений их содержимое обрезается.



это, кажется, сделало его трудным для меня, чтобы добавить тень к слоям, как когда я поворачиваюсь clipsToBounds на тени также обрезаются.



Я пытался манипулировать view.frame и view.bounds для того чтобы добавить отбросьте тень на кадр, но позвольте границам быть достаточно большими, чтобы охватить его, однако мне не повезло с этим.



вот код, который я использую, чтобы добавить тень (это работает только с clipsToBounds выкл как показано)



view.clipsToBounds = NO;
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowOffset = CGSizeMake(0,5);
view.layer.shadowOpacity = 0.5;


вот скриншот тени, применяемой к верхнему светлому серому слою. Надеюсь, это дает представление о том, как мой контент будет перекрывать, если clipsToBounds выкл.



Shadow Application.



как я могу добавить тень к моей UIView и держать мой контент обрезанным?



Edit: просто хотел добавить, что я также играл с использованием фоновых изображений с тенями, что хорошо работает, однако я все равно хотел бы знать лучшее кодированное решение для этого.

674   6  

6 ответов:

попробуйте это:

UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:view.bounds];
view.layer.masksToBounds = NO;
view.layer.shadowColor = [UIColor blackColor].CGColor;
view.layer.shadowOffset = CGSizeMake(0.0f, 5.0f);
view.layer.shadowOpacity = 0.5f;
view.layer.shadowPath = shadowPath.CGPath;

в первую очередь: The UIBezierPath использовать как shadowPath имеет решающее значение. Если вы не используете его, вы можете не заметить разницу сначала, но острый глаз будет наблюдать определенное отставание, происходящее во время таких событий, как вращение устройства и/или подобное. Это важная настройка производительности.

что касается вашего вопроса конкретно: важная строка view.layer.masksToBounds = NO. Он отключает отсечение слой представления подслои, которые простираются дальше, чем границы этого представления.

для тех, кому интересно, в чем разница между masksToBounds (на слое) и собственный вид clipToBounds свойство: на самом деле нет. Переключение одного будет иметь эффект на другой. Просто другой уровень абстракции.


Swift 2.2:

override func layoutSubviews()
{
    super.layoutSubviews()

    let shadowPath = UIBezierPath(rect: bounds)
    layer.masksToBounds = false
    layer.shadowColor = UIColor.blackColor().CGColor
    layer.shadowOffset = CGSizeMake(0.0, 5.0)
    layer.shadowOpacity = 0.5
    layer.shadowPath = shadowPath.CGPath
}

Swift 3:

override func layoutSubviews()
{
    super.layoutSubviews()

    let shadowPath = UIBezierPath(rect: bounds)
    layer.masksToBounds = false
    layer.shadowColor = UIColor.black.cgColor
    layer.shadowOffset = CGSize(width: 0.0, height: 5.0)
    layer.shadowOpacity = 0.5
    layer.shadowPath = shadowPath.cgPath
}

ответ Васабии в Swift 2.3:

    let shadowPath = UIBezierPath(rect: view.bounds)
    view.layer.masksToBounds = false
    view.layer.shadowColor = UIColor.blackColor().CGColor
    view.layer.shadowOffset = CGSize(width: 0, height: 0.5)
    view.layer.shadowOpacity = 0.2
    view.layer.shadowPath = shadowPath.CGPath

и в Swift 3/4:

    let shadowPath = UIBezierPath(rect: view.bounds)
    view.layer.masksToBounds = false
    view.layer.shadowColor = UIColor.black.cgColor
    view.layer.shadowOffset = CGSize(width: 0, height: 0.5)
    view.layer.shadowOpacity = 0.2
    view.layer.shadowPath = shadowPath.cgPath

поместите этот код в layoutSubviews (), если вы используете AutoLayout.

трюк заключается в определении masksToBounds свойство слоя вашего представления правильно:

view.layer.masksToBounds = NO;

и это должно работать.

(источник)

вы можете создать расширение для UIView для доступа к этим значениям в Редакторе дизайна

Shadow options in design editor

extension UIView{

    @IBInspectable var shadowOffset: CGSize{
        get{
            return self.layer.shadowOffset
        }
        set{
            self.layer.shadowOffset = newValue
        }
    }

    @IBInspectable var shadowColor: UIColor{
        get{
            return UIColor(cgColor: self.layer.shadowColor!)
        }
        set{
            self.layer.shadowColor = newValue.cgColor
        }
    }

    @IBInspectable var shadowRadius: CGFloat{
        get{
            return self.layer.shadowRadius
        }
        set{
            self.layer.shadowRadius = newValue
        }
    }

    @IBInspectable var shadowOpacity: Float{
        get{
            return self.layer.shadowOpacity
        }
        set{
            self.layer.shadowOpacity = newValue
        }
    }
}

вы можете установить тень на ваш вид из раскадровки также

enter image description here

на viewWillLayoutSubviews:

override func viewWillLayoutSubviews() {
    sampleView.layer.masksToBounds =  false
    sampleView.layer.shadowColor = UIColor.darkGrayColor().CGColor;
    sampleView.layer.shadowOffset = CGSizeMake(2.0, 2.0)
    sampleView.layer.shadowOpacity = 1.0
}

используя расширение UIView:

extension UIView {

    func addDropShadowToView(targetView:UIView? ){
        targetView!.layer.masksToBounds =  false
        targetView!.layer.shadowColor = UIColor.darkGrayColor().CGColor;
        targetView!.layer.shadowOffset = CGSizeMake(2.0, 2.0)
        targetView!.layer.shadowOpacity = 1.0
    }
}

использование:

sampleView.addDropShadowToView(sampleView)

Comments

    Ничего не найдено.