Köşeleri yuvarlatılmış ve gölge ile UIView?


390

Özel bir UIView... istiyorum : Sadece yuvarlatılmış köşeleri ve açık gölge (ışık efekti olmadan) ile boş bir beyaz görünüm istedim. Bunların her birini tek tek yapabilirim ama olağan clipToBounds/ maskToBoundsçatışmalar meydana gelir.


1
Aşağıdaki yorumda CoreGraphics kullanarak bu çalışmayı aldığınızı söylediğinizden, cevabı toplulukla paylaşmayı düşünürsünüz, böylece size yardımcı olmaya çalıştıkça aynı durumda başkalarına yardımcı olabilir misiniz?
lnafziger

Üzgünüm, bu çok uzun zaman önceydi ve artık kaynağım yok. Yaptığım şey geçersiz kılma -drawRect: ve bir dikdörtgen çizmek ve görünümü destekleyen katmana bir gölge uygulamak için UIBezierPath kullanın ... doğru hatırlıyorsam. :)
Aditya Vaidyam

5
Kabul edilen cevap çalışmıyor!
onmyway133


1
@Sachavijay Yorum yapmadan önce her iki gönderinin tarihini de doğrulamalısınız.
Aditya Vaidyam

Yanıtlar:


444

Aşağıdaki kod parçası kenarlık, sınır yarıçapı ve gölge ekler vbir 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)];

Ayarları ihtiyaçlarınıza göre ayarlayabilirsiniz.

Ayrıca, projenize QuartzCore çerçevesini ekleyin ve:

#import <QuartzCore/QuartzCore.h>

İle ilgili diğer cevabımı görün masksToBounds.


Not

Bu her durumda çalışmayabilir. Bu yöntemin gerçekleştirdiğiniz diğer çizim işlemlerine müdahale ettiğini fark ederseniz, lütfen bu cevaba bakın .


83
Sorun şu ki, köşe yarıçapını ayarladığımda, maskToBounds: YES'i ayarlarken, gölge clipToBounds gerektirir: NO (clipToBounds'un maskToBounds ile aynı şeyi yaptığı)
Aditya Vaidyam 21:11

15
burada da aynı problem. Eğer bir arka plan rengim varsa, bunun yuvarlatılmış köşelere kırpılmasını istiyorum. Bunu yapmak için maskToBounds = DOĞRU kullanmak zorundayım, ama sonra gölge
kayboluyor

3
Benim gibi yeni başlayanlar için: Katman nesnesindeki yöntemleri çağırmak için QuartzCore çerçevesini projeme aktarmak zorunda kaldım.
SilithCrowe

38
Bunun doğru şekilde çalışmasını sağlamanın yolu , sınırınızı ve arka plan renginizi her ikisi de köşe yarıçapında barındıracak bir iç kap görünümü kullanmaktır. Bu görünüm sınırlara kırpılacak! İkinci, dış konteyner görünümü ilkini içerecek, sadece bir gölge ile aynı çerçeveye sahip olacak. Bir kenarlık, gölge ve köşe yarıçapını birleştirmek için bunu birkaç kez yaptım. Gerçekten sinir bozucu, ama gerçekten iyi çalışıyor.
Kpmurphy91

23
Çalışmıyor. Neden bu kadar çok oy olduğunu bilmiyorum. Bu eski sürümlerde uygulanabilir miydi?
Yarneo

627

hızlı

resim açıklamasını buraya girin

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

Seçenekleri keşfetme

resim açıklamasını buraya girin

resim açıklamasını buraya girin

resim açıklamasını buraya girin

resim açıklamasını buraya girin

resim açıklamasını buraya girin

Sorun 1: Gölge kırpılıyor

İçeriğini görüşümüzün sınırlarına kırpmak istediğimiz alt katmanlar veya alt görünümler (resim gibi) varsa ne olur?

resim açıklamasını buraya girin

Bunu şu şekilde yapabiliriz:

blueView.layer.masksToBounds = true

(Alternatif olarak, aynı sonucublueView.clipsToBounds = true verir .)

resim açıklamasını buraya girin

Ama, hayır! Gölge de kesildi çünkü sınırların dışında! Ne yapalım? Ne yapalım?

Çözüm

Gölge ve kenarlık için ayrı görünümler kullanın. Taban görünümü saydamdır ve gölgeye sahiptir. Sınır görünümü, sınırlarına sahip olduğu diğer alt içerikleri de kırpar.

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

Bu, aşağıdaki sonucu verir:

resim açıklamasını buraya girin

Sorun 2: Kötü performans

Yuvarlak köşeler ve gölgeler eklemek bir performans isabeti olabilir. Gölge için önceden tanımlanmış bir yol kullanarak ve ayrıca rasterleştirileceğini belirterek performansı artırabilirsiniz. Aşağıdaki kod yukarıdaki örneğe eklenebilir.

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

Daha fazla ayrıntı için bu gönderiye bakın. Buraya ve buraya da bakın .

Bu cevap Swift 4 ve Xcode 9 ile test edildi.


1
@ EICaptainv2.0, Yalnızca bir kenarlık (ve / veya köşe yarıçapı) istiyorsanız, ayrı bir görünüme ihtiyacınız yoktur. Ayrı görüş, yuvarlak köşelere ve gölgeye ihtiyaç duyduğunuz durum içindir .
Suragch

2
Bu benim için çalışmıyor. BaseView üzerinde arka zemin rengini temizlemek için ayarladığımda artık bir gölge görünmüyor. Neyi yanlış yapıyorum?
Rutger Huijsmans

3
Çalışmıyorsa, ayar baseView.backgroundColor = UIColor.cleargölgeyi kaldırır. Yalnızca bir arka plan rengi ayarladıysanız görürsünüz.
Aleksander

2
BENİM İÇİN ÇALIŞMAYIN.
Markus

4
FYI Başlangıçta diğer yorumcuların baseView'un gölgesinin arka plan rengi açık olduğunda nerede görünmediğini gördüğü sorunu görüyordum. Sorun sadece kodun ilk bölümünü (baseView şeyler) çalıştırıyordu. Bir alt görünüm olarak borderView ekledikten sonra gölge görüntülenmeye başladı. Gölgenin görüntülenmesi için görünüm hiyerarşisinde en az bir görünür kenarlık (veya arka plan) olması gerekir. Saydam olmayan bir borderView.layer.borderColor (veya saydam olmayan bir arka plan rengi) ile borderView.layer.borderWidth> = 0 olduğundan emin olun
Mike Vosseller

79

Bunu yapmanın bir yolu, köşeleri yuvarlatılmış görünümü alt gölge ile görünüm haline getirmektir.

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];

Ardından, shadowView'ı istediğiniz yere ekleyebilirsiniz.


5
Amit, sadece * roundedView * için maskToBounds / clipToBounds = YES ayarlamanız gerekir. Bunu shadowView olarak ayarlamayın. Yukarıdaki kodu denemedim ama bu çözüm kesinlikle ideal olmasa da kesinlikle emin biliyorum. Yüksek gölge Radadi köşe yarıçapı alanlarına bakar. ShadowRadius'u 0 veya 1 olarak ayarlayın ve ne demeye çalıştığımı göreceksiniz.
Deepak GM

2
ShadowView.layer.shadowOpacity = 0.6 gibi bir şey; eksik
Bo.

3
"shadowView.layer.opacity = 1.0", "shadowView.layer.shadowOpacity = 1.0" olmalı
Chris

ShadowView.layer.shadowOpacity = 1.0
Mansurov Ruslan

ShadowOpacity için kod düzeltildi
Softlion

63

Bileşeni doğru kullandığınızdan emin olmak için GitHub'daki örnek projeye göz atın .

Ek alt görünüm veya alt sınıflama olmadan basit Swift 5 çözümü:

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

Aramadan önce görünümünüzü köşe yarıçapı ve diğer özelliklerle ayarlamanız gerektiğini unutmayın addShadow.

Bundan sonra, bunu şu şekilde arayın viewDidLoad:

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

Son sonuç:

sonuç

Süper kolay ve basit!


Bu düğmeler üzerinde çalışıyor mu? Çünkü bu benim için çalışmıyor.
Cesare

Önerdiğiniz adımları izlemeyi denedim. Ama hala şans yok. Nasıl yaptığınızı görmek için bir örnek (Github'da) paylaşmanız harika olurdu, ki bu benim ve diğer insanlar için imkansız görünüyor.
Hemang

Sadece bu satırı kaldırarak çalışmasını sağladı layer.shadowPath = UIBezierPath.init(roundedRect: layer.bounds, cornerRadius: layer.cornerRadius).cgPath. Neden olduğunu açıklayamıyorum, birisinin bunun için bir açıklaması var mı?
trupin

@Curnelious, bir Xcode proje örneği ile güncellenmiş cevaba göz atmaktan çekinmeyin.
Çalışamıyor

3
Bu benim için de işe yaradı, sadece bir şey daha gerekiyor tüm alt görünümleri arka plan rengini temizlemek için yapmak, böylece sadece konteyner görünümü görünür bir arka plana sahip ve bu benim sorunumu çözdü. Teşekkürler!! @SergeyGrischyov
Rishabh

42

Bu benim için çalıştı. Hile, arka plan rengini ana görünümden katmana taşımaktı.

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 ;

Diğer tüm çözümler işe yarıyor olsa da ve belki de daha genel olsalar da, bu sorun için en iyi çözümdür. Alt görünümler veya alt katmanlar eklemek, kare boyutlarını korumaya çalışan bir dünya veya acı yaratır veya en iyi ihtimalle performans sorunlarına neden olabilir.
emem

Cevap bu olmalı. Temiz ve zarif.
Axy

En iyi çözüm ve kesinlikle zarif!
Roberto Ferraz

Vay canına, bu gerçekten işe yarıyor. Neden çalışması gerektiğini anlamıyorum - görünümün backgroundColor düzgün iOS doğrudan layer.backgroundColor özelliği ile eşleşeceğini düşünürdüm - ama ÇALIŞIYOR. (Xcode 8, Swift 3.) Aferin ve teşekkürler. Bu kabul edilen cevap olmalı.
Womble

UIView extensionBurada kullanarak yanıtınızın Swift 3.1 sürümünü oluşturdum - stackoverflow.com/a/43295741/1313939 İlhamınız için teşekkürler!
Sergey Grischyov

26

Kapsayıcı görünümü için gölge yolu atarken aşağıdaki hileyi kullanarak sorunu çözdüm:

[UIBezierPath bezierPathWithRoundedRect:cell.bounds cornerRadius:12]

Gölgeye verilen yolun, hücrenin içerdiği arka planla aynı köşe yarıçapına sahip yuvarlak bir dikdörtgen olduğuna dikkat edin:

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

En iyi yanıt, daha yuvarlak köşeli bir görünüme gölge eklemenin doğru yolunu açıkladığı için. @Alex Stone
programcı

17

Eğer yuvarlanmış cornersvs.'ye subviewskarşı mücadele ediyorsanız masksToBounds, benim fonksiyonumu kullanmayı deneyin:

- (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;
}

görünümünüzde arayın. görünümünüzün köşeleri yuvarlanmış olsun, boyutu ne olursa olsun, şekli - hoş bir gölge çizilecek.

Tablonun kaldırılmasını istediğinizde başvurabilmeniz için işlevin dönüş değerini korumanız yeterlidir (veya örneğin kullanın insertSubview:aboveView:)


iyi çalışıyor. Ancak görünümde hareket tanıyıcılar varsa, çalışmaz. nasıl çözebiliriz?
manujmv

@manujmv "// Gerekirse bunu değiştir" ifadesinin belirtildiği satırları görüyor musunuz? İhtiyacın olan bu. shadow.userInteractionEnabled = EVET;
daniel.gindi

@manujmv o zaman neden görmek için görünüm ve alt görünüm çerçevelerini test etmelisiniz. muhtemelen orada bir şey yok. Bu tam kod bazı çok güzel uygulamalarda benim için çalışıyor
daniel.gindi

2
Bu çözüm, köşeleri yuvarlatılmış UITableViews için harika çalışıyor. Keşke daha fazla oy verebilsem. Teşekkürler!
Chris Hart

@ CarlosEduardoLópez Çizgiyi görüyor musunuz shadow.userInteractionEnabled = NO; // Modify this if needed? Yani ihtiyaç duyulan durum budur. userInteractionEnabledzaten aşina olmanız gereken temel ve popüler bir özelliktir :-)
daniel.gindi

12

Swift 4 ve Xcode 9'u kullanarak , bir alt ImageViewgölge ve bir kenarlık içeren bir yuvarlama için çalışan bir örnektir .

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

resim açıklamasını buraya girin

Görüntünün dairesel olmasını istiyorsanız: (ve kenarlıksız olarak gösterilir)

let cornerRadius = imageWidth / 2

resim açıklamasını buraya girin


7

UIView'da bir yardımcı oluşturdum

@interface UIView (Helper)

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

buna böyle diyebilirsin

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

İşte uygulama

- (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
Bu iyi ve zarif bir çözüm. Kullanmadan önce görünümünüzün denetimine eklendiğinden emin olun. Bana gölge üzerinde daha fazla kontrol sağlamak için bazı parametreler ekledim, ancak genel olarak mükemmel çalışıyor. Teşekkürler!
Aaron Vegh

Bu güzel bir çözüm ancak Otomatik mizanpaj ile çalışmayı yapmaz: görünüm kökeni 0,0 tarihinde çekilecek
gderaco

5

Yuvarlak köşe görünümünün gölge ile bir günlük bir araştırmasından sonra, özel uiview sınıfımı buraya göndermekten memnuniyet duyuyorum, bu soruyu bitirmeyi umuyoruz:

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

Bu nedenle, hedef görünümde alt veya üst görünüm eklemenize gerek yok, sadece geçerli görünümde bir katman ekleyin ve tamamlamak için 3 adım yapın!

koddaki yorumlara yakından bakın, bileşeni anlamak yardımcı olur!


5

Hızlı 4'te test edilen bir şey

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

üretir

resim açıklamasını buraya girin

Müfettiş'te şu şekilde etkinleştirirseniz:

resim açıklamasını buraya girin

Kullanıcı Tanımlı Çalışma Zamanı Özelliğini ekler ve bunun sonucunda:

resim açıklamasını buraya girin

(Daha önce ekledim cornerRadius = 8)

:)


5

Kullanımı shadowViewveroundView

resim açıklamasını buraya girin

shadowView

  • Arka plan rengi olmalı
  • Geride kalmalı roundView
  • İşin püf noktası, shadowViewiçeride bir düzen oluşturmak ve gölgesinin parlaması gerekiyor. Arkada tamamen görünmeyecek insetsşekilde ayarlayınshadowViewroundView

Roundview

  • Klip alt klipleri gerekir

Kod

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
}

Veya aşağıda belirtmeden yapabilirsiniz clipToBounds/maskToBounds

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

4

Swift 3 ve IBI öngörülebilir çözüm: Ade'nin çözümünden
ilham aldı

İlk olarak, bir UIView uzantısı oluşturun:

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

Ardından, arayüz oluşturucu ayar gölgesi AÇIK ve köşe yarıçapında UIView'inizi aşağıdaki gibi seçmeniz yeterlidir :

UIView'inizi seçme

Gölge AÇIK ve köşe yarıçapını ayarlama

Sonuç!

Sonuç


Bu konudaki diğer tüm "çözümler" gibi, en azından iOS 11.0 / Swift 4.1'de çalışmaz.
inexcitus

Konunun başında "Swift 3" ü okudunuz mu? Yani bu bir Swift 3 çözümü, Swift 4.1'de test etmedim çünkü artık ihtiyacım yok. Cevabı düzenlemekten ve bir çözüm vermekten çekinmeyin. ;) Şerefe
Thomás Calmon

3

İşte masksToBounds çatışma sorununun çözümü, benim için çalışıyor.

CorderRadius / borderColor / shadow ve benzerlerini ayarladıktan sonra masksToBounds öğesini NO olarak ayarlayın:

v.layer.masksToBounds = NO;

Bu benim için çalıştı !! Aman tanrım, neredeyse cevap verdiğin hileleri neredeyse yaptım! teşekkürler Shaopeng.
MontDeska

3

Gölge + Sınır + Köşe Yarıçapı resim açıklamasını buraya girin

    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

İşte bir UIView için Swift 3'teki sürümüm

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'in Alt Sınıfını Oluşturun

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
    }

}

Kullanımı ..

Sınıf Gölge Görünümü'nü kullanma


2

Eğer uçlarınızı değiştirmek ve hiyerarşiyi önerilen David C. olarak görmek istemiyorsanız, bu yöntem sizin için yapacaktır. UIImageView'ınıza yuvarlatılmış köşeler ve gölge eklemek için sadece bu yöntemi kullanın, örneğin:

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

(!) Performans nedenleriyle, bu kodu UITableView gibi bir şeyde kullanmanın iyi bir fikir olduğunu düşünmüyorum, çünkü bu kod görünüm hiyerarşisini değiştirir. Bu yüzden ucunuzu değiştirmenizi ve gölge efekti için bir kap görünümü eklemenizi ve Davic C. kodunu kullanmanızı öneririm.

+ (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

Eski iplik hala geçerli ...

Daniel Gindi'nin yöntemini düğmelerle de kullanmayı mümkün kılmak için düzenledim. Herhangi birinin yuvarlak köşelere ihtiyacı varsa veya yuvarlak köşeleri ve bir sınırı birleştirmek istiyorsa, görünümün bu yönteme geçirilen katmanına ayarlanması gerekir. Rasterleştirmeyi biraz hızlandırmak için de ayarladım.

+ (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

Aşağıdakiler benim için en iyi sonucu verdi (bu kod UIView uzantısında yer alıyor, bu yüzden kendi kendine gölge ve yuvarlak köşe eklememiz gereken bazı UIView'i gösteriyor)

- (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];
}

Bu ve diğer kod örnekleri arasındaki temel fark, bunun gölge görünümünü bir kardeş görünümü olarak eklemesidir (mevcut görünümü gölge görünümünün alt görünümü olarak eklemeye karşı), böylece mevcut görünüm hiyerarşisini herhangi bir şekilde değiştirme ihtiyacını ortadan kaldırır.


1

daniel.gindi'nin yukarıdaki cevabı benim için hile yaptı! (+1 daniel) Ancak, küçük ayarlamalar yapmak zorunda kaldım - shadowFrame boyutunu görünümün kare boyutuyla aynı olacak şekilde değiştirmek ve kullanıcı etkileşimini etkinleştirmek zorunda kaldım. Güncellenmiş kod:

+ (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;
}

Benim durumumda, bu bir üçüncü taraf görünüm denetleyicisine eklemek için çalışıyordu eklemek istiyorum, yani kod üzerinde doğrudan kontrol yoktu. Yani, yukarıdaki işlevi nasıl kullandım:

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 kodunda bazı değişiklikler yapıyorum

Çalıştırmak için ihtiyacınız olan her şey bu.

+ (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

Bunu UIViewsbaşarmak için iki tane kullanmanız gerekir . Biri UIViewgölge gibi, diğeri yuvarlak kenarlık için çalışacaktır.

İşte kod pasajı a'nın Class Methodyardımıyla 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;
}

Yukarıdaki kodda , düğme tıklamasıyla tetiklenecek btnCompose_click:bir @requiredtemsilci yöntemi haline gelecektir .

Ve burada UIViewControllerböyle bir düğme ekledim :

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];

Sonuç şöyle görünecektir:

resim açıklamasını buraya girin


1

Bu yazıdan çok sayıda çözüm denedim ve aşağıdaki çözümle sonuçlandım. Bu, gölgeyi net bir renk görünümünde düşürmeniz gerekmediği sürece tam kanıtlı bir çözümdür .

- (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;
}

İfade "aptal geçirmez" dir. :)
Ben Thomas

Sadece İngilizceyi düzeltiyordum. :) Çözüm işe yarıyor.
Ben Thomas

1

İşte kesinlikle işe yarayacak çözüm!

Aşağıdaki gibi gölge uygulamak için gerekli kenarlara sahip UIView uzantısı oluşturdum


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

Son olarak, UIView alt sınıflarınızdan herhangi biri için gölge işlevini aşağıdaki gibi çağırabilirsiniz, ayrıca gölge uygulanacak kenarı belirtebilir, aşağıdaki yöntem çağrısının parametrelerini değiştirmenize göre farklı varyasyonlar deneyebilirsiniz.

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

Sonuç resmi

resim açıklamasını buraya girin

resim açıklamasını buraya girin

resim açıklamasını buraya girin


0

Evan Mulawski'nin verdiği cevap mükemmel bir şekilde çalışacaktır. Yakalama, görünüm için arka plan rengini clearColor ve masksToBounds özelliğini NO olarak ayarlamanızdır.

Görünüm için istediğiniz rengi ayarlayabilirsiniz,

v.layer.backgroundColor = your color;

Bu yardımcı olur umarım..


0

Yuvarlatılmış köşeleri ve yuvarlatılmış gölgeleriyle, yolları rahatsız etmeden böyle yaparsınız.

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

İçerikli görünüm, benim durumumda bir UIImageView, bir köşe yarıçapına sahiptir ve bu nedenle sınırlara maskelemek zorundadır.

Gölgeler için eşit boyutta başka bir görünüm oluştururuz, maskToBounds değerini NO olarak ayarlarız ve ardından içerik görünümünü kapsayıcı görünümüne ekleriz (örn. ShadowContainer).


0

Bu sorunu çözmek için bu UIView kategori yöntemini yazıyorum, gölge ve köşe yarıçapı için ayrı görünümler kullanıyor.

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

UICollectionViewCell'i yuvarlak hale getirmek ve Gölgeler eklemek için Swift 4 Çözümü herhangi bir uzantı ve komplikasyon olmadan :)

Not: Basit görünümler için, örneğin Düğmeler. Bu yayındaki @ suragch'ın Cevabına bakınız. https://stackoverflow.com/a/34984063/7698092 . Düğmeler için başarıyla test edildi

Durumunda herhangi bir eğer hala mücadele etmek yuvarlamak köşeleri ve eklemek gölgeleri aynı anda. Bu çözüm UICollectionViewCell ile çalışsa da, herhangi bir görünüme genelleştirilebilir.

Bu teknik benim için herhangi bir uzantı ve karmaşık şeyler yapmadan çalıştı. StoryBoard ile çalışıyorum.

teknik

StoryBoard'da UICollectionViewCell'inize bir UIView ("containerView" diyelim) eklemeli ve bu kapsayıcıView içine gerekli tüm görünümleri (düğmeler, resimler vb.) Eklemelisiniz. Ekran görüntüsüne bakın. Hücrenin Yapısı

ContainerView için çıkışı bağlayın. CellforItemAtIndexPath delege işlevine aşağıdaki kod satırlarını ekleyin.

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

Çıktı

Simülatör ekran görüntüsüne bakın Gölgeli yuvarlak köşeler (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)
        }

    }
}

Merhaba, teşekkürler cevap için, size anlatıldığı gibi bir açıklama Kodunuza bazı yorumlar eklemek gerekir Yanıt nasıl .
Baptiste Mille-Mathias
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.