UIView із закругленими кутами та тінню?


389

Я хочу користувальницький UIView…: Я просто хотів порожній білий вид із закругленими кутами та світлою тіньою краплі (без освітлювального ефекту). Я можу зробити кожен з них по одному, але трапляються звичайні clipToBounds/ maskToBoundsконфлікти.


1
Оскільки в коментарі нижче ви говорите, що ви працювали за допомогою CoreGraphics, чи не заперечуєте ви поділитися відповіддю з громадою, щоб ви могли допомогти іншим у тій же ситуації, коли вони намагалися допомогти вам?
lnafziger

Вибачте, це було досить давно, і у мене вже немає джерела. Що я зробив, було переосмислено -drawRect: і використати UIBezierPath, щоб намалювати прямокутник, і нанести тінь на шар, що підтримує подання ... якщо я правильно пам'ятаю. :)
Aditya Vaidyam

5
Прийнята відповідь не працює!
onmyway133


1
@Sachavijay Ви повинні перевірити дати обох публікацій, перш ніж коментувати.
Адітя Вайдям

Відповіді:


444

Наступний фрагмент коду додає рамку, радіус кордону і тіні для v, UIView:

// border radius
[v.layer setCornerRadius:30.0f];

// border
[v.layer setBorderColor:[UIColor lightGrayColor].CGColor];
[v.layer setBorderWidth:1.5f];

// drop shadow
[v.layer setShadowColor:[UIColor blackColor].CGColor];
[v.layer setShadowOpacity:0.8];
[v.layer setShadowRadius:3.0];
[v.layer setShadowOffset:CGSizeMake(2.0, 2.0)];

Ви можете налаштувати налаштування відповідно до ваших потреб.

Також додайте рамки QuartzCore до свого проекту та:

#import <QuartzCore/QuartzCore.h>

Дивіться мою іншу відповідь щодо masksToBounds.


Примітка

Це може працювати не у всіх випадках. Якщо ви виявите, що цей метод перешкоджає виконанню інших операцій з малювання, перегляньте цю відповідь .


83
Ну і проблема в тому, що коли я встановлюю радіус кута, він встановлює maskToBounds: ТАК, тоді як тінь вимагає clipToBounds: НЕ (де clipToBounds робить те саме, що і maskToBounds)
Aditya Vaidyam

15
та ж проблема тут. Якщо у мене колір тла, я хочу, щоб він був прикріплений до закруглених кутів. Для цього мені потрібно використовувати maskToBounds = ІСТИНА, але тоді тінь зникає ..
hfossli

3
Для новачків, як я: мені довелося імпортувати рамку QuartzCore у свій проект, щоб викликати методи на об’єкті шару.
SilithCrowe

38
Спосіб отримати цю роботу правильного шлях полягає у використанні внутрішнього вигляду контейнера, який буде будинок вашої кордону і кольору фону, як з кутовим радіусом. Цей погляд буде вирізаний до меж! Другий, зовнішній вигляд контейнера, розмістить перший, має той самий каркас, з просто тінню. Я робив це досить декілька разів, щоб поєднати облямівку, тінь і радіус кута. Це дійсно дратує, але це працює дуже добре.
Kpmurphy91

23
Не працює. Не знаю, чому так багато голосів. Чи було це застосовано в старих версіях?
Ярнео

627

Швидкий

введіть тут опис зображення

// 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

Вивчення варіантів

введіть тут опис зображення

введіть тут опис зображення

введіть тут опис зображення

введіть тут опис зображення

введіть тут опис зображення

Проблема 1: Тінь знімається

Що робити, якщо є підшари або підзагляди (як зображення), вміст яких ми хочемо відключити до меж нашого погляду?

введіть тут опис зображення

Ми можемо досягти цього за допомогою

blueView.layer.masksToBounds = true

(Крім того, blueView.clipsToBounds = trueдає такий же результат .)

введіть тут опис зображення

Але, о ні! Тінь також була обрізана, бо це поза межами меж! Що робити? Що робити?

Рішення

Використовуйте окремі види для тіні та межі. Вигляд основи прозорий і має тінь. Перегляд кордону вирізає будь-який інший зміст, який він має до меж.

// 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)

Це дає такий результат:

введіть тут опис зображення

Проблема 2: Погана продуктивність

Додавання округлих кутів і тіней може стати хітом для продуктивності. Ви можете покращити продуктивність, використовуючи заздалегідь визначений шлях для тіні, а також вказавши, що він буде растрований. У наведеному вище прикладі можна додати наступний код.

baseView.layer.shadowPath = UIBezierPath(roundedRect: baseView.bounds, cornerRadius: 10).cgPath
baseView.layer.shouldRasterize = true
baseView.layer.rasterizationScale = UIScreen.main.scale

Докладнішу інформацію див. У цій публікації . Дивіться тут і тут також.

Цю відповідь було перевірено за допомогою Swift 4 та Xcode 9.


1
@ EICaptainv2.0. Якщо ви хочете лише рамку (та / або радіус кута), вам не потрібен окремий вигляд. Окремий вигляд - це ситуація, коли потрібні круглі кути та тінь .
Сурагч

2
Це не працює для мене. Коли я встановив задній основний колір для очищення на baseView, тінь більше не з’являється. Що я роблю неправильно?
Rutger Huijsmans

3
Не працює, налаштування baseView.backgroundColor = UIColor.clearвидаляє тінь. Тільки якщо ви встановите колір фону, ви побачите його.
Олександр

2
НЕ ПРАЦЮЄ ДЛЯ МНЕ.
Маркус

4
FYI Я спочатку бачив ту ж проблему, що й інші коментатори бачили, де тінь baseView не відображається, коли її колір фону був чітким. Проблема полягала в тому, що я запускав лише першу частину коду (базовий елемент). Як тільки я додав borderView як підзагляд, тінь почала відображатися. Здається, що для відображення тіні має бути принаймні одна видима межа (або фон) в її ієрархії перегляду. Тому не забудьте мати borderView.layer.borderWidth> = 0 з непрозорим кольором borderView.layer.borderColor (або непрозорим кольором фону)
Mike Vosseller

79

Один із способів зробити це - поставити вид із закругленими кутами в вид з тінню.

UIView* roundedView = [[UIView alloc] initWithFrame: frame];
roundedView.layer.cornerRadius = 5.0;
roundedView.layer.masksToBounds = YES;

UIView* shadowView = [[UIView alloc] initWithFrame: frame];
shadowView.layer.shadowColor = [UIColor blackColor].CGColor;
shadowView.layer.shadowRadius = 5.0;
shadowView.layer.shadowOffset = CGSizeMake(3.0, 3.0);
shadowView.layer.shadowOpacity = 1.0;
[shadowView addSubview: roundedView];

Тоді ви можете додати shadowView куди завгодно.


5
Дозвольте, вам потрібно встановити maskToBounds / clipToBounds = ТАК лише для * roundedView *. НЕ встановлюйте це для shadowView. Я не пробував вищевказаний код, але точно знаю, що це рішення точно працює, хоча і не ідеально. Вища тіньРадіус опікується ділянками радіуса кута. Встановіть shadowRadius на 0 або 1, і ви помітите, що я намагаюся сказати.
Deepak GM

2
Щось на зразок shadowView.layer.shadowOpacity = 0,6; відсутня
Бо.

3
"shadowView.layer.opacity = 1.0" має бути "shadowView.layer.shadowOpacity = 1.0"
Кріс

Працює на iOS 9, якщо використовувати shadowView.layer.shadowOpacity = 1.0
Мансуров Руслан

Код виправлено для shadowOpacity
Softlion

63

Перевірте приклад проекту на GitHub, щоб переконатися, що ви правильно використовуєте компонент.

Просте рішення Swift 5 без додаткових підпереглядів та підкласифікації:

extension UIView {

    func addShadow(offset: CGSize, color: UIColor, radius: CGFloat, opacity: Float) {
        layer.masksToBounds = false
        layer.shadowOffset = offset
        layer.shadowColor = color.cgColor
        layer.shadowRadius = radius
        layer.shadowOpacity = opacity

        let backgroundCGColor = backgroundColor?.cgColor
        backgroundColor = nil
        layer.backgroundColor =  backgroundCGColor
    }
}

Зауважте, що перед налаштуванням дзвінка слід налаштувати свій погляд з радіусом кута та іншими властивостями addShadow.

Після цього просто телефонуйте viewDidLoadтак:

button.addShadow(offset: CGSize.init(width: 0, height: 3), color: UIColor.black, radius: 2.0, opacity: 0.35)

Кінцевий результат:

результат

Супер легко і просто!


Це працює на кнопках? Тому що це не працює на моєму кінці.
Чезаре

Я спробував дотримуватися точних кроків, які ви запропонували. Але все одно не везе. Було б чудово, якби ви поділилися зразком (на Github), щоб побачити, як ви зробили, що здається неможливим для мене та інших людей.
Hemang

Вдалося змусити його працювати лише видаливши цю лінію layer.shadowPath = UIBezierPath.init(roundedRect: layer.bounds, cornerRadius: layer.cornerRadius).cgPath. Не можу пояснити, чому, хоча хтось має для цього пояснення?
trupin

@Curnelious сміливо переглядайте оновлену відповідь на прикладі проекту Xcode. Це не може працювати :)
Сергій Грищйов

3
Це працювало і для мене, просто потрібно ще одне - зробити так, щоб всі підгляди фонового кольору були очищені, щоб тільки вигляд контейнера мав видимий фон, і це вирішило мою проблему. Дякую!! @SergeyGrischyov
Rishabh

42

Це працювало для мене. Трюк повинен був перемістити колір фону з основного виду на шар.

CALayer *layer = view.layer;
layer.cornerRadius = 15.0f;
layer.masksToBounds = NO;

layer.shadowOffset = CGSizeMake(0, 3);
layer.shadowColor = [[UIColor blackColor] CGColor];
layer.shadowRadius = 2.0f;
layer.shadowOpacity = 0.35f;
layer.shadowPath = [[UIBezierPath bezierPathWithRoundedRect:layer.bounds cornerRadius:layer.cornerRadius] CGPath];

CGColorRef  bColor = view.backgroundColor.CGColor;
view.backgroundColor = nil;
layer.backgroundColor =  bColor ;

Хоча всі інші рішення працюють, і, можливо, вони є загальнішими, це, безумовно, найкраще рішення проблеми. Додавання підвидів або підшарів створює світ або біль, намагаючись підтримувати розміри кадру, або в кращому випадку може спричинити проблеми з продуктивністю.
emem

Це має бути відповіддю. Чисто та елегантно.
Axy

Найкраще рішення і, безумовно, елегантно!
Роберто Ферраз

Ого, це насправді працює. Я не розумію, чому це має працювати - ви вважаєте, що фоновий виглядColor належним чином буде безпосередньо відображатись у властивості layer.backgroundColor на iOS, але це працює. (Xcode 8, Swift 3.) Молодці, і дякую. Це має бути прийнятою відповіддю.
Womble

Я створив версію своєї відповіді Swift 3.1, використовуючи UIView extensionтут - stackoverflow.com/a/43295741/1313939 спасибі за натхнення!
Сергій Грищов

26

Я вирішив проблему, використовуючи наступний трюк при призначенні тіньового шляху для перегляду контейнера:

[UIBezierPath bezierPathWithRoundedRect:cell.bounds cornerRadius:12]

Зауважте, що шлях, заданий тінню, - це округлий прямокутник з тим же радіусом кута, що і фон, який містить комірка:

//this is the border for the UIView that is added to a cell
cell.backgroundView.layer.cornerRadius = 12;
cell.backgroundView.layer.masksToBounds = YES;
cell.backgroundView.layer.borderColor = [UIColor darkGrayColor].CGColor;
cell.backgroundView.layer.borderWidth = 1;

//this is the shadow around the cell itself (cannot have round corners with borders and shadow, need to use two views
cell.layer.shadowRadius = 2;
cell.layer.cornerRadius = 12;
cell.layer.masksToBounds = NO;
[[cell layer] setShadowColor:[[UIColor darkGrayColor] CGColor]];

[[cell layer] setShadowOffset:CGSizeMake(0.0,0.0)];
[[cell layer] setShadowOpacity:1.0];

UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:cell.bounds cornerRadius:12];
[[cell layer] setShadowPath:[path CGPath]];

Найкраща відповідь, тому що він пояснює правильний спосіб додати тінь до більш круглим видом. Дякуємо @Alex Stone
програміст

17

Якщо ви боретеся через округлення cornersпроти subviewsі masksToBounds, спробуйте скористатися моєю функцією:

- (UIView*)putView:(UIView*)view insideShadowWithColor:(UIColor*)color andRadius:(CGFloat)shadowRadius andOffset:(CGSize)shadowOffset andOpacity:(CGFloat)shadowOpacity
{
    CGRect shadowFrame; // Modify this if needed
    shadowFrame.size.width = 0.f;
    shadowFrame.size.height = 0.f;
    shadowFrame.origin.x = 0.f;
    shadowFrame.origin.y = 0.f;
    UIView * shadow = [[UIView alloc] initWithFrame:shadowFrame];
    shadow.userInteractionEnabled = NO; // Modify this if needed
    shadow.layer.shadowColor = color.CGColor;
    shadow.layer.shadowOffset = shadowOffset;
    shadow.layer.shadowRadius = shadowRadius;
    shadow.layer.masksToBounds = NO;
    shadow.clipsToBounds = NO;
    shadow.layer.shadowOpacity = shadowOpacity;
    [view.superview insertSubview:shadow belowSubview:view];
    [shadow addSubview:view];
    return shadow;
}

зателефонуйте на ваш погляд. чи має ваш погляд закруглені кути, незалежно від його розміру, його форми - буде намальована приємна тінь.

Просто зберігайте повернене значення функції, щоб ви могли посилатися на неї, коли ви хочете видалити таблицю (або, наприклад, використовувати insertSubview:aboveView:)


це чудово працює. Але якщо погляд має розпізнавачі жестів, то це не вийде. як ми можемо це вирішити?
manujmv

@manujmv Чи бачите ви рядки, де вказано "// Змінити це, якщо потрібно"? Це те, що вам потрібно. shadow.userInteractionEnabled = ТАК;
daniel.gindi

@manujmv, тоді ви повинні перевірити кадри перегляду та субпрогляду, щоб зрозуміти, чому. щось, мабуть, там не так. цей точний код працює для мене в дуже приємних програмах
daniel.gindi

2
Це рішення чудово підходить для UITableViews із закругленими кутами. Бажаю, щоб я міг отримати більше голосів. Дякую!
Кріс Харт

@ CarlosEduardoLópez Ви бачите shadow.userInteractionEnabled = NO; // Modify this if neededлінію? Тож це той випадок, коли потрібно. userInteractionEnabledє основною та популярною власністю, з якою ви повинні вже ознайомитись :-)
daniel.gindi

12

Використовуючи Swift 4 та Xcode 9 , це робочий приклад округлення ImageViewтіні з краплею та рамкою.

    //set dimensions and position of image (in this case, centered)
    let imageHeight: CGFloat = 150, imageWidth: CGFloat = 150
    let xPosition = (self.view.frame.width / 2) - (imageWidth / 2)
    let yPosition = (self.view.frame.height / 2) - (imageHeight / 2)

    //set desired corner radius
    let cornerRadius: CGFloat = 20

    //create container for the image
    let imageContainer = UIView(frame: CGRect(x: xPosition, y: yPosition, width: imageWidth, height: imageHeight))

    //configure the container
    imageContainer.clipsToBounds = false
    imageContainer.layer.shadowColor = UIColor.black.cgColor
    imageContainer.layer.shadowOpacity = 1
    imageContainer.layer.shadowOffset = CGSize(width: 3.0, height: 3.0)
    imageContainer.layer.shadowRadius = 5
    imageContainer.layer.shadowPath = UIBezierPath(roundedRect: imageContainer.bounds, cornerRadius: cornerRadius).cgPath

    //create imageView
    let imageView = UIImageView(frame: imageContainer.bounds)

    //configure the imageView
    imageView.clipsToBounds = true
    imageView.layer.cornerRadius = cornerRadius
    //add a border (if required)
    imageView.layer.borderColor = UIColor.black.cgColor
    imageView.layer.borderWidth = 1.0
    //set the image
    imageView.image = UIImage(named: "bird")

    //add the views to the superview
    view.addSubview(imageContainer)
    imageContainer.addSubview(imageView)

введіть тут опис зображення

Якщо ви хочете, щоб зображення було круглим: (і відображається без меж)

let cornerRadius = imageWidth / 2

введіть тут опис зображення


7

Я створив помічника в UIView

@interface UIView (Helper)

- (void)roundCornerswithRadius:(float)cornerRadius
               andShadowOffset:(float)shadowOffset;
@end

ви можете назвати це так

[self.view roundCornerswithRadius:5 andShadowOffset:5];

Ось реалізація

- (void)roundCornerswithRadius:(float)cornerRadius
               andShadowOffset:(float)shadowOffset
{
    const float CORNER_RADIUS = cornerRadius;
    const float SHADOW_OFFSET = shadowOffset;
    const float SHADOW_OPACITY = 0.5;
    const float SHADOW_RADIUS = 3.0;

    UIView *superView = self.superview;

    CGRect oldBackgroundFrame = self.frame;
    [self removeFromSuperview];

    CGRect frameForShadowView = CGRectMake(0, 0, oldBackgroundFrame.size.width, oldBackgroundFrame.size.height);
    UIView *shadowView = [[UIView alloc] initWithFrame:frameForShadowView];
    [shadowView.layer setShadowOpacity:SHADOW_OPACITY];
    [shadowView.layer setShadowRadius:SHADOW_RADIUS];
    [shadowView.layer setShadowOffset:CGSizeMake(SHADOW_OFFSET, SHADOW_OFFSET)];

    [self.layer setCornerRadius:CORNER_RADIUS];
    [self.layer setMasksToBounds:YES];

    [shadowView addSubview:self];
    [superView addSubview:shadowView];

}

2
Це хороше елегантне рішення. Переконайтеся, що ваш погляд було додано до його огляду перед використанням. Я додав деякі параметри, щоб дати мені більше контролю над тінню, але в цілому працює ідеально. Дякую!
Аарон Вег

Це приємне рішення, але воно не працює з автоматичним розгортанням: подання буде складено за походженням 0,0
gderaco

5

Після цілоденного дослідження круглого кутового виду з тінню я радий розмістити тут свій власний клас uiview, сподіваюся закінчити це питання:

RoundCornerShadowView.h

#import <UIKit/UIKit.h>

@interface RoundCornerShadowView : UIView

@end

RoundCornerShadowView.m

#import "RoundCornerShadowView.h"

@implementation RoundCornerShadowView

// *** must override this method, not the other method ***
// otherwise, the background corner doesn't disappear....
// @2015/05/29
-(void) layoutSubviews {
    [super layoutSubviews];//is must to ensure rightly layout children view

    //1. first, create Inner layer with content
    CALayer *innerView = [CALayer layer];
    innerView.frame = CGRectMake(0,0,self.bounds.size.width,self.bounds.size.height);
    //instead of: innerView.frame = self.frame;
    innerView.borderWidth = 1.0f;
    innerView.cornerRadius = 6.0f;
    innerView.masksToBounds = YES;
    innerView.borderColor = [[UIColor lightGrayColor] CGColor];
    innerView.backgroundColor = [[UIColor whiteColor] CGColor];
    //put the layer to the BOTTOM of layers is also a MUST step...
    //otherwise this layer will overlay the sub uiviews in current uiview...
    [self.layer insertSublayer:innerView atIndex:0];

    //2. then, create shadow with self layer
    self.layer.masksToBounds = NO;
    self.layer.shadowColor = [[UIColor darkGrayColor] CGColor];
    self.layer.shadowOpacity = 0.4f;
    //shadow length
    self.layer.shadowRadius = 2.0f;
    //no offset
    self.layer.shadowOffset = CGSizeMake(0, 0);
    //right down shadow
    //[self.layer setShadowOffset: CGSizeMake(1.0f, 1.0f)];

    //3. last but important, MUST clear current view background color, or the color will show in the corner!
    self.backgroundColor = [UIColor clearColor];
}

@end

Отже, НЕ потрібно додавати підперегляд у поданні чи нижче в цільовому поданні, просто додайте один шар у поточному поданні та зробіть 3 кроки для його завершення!

уважно придивіться до коментарів у коді, корисно зрозуміти компонент!


5

Щось тест перевірений у швидкому 4

import UIKit

extension UIView {
    @IBInspectable var dropShadow: Bool {
        set{
            if newValue {
                layer.shadowColor = UIColor.black.cgColor
                layer.shadowOpacity = 0.4
                layer.shadowRadius = 1
                layer.shadowOffset = CGSize.zero
            } else {
                layer.shadowColor = UIColor.clear.cgColor
                layer.shadowOpacity = 0
                layer.shadowRadius = 0
                layer.shadowOffset = CGSize.zero
            }
        }
        get {
            return layer.shadowOpacity > 0
        }
    }
}

Виробляє

введіть тут опис зображення

Якщо ввімкнути його в Інспекторі так:

введіть тут опис зображення

Він додасть визначений користувачем атрибут виконання, в результаті чого:

введіть тут опис зображення

(Я раніше додав cornerRadius = 8)

:)


5

Вам потрібно використовувати shadowViewі використанняroundView

введіть тут опис зображення

shadowView

  • Обов’язково має колір тла
  • Слід лежати позаду roundView
  • Хитрість полягає в розташуванні shadowViewтрохи всередині, і його тінь повинна світитися. Відрегулюйте insetsтак, що shadowViewпозаду зовсім непомітноroundView

roundView

  • Потрібно відстежувати підзагляди кліпів

Код

addSubviews(shadowView, roundView)
roundView.addSubviews(titleLabel, subtitleLabel, imageView)

// need inset
shadowView.pinEdges(view: self, inset: UIEdgeInsets(constraintInsets: 2))
roundView.pinEdges(view: self)

do {
  shadowView.backgroundColor = .white // need background
  let layer = shadowView.layer
  layer.shadowColor = UIColor.black.cgColor
  layer.shadowRadius = 3
  layer.shadowOffset = CGSize(width: 3, height: 3)
  layer.shadowOpacity = 0.7
  layer.shouldRasterize = true
}

do {
  roundView.backgroundColor = .white
  let layer = roundView.layer
  layer.masksToBounds = true
  layer.cornerRadius = 5
}

Або ви можете просто зробити нижче, не вказуючи clipToBounds/maskToBounds

layer.shadowColor = UIColor.gray.cgColor
layer.shadowOffset = CGSize(width: 3, height: 3)
layer.shadowOpacity = 0.8

4

Swift 3 & IBI Непередбачуване рішення:
натхненний рішенням Ade

Спочатку створіть розширення UIView:

//
//  UIView-Extension.swift
//  

import Foundation
import UIKit

@IBDesignable
extension UIView {
     // Shadow
     @IBInspectable var shadow: Bool {
          get {
               return layer.shadowOpacity > 0.0
          }
          set {
               if newValue == true {
                    self.addShadow()
               }
          }
     }

     fileprivate func addShadow(shadowColor: CGColor = UIColor.black.cgColor, shadowOffset: CGSize = CGSize(width: 3.0, height: 3.0), shadowOpacity: Float = 0.35, shadowRadius: CGFloat = 5.0) {
          let layer = self.layer
          layer.masksToBounds = false

          layer.shadowColor = shadowColor
          layer.shadowOffset = shadowOffset
          layer.shadowRadius = shadowRadius
          layer.shadowOpacity = shadowOpacity
          layer.shadowPath = UIBezierPath(roundedRect: layer.bounds, cornerRadius: layer.cornerRadius).cgPath

          let backgroundColor = self.backgroundColor?.cgColor
          self.backgroundColor = nil
          layer.backgroundColor =  backgroundColor
     }


     // Corner radius
     @IBInspectable var circle: Bool {
          get {
               return layer.cornerRadius == self.bounds.width*0.5
          }
          set {
               if newValue == true {
                    self.cornerRadius = self.bounds.width*0.5
               }
          }
     }

     @IBInspectable var cornerRadius: CGFloat {
          get {
               return self.layer.cornerRadius
          }

          set {
               self.layer.cornerRadius = newValue
          }
     }


     // Borders
     // Border width
     @IBInspectable
     public var borderWidth: CGFloat {
          set {
               layer.borderWidth = newValue
          }

          get {
               return layer.borderWidth
          }
     }

     // Border color
     @IBInspectable
     public var borderColor: UIColor? {
          set {
               layer.borderColor = newValue?.cgColor
          }

          get {
               if let borderColor = layer.borderColor {
                    return UIColor(cgColor: borderColor)
               }
               return nil
          }
     }
}

Потім просто виберіть свій UIView у налаштуваннях тіні для налаштування інтерфейсу ON та кутовий радіус , як показано нижче:

Вибір вашого UIView

Встановлення тіні ON і радіус кута

Результат!

Результат


Як і будь-яке інше "рішення" в цій темі, воно просто не працює, принаймні, не на iOS 11.0 / Swift 4.1.
незрозумілий

Ви читали "Свіфт 3" на початку теми? Отже, це означає, що це рішення Swift 3, я його не перевіряв у Swift 4.1, оскільки він мені вже не потрібен. Не соромтесь відредагувати відповідь та дати рішення. ;) Ура
Томас Кальмон

3

Ось вирішення проблеми конфлікту masksToBounds, вона працює для мене.

Після встановлення corderRadius / borderColor / тінь тощо, встановіть masksToBounds як НІ:

v.layer.masksToBounds = NO;

Це працювало для мене !! omg Я майже зробив усі хитрощі вище, ніж ти відповів! дякую Шаопенгу.
MontDeska

3

Тінь + межа + радіус кута введіть тут опис зображення

    scrollview.backgroundColor = [UIColor whiteColor]; 
    CALayer *ScrlViewLayer = [scrollview layer];
    [ScrlViewLayer setMasksToBounds:NO ];
    [ScrlViewLayer setShadowColor:[[UIColor lightGrayColor] CGColor]];
    [ScrlViewLayer setShadowOpacity:1.0 ];
    [ScrlViewLayer setShadowRadius:6.0 ];
    [ScrlViewLayer setShadowOffset:CGSizeMake( 0 , 0 )];
    [ScrlViewLayer setShouldRasterize:YES];
    [ScrlViewLayer setCornerRadius:5.0];
    [ScrlViewLayer setBorderColor:[UIColor lightGrayColor].CGColor];
    [ScrlViewLayer setBorderWidth:1.0];
    [ScrlViewLayer setShadowPath:[UIBezierPath bezierPathWithRect:scrollview.bounds].CGPath];

3

Ось моя версія в Swift 3 для UIView

let corners:UIRectCorner = [.bottomLeft, .topRight]
let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()

mask.path = path.cgPath
mask.fillColor = UIColor.white.cgColor

let shadowLayer = CAShapeLayer()
shadowLayer.shadowColor = UIColor.black.cgColor
shadowLayer.shadowOffset = CGSize(width: 0.0, height: 4.0)
shadowLayer.shadowRadius = 6.0
shadowLayer.shadowOpacity = 0.25
shadowLayer.shadowPath = mask.path

self.layer.insertSublayer(shadowLayer, at: 0)
self.layer.insertSublayer(mask, at: 1)

3

Swift 4: Створення підкласу UIView

class ShadowView: UIView {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        // corner radius
        self.layer.cornerRadius = 10

        // border
        self.layer.borderWidth = 1.0
        self.layer.borderColor = UIColor.black.cgColor

        // shadow
        self.layer.shadowColor = UIColor.black.cgColor
        self.layer.shadowOffset = CGSize(width: 3, height: 3)
        self.layer.shadowOpacity = 0.7
        self.layer.shadowRadius = 4.0
    }

}

Використовуючи ..

Використовуйте перегляд тіней у класі


2

Добре, якщо ви не хочете змінювати нитки і переглядати ієрархію, як запропонував Девід С., цей метод зробить це за вас. Щоб додати закруглені кути та тінь у свій UIImageView, просто скористайтеся цим методом, наприклад:

[Utils roundCornersForImageView:myImageView withCornerRadius:6.0 
andShadowOffset:2.0];

(!) З міркувань продуктивності я не думаю, що було б корисно використовувати цей код у чомусь на зразок UITableView, оскільки цей код змінює ієрархію подання. Тож я запропоную змінити вашу ручку та додати перегляд контейнера для ефекту тіні та використовувати код Davic C.

+ (void)roundCornersForImageView:(UIImageView *)imageView 
withCornerRadius:(float)cornerRadius andShadowOffset:(float)shadowOffset
{
    const float CORNER_RADIUS = cornerRadius;
    const float BORDER_WIDTH = 1.0; 
    const float SHADOW_OFFSET = shadowOffset;
    const float SHADOW_OPACITY = 0.8;
    const float SHADOW_RADIUS = 3.0;

    //Our old image now is just background image view with shadow
    UIImageView *backgroundImageView = imageView;
    UIView *superView = backgroundImageView.superview;

    //Make wider actual visible rect taking into account shadow
    //offset
    CGRect oldBackgroundFrame = backgroundImageView.frame;
    CGRect newBackgroundFrame = CGRectMake(oldBackgroundFrame.origin.x, oldBackgroundFrame.origin.y, oldBackgroundFrame.size.width + SHADOW_OFFSET, oldBackgroundFrame.size.height + SHADOW_OFFSET);
    [backgroundImageView removeFromSuperview];
    backgroundImageView.frame = newBackgroundFrame;        

    //Make new UIImageView with rounded corners and put our old image
    CGRect frameForRoundedImageView = CGRectMake(0, 0, oldBackgroundFrame.size.width, oldBackgroundFrame.size.height);
    UIImageView *roundedImageView = [[UIImageView alloc]initWithFrame:frameForRoundedImageView];
    roundedImageView.image = imageView.image;
    [roundedImageView.layer setCornerRadius:CORNER_RADIUS];
    [roundedImageView.layer setBorderColor:[UIColor lightGrayColor].CGColor];        
    [roundedImageView.layer setBorderWidth:BORDER_WIDTH]; 
    [roundedImageView.layer setMasksToBounds:YES];

    //Set shadow preferences
    [backgroundImageView setImage:nil];
    [backgroundImageView.layer setShadowColor:[UIColor blackColor].CGColor];
    [backgroundImageView.layer setShadowOpacity:SHADOW_OPACITY];
    [backgroundImageView.layer setShadowRadius:SHADOW_RADIUS];
    [backgroundImageView.layer setShadowOffset:CGSizeMake(SHADOW_OFFSET, SHADOW_OFFSET)];   

    //Add out two image views back to the view hierarchy.
    [backgroundImageView addSubview:roundedImageView];
    [superView addSubview:backgroundImageView];   
}    

2

Стара нитка все ще актуальна ...

Я відредагував метод Даніеля Гінді, щоб зробити його можливим також використовувати кнопки тощо. Якщо комусь потрібні закруглені кути або хоче поєднати круглі кути та облямівку, його потрібно встановити на шарі подання, який передається цьому методу. Я також встановив растерізацію, щоб трохи прискорити її.

+ (UIView*)putView:(UIView*)view insideShadowWithColor:(CGColorRef)color 
                                 andRadius:(CGFloat)shadowRadius 
                                 andOffset:(CGSize)shadowOffset 
                                 andOpacity:(CGFloat)shadowOpacity
{
    // Must have same position like "view"
    UIView *shadow = [[UIView alloc] initWithFrame:view.frame]; 

    shadow.layer.contentsScale = [UIScreen mainScreen].scale;
    shadow.userInteractionEnabled = YES; // Modify this if needed
    shadow.layer.shadowColor = color;
    shadow.layer.shadowOffset = shadowOffset;
    shadow.layer.shadowRadius = shadowRadius;
    shadow.layer.masksToBounds = NO;
    shadow.clipsToBounds = NO;
    shadow.layer.shadowOpacity = shadowOpacity;
    shadow.layer.rasterizationScale = [UIScreen mainScreen].scale;
    shadow.layer.shouldRasterize = YES;

    [view.superview insertSubview:shadow belowSubview:view];
    [shadow addSubview:view];

    // Move view to the top left corner inside the shadowview 
    // ---> Buttons etc are working again :)
    view.frame = CGRectMake(0, 0, view.frame.size.width, view.frame.size.height);

    return shadow;
}

2

Наступне найкраще працювало для мене (цей код лежить у розширенні UIView, тому self позначає деякий UIView, до якого треба додати тінь та круглий кут)

- (void)addShadowViewWithCornerRadius:(CGFloat)radius {

UIView *container = self.superview;

if (!container) {
    return;
}

UIView *shadowView = [[UIView alloc] init];
shadowView.translatesAutoresizingMaskIntoConstraints = NO;
shadowView.backgroundColor = [UIColor lightGrayColor];
shadowView.layer.cornerRadius = radius;
shadowView.layer.masksToBounds = YES;

[container addSubview:shadowView];
[container bringSubviewToFront:shadowView];

[container addConstraint:[NSLayoutConstraint constraintWithItem:shadowView
                                                      attribute:NSLayoutAttributeWidth
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self
                                                      attribute:NSLayoutAttributeWidth
                                                     multiplier:1.0
                                                       constant:0.0]];
[container addConstraint:[NSLayoutConstraint constraintWithItem:shadowView
                                                      attribute:NSLayoutAttributeLeading
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self
                                                      attribute:NSLayoutAttributeLeading
                                                     multiplier:1.0
                                                       constant:2.0]];

[container addConstraint:[NSLayoutConstraint constraintWithItem:shadowView
                                                      attribute:NSLayoutAttributeHeight
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self
                                                      attribute:NSLayoutAttributeHeight
                                                     multiplier:1.0
                                                       constant:0.0]];
[container addConstraint:[NSLayoutConstraint constraintWithItem:shadowView
                                                      attribute:NSLayoutAttributeTop
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self
                                                      attribute:NSLayoutAttributeTop
                                                     multiplier:1.0
                                                       constant:2.0]];
[container sendSubviewToBack:shadowView];
}

Основна відмінність між цим та іншими прикладами коди є те , що це додає вид тіні в якості точки зору сіблінгов (в порівнянні з додаванням поточного виду як підвид зору тіньового), тим самим усуваючи необхідність змінити існуючу ієрархію виду в будь-якому випадку.


1

Відповідь daniel.gindi вище зробила трюк для мене! (+1 даніель) Однак мені довелося внести незначні корективи - змінити розмір shadowFrame на такий, як розмір кадру перегляду, та включити взаємодію з користувачем. Ось оновлений код:

+ (UIView*)putView:(UIView*)view insideShadowWithColor:(UIColor*)color andRadius:(CGFloat)shadowRadius andOffset:(CGSize)shadowOffset andOpacity:(CGFloat)shadowOpacity
{
    CGRect shadowFrame; // Modify this if needed

    // Modified this line
    shadowFrame.size = CGSizeMake(view.frame.size.width, view.frame.size.height);

    shadowFrame.origin.x = 0.f;
    shadowFrame.origin.y = 0.f;
    UIView * shadow = [[UIView alloc] initWithFrame:shadowFrame];

    // Modified this line
    shadow.userInteractionEnabled = YES;
    shadow.layer.shadowColor = color.CGColor;
    shadow.layer.shadowOffset = shadowOffset;
    shadow.layer.shadowRadius = shadowRadius;
    shadow.layer.masksToBounds = NO;
    shadow.clipsToBounds = NO;
    shadow.layer.shadowOpacity = shadowOpacity;

    [shadow addSubview:view];
    return shadow;
}

Я хотів би додати, що в моєму випадку я намагався додати це до стороннього контролера перегляду, тобто я не мав прямого контролю над кодом. Отже, ось як я використовував функцію вище:

UIView *shadow = [self putView:vc.view 
         insideShadowWithColor:[UIColor blackColor]
                     andRadius:5.0 
                     andOffset:CGSizeMake(0.0, 0.0) 
                    andOpacity:1.0];
vc.view = shadow;
vc.view.layer.cornerRadius = 5.0;
vc.view.layer.masksToBounds = YES;

1

Я вношу деякі зміни в код daniel.gindi

Це все, що потрібно для того, щоб він працював.

+ (void)putView:(UIView*)view insideShadowWithColor:(UIColor*)color andBlur:         (CGFloat)blur andOffset:(CGSize)shadowOffset andOpacity:(CGFloat)shadowOpacity
{
    CGRect shadowFrame = view.frame;
    UIView * shadow = [[UIView alloc] initWithFrame:shadowFrame];
    shadow.backgroundColor = [UIColor redColor];
    shadow.userInteractionEnabled = YES; // Modify this if needed
    shadow.layer.shadowColor = color.CGColor;
    shadow.layer.shadowOffset = shadowOffset;
    shadow.layer.shadowRadius = blur;
    shadow.layer.cornerRadius = view.layer.cornerRadius;
    shadow.layer.masksToBounds = NO;
    shadow.clipsToBounds = NO;
    shadow.layer.shadowOpacity = shadowOpacity;
    [view.superview insertSubview:shadow belowSubview:view];
}

1

Щоб UIViewsдосягти цього, потрібно використовувати два . Один UIViewбуде працювати як тінь, а інший буде працювати для округлого кордону.

Ось фрагмент коду a Class Methodза допомогою protocol:

@implementation UIMethods

+ (UIView *)genComposeButton:(UIViewController <UIComposeButtonDelegate> *)observer;
{
    UIView *shadow = [[UIView alloc]init];
    shadow.layer.cornerRadius = 5.0;
    shadow.layer.shadowColor = [[UIColor blackColor] CGColor];
    shadow.layer.shadowOpacity = 1.0;
    shadow.layer.shadowRadius = 10.0;
    shadow.layer.shadowOffset = CGSizeMake(0.0f, -0.5f);

    UIButton *btnCompose = [[UIButton alloc]initWithFrame:CGRectMake(0, 0,60, 60)];
    [btnCompose setUserInteractionEnabled:YES];
    btnCompose.layer.cornerRadius = 30;
    btnCompose.layer.masksToBounds = YES;
    [btnCompose setImage:[UIImage imageNamed:@"60x60"] forState:UIControlStateNormal];
    [btnCompose addTarget:observer action:@selector(btnCompose_click:) forControlEvents:UIControlEventTouchUpInside];
    [shadow addSubview:btnCompose];
    return shadow;
}

У наведеному вище коді btnCompose_click:стане @requiredделегатним методом, який спрацює при натисканні кнопки.

І тут я додав кнопку до свого UIViewControllerподібного:

UIView *btnCompose = [UIMethods genComposeButton:self];
btnCompose.frame = CGRectMake(self.view.frame.size.width - 75,
                          self.view.frame.size.height - 75,
                          60, 60);
[self.view addSubview:btnCompose];

Результат буде виглядати приблизно так:

введіть тут опис зображення


1

Я спробував так багато рішень з цієї посади і закінчив наступне рішення. Це повне доказне рішення, якщо вам не потрібно кидати тінь на чітке кольорове подання .

- (void)addShadowWithRadius:(CGFloat)shadowRadius withOpacity:(CGFloat)shadowOpacity withOffset:(CGSize)shadowOffset withColor:(UIColor *)shadowColor withCornerradius:(CGFloat)cornerRadius
{
    UIView *viewShadow = [[UIView alloc]initWithFrame:self.frame];
    viewShadow.backgroundColor = [UIColor whiteColor];
    viewShadow.layer.shadowColor = shadowColor.CGColor;
    viewShadow.layer.shadowOffset = shadowOffset;
    viewShadow.layer.shadowRadius = shadowRadius;
    viewShadow.layer.shadowOpacity = shadowOpacity;
    viewShadow.layer.cornerRadius = cornerRadius;
    viewShadow.layer.masksToBounds = NO;
    [self.superview insertSubview:viewShadow belowSubview:self];

    [viewShadow setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:viewShadow attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0]];
    [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:viewShadow attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0]];
    [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:viewShadow attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:viewShadow attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];
    [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:viewShadow attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:viewShadow attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]];
    [self layoutIfNeeded];

    self.layer.cornerRadius = cornerRadius;
    self.layer.masksToBounds = YES;
}

Вираз - "дурний доказ". :)
Бен Томас

Я тільки виправляв англійську. :) Рішення працює.
Бен Томас

1

Ось рішення, яке буде працювати точно!

Я створив розширення UIView з необхідними краями, щоб застосувати тінь, як показано нижче


enum AIEdge:Int {
    case
    Top,
    Left,
    Bottom,
    Right,
    Top_Left,
    Top_Right,
    Bottom_Left,
    Bottom_Right,
    All,
    None
}

extension UIView {

    func applyShadowWithCornerRadius(color:UIColor, opacity:Float, radius: CGFloat, edge:AIEdge, shadowSpace:CGFloat)    {

        var sizeOffset:CGSize = CGSize.zero

        switch edge {
        case .Top:
            sizeOffset = CGSize(width: 0, height: -shadowSpace)
        case .Left:
            sizeOffset = CGSize(width: -shadowSpace, height: 0)
        case .Bottom:
            sizeOffset = CGSize(width: 0, height: shadowSpace)
        case .Right:
            sizeOffset = CGSize(width: shadowSpace, height: 0)


        case .Top_Left:
            sizeOffset = CGSize(width: -shadowSpace, height: -shadowSpace)
        case .Top_Right:
            sizeOffset = CGSize(width: shadowSpace, height: -shadowSpace)
        case .Bottom_Left:
            sizeOffset = CGSize(width: -shadowSpace, height: shadowSpace)
        case .Bottom_Right:
            sizeOffset = CGSize(width: shadowSpace, height: shadowSpace)


        case .All:
            sizeOffset = CGSize(width: 0, height: 0)
        case .None:
            sizeOffset = CGSize.zero
        }

        self.layer.cornerRadius = self.frame.size.height / 2
        self.layer.masksToBounds = true;

        self.layer.shadowColor = color.cgColor
        self.layer.shadowOpacity = opacity
        self.layer.shadowOffset = sizeOffset
        self.layer.shadowRadius = radius
        self.layer.masksToBounds = false

        self.layer.shadowPath = UIBezierPath(roundedRect:self.bounds, cornerRadius:self.layer.cornerRadius).cgPath
    }
}

Нарешті, ви можете зателефонувати на функцію тіні, як показано нижче, для будь-якого підкласу UIView, ви також можете вказати край, до якого слід застосувати тінь, спробуйте різні варіанти відповідно до ваших потреб, змінивши параметри виклику методу нижче.

viewRoundedToBeShadowedAsWell.applyShadowWithCornerRadius(color: .gray, opacity: 1, radius: 15, edge: AIEdge.All, shadowSpace: 15)

Результат зображення

введіть тут опис зображення

введіть тут опис зображення

введіть тут опис зображення


0

Відповідь, яку надав Еван Мулавський, буде чудово працювати. Суть полягає в тому, що вам потрібно встановити колір тла для перегляду, щоб очистити колір та властивість masksToBounds значення НІ.

Ви можете встановити будь-який колір для перегляду, встановити його як подобається

v.layer.backgroundColor = your color;

Сподіваюся, це допомагає ..


0

Так ви робите, із закругленими кутами та закругленими тінями, не обтяжуючи доріжок.

//Inner view with content
[imageView.layer setBorderColor:[[UIColor lightGrayColor] CGColor]];
[imageView.layer setBorderWidth:1.0f];
[imageView.layer setCornerRadius:8.0f];
[imageView.layer setMasksToBounds:YES];

//Outer view with shadow
UIView* shadowContainer = [[UIView alloc] initWithFrame:imageView.frame];
[shadowContainer.layer setMasksToBounds:NO];
[shadowContainer.layer setShadowColor:[[UIColor blackColor] CGColor]];
[shadowContainer.layer setShadowOpacity:0.6f];
[shadowContainer.layer setShadowRadius:2.0f];
[shadowContainer.layer setShadowOffset: CGSizeMake(0.0f, 2.0f)];

[shadowContainer addSubview:imageView];

Вид із вмістом, в моєму випадку UIImageView, має кутовий радіус і тому повинен маскуватися до меж.

Ми створюємо ще один вигляд однакового розміру для тіней, встановлюємо його maskToBounds в NO, а потім додаємо подання вмісту до перегляду контейнера (наприклад, shadowContainer).


0

Я пишу цей метод категорії UIView для вирішення цієї проблеми, використовуючи окремі види для тіні та радіуса кута.

-(UIView *)shadowedWrapViewWithBounds:(CGRect)bounds {
UIView *baseView = [[UIView alloc] init];
baseView.bounds = bounds;
baseView.backgroundColor = [UIColor clearColor];
baseView.layer.shadowColor = [UIColor blackColor].CGColor;
baseView.layer.shadowOffset = CGSizeMake(0, 0);
baseView.layer.shadowOpacity = 0.7;
baseView.layer.shadowRadius = 4.0;

// improve performance
baseView.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:baseView.bounds cornerRadius:4].CGPath;
baseView.layer.shouldRasterize = YES;
baseView.layer.rasterizationScale = [UIScreen mainScreen].scale;

[baseView addSubview:self];
//use Masonry autolayout, self can set corner radius
[self makeConstraints:^(MASConstraintMaker *make) {
    make.edges.equalTo(baseView);
}];

return baseView;
}

0

Swift 4 Рішення для того, щоб зробити UICollectionViewCell круглим і додати тіні , без розширень і ускладнень :)

Примітка: для простих подань, наприклад, кнопки. Дивіться відповідь @ suragch у цій публікації. https://stackoverflow.com/a/34984063/7698092 . Успішно перевірено на кнопках

У разі , якщо будь - яких один до сих пір з усіх сил , щоб закруглити кути і додати тіні в той же час. Хоча це рішення працює з UICollectionViewCell, воно може бути узагальнено до будь-якого виду.

Ця техніка працювала для мене, не роблячи ніяких розширень і всіх складних речей. Я працюю з storyBoard.

Техніка

Ви повинні додати UIView (дозвольте сказати, що це "контейнерний вигляд") всередині свого UICollectionViewCell в панелі сюжетів і додати всі необхідні представлення (кнопки, зображення тощо) всередині цього контейнера. Дивіться знімок екрана. Будова клітини

Підключіть розетку для контейнераView. Додайте наступні рядки коду у функції делегата CellforItemAtIndexPath.

//adds shadow to the layer of cell

cell.layer.cornerRadius = 3.0
    cell.layer.masksToBounds = false
    cell.layer.shadowColor = UIColor.black.cgColor
    cell.layer.shadowOffset = CGSize(width: 0, height: 0)
    cell.layer.shadowOpacity = 0.6

//makes the cell round 

let containerView = cell.containerView!
    containerView.layer.cornerRadius = 8
    containerView.clipsToBounds = true

Вихідні дані

Дивіться знімок екрана тренажера Закруглені кути з тінями (UICollectionViewCell)


0
extension UIView {
    func dropRoundedShadowForAllSides() {
        let backgroundView = UIView(frame:self.frame)
        let radius = frame.height/2
        backgroundView.layer.masksToBounds = false
        self.layer.masksToBounds = true
        backgroundView.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
        backgroundView.layer.shadowRadius = 4
        backgroundView.layer.shadowOpacity = 0.4

        let path = UIBezierPath()

        // Start at the Top Left Corner + radius distance
        path.move(to: CGPoint(x: 2*radius, y: 0.0))

        // Move to the Top Right Corner - radius distance
        path.addLine(to: CGPoint(x: backgroundView.frame.size.width - radius, y: 0.0))

        // Move to top right corner + radius down as curve
        let centerPoint1 = CGPoint(x:backgroundView.frame.size.width - radius,y:radius)
        path.addArc(withCenter: centerPoint1, radius: radius, startAngle: 3*(.pi/2), endAngle: 0, clockwise: true)

        // Move to the Bottom Right Corner - radius
        path.addLine(to: CGPoint(x: backgroundView.frame.size.width, y: backgroundView.frame.size.height - radius))

        // Move to top right corner + radius left as curve
        let centerPoint2 = CGPoint(x:backgroundView.frame.size.width - radius,y:backgroundView.frame.size.height - radius)
        path.addArc(withCenter: centerPoint2, radius: radius, startAngle: 0, endAngle: .pi/2, clockwise: true)

        // Move to the Bottom Left Corner - radius
        path.addLine(to: CGPoint(x: radius, y: backgroundView.frame.size.height))

        // Move to left right corner - radius up as curve
        let centerPoint3 = CGPoint(x:radius,y:backgroundView.frame.size.height - radius)
        path.addArc(withCenter: centerPoint3, radius: radius, startAngle: .pi/2, endAngle: .pi, clockwise: true)

        // Move to the top Left Corner - radius
        path.addLine(to: CGPoint(x: 0, y: radius))

        // Move to top right corner + radius down as curve
        let centerPoint4 = CGPoint(x:radius,y:radius)
        path.addArc(withCenter: centerPoint4, radius: radius, startAngle: .pi, endAngle: 3 * (.pi/2), clockwise: true)

        path.close()

        backgroundView.layer.shadowPath = path.cgPath
        if let superView = self.superview {
            superView.addSubview(backgroundView)
            superView.sendSubview(toBack: backgroundView)
            superView.bringSubview(toFront: self)
        }

    }
}

Привіт, дякую за вашу відповідь, ви повинні додати кілька коментарів до свого коду, щоб трохи пояснити, як описано в розділі Як відповісти .
Батист Мілле-Матіас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.