UIView dengan sudut bulat dan drop shadow?


390

Saya ingin kebiasaan UIView...: Saya hanya ingin tampilan putih kosong dengan sudut bulat dan bayangan setetes cahaya (tanpa efek pencahayaan). Saya dapat melakukan masing-masing satu per satu tetapi yang biasa terjadi clipToBounds/ maskToBoundskonflik.


1
Karena Anda mengatakan dalam komentar di bawah ini bahwa Anda mendapatkan pekerjaan ini menggunakan CoreGraphics, maukah Anda berbagi jawaban dengan komunitas sehingga Anda dapat membantu orang lain dalam situasi yang sama, ketika mereka mencoba membantu Anda?
lnafziger

Maaf, ini sudah lama sekali, dan saya tidak punya sumbernya lagi. Apa yang saya lakukan adalah menimpa -drawRect: dan menggunakan UIBezierPath untuk menggambar persegi panjang, dan menerapkan bayangan ke lapisan yang mendukung tampilan ... jika saya ingat dengan benar. :)
Aditya Vaidyam

5
Jawaban yang diterima tidak berfungsi!
onmyway133

1
Kemungkinan duplikat dari Memberikan sudut bulat UIView

1
@Sachavijay Anda harus memverifikasi tanggal dari kedua posting sebelum Anda berkomentar.
Aditya Vaidyam

Jawaban:


444

Cuplikan kode berikut menambahkan perbatasan, radius perbatasan, dan drop shadow ke v, a 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)];

Anda dapat menyesuaikan pengaturan sesuai dengan kebutuhan Anda.

Juga, tambahkan kerangka kerja QuartzCore ke proyek Anda dan:

#import <QuartzCore/QuartzCore.h>

Lihat jawaban saya yang lain tentang masksToBounds.


Catatan

Ini mungkin tidak berfungsi dalam semua kasus. Jika Anda menemukan bahwa metode ini mengganggu operasi gambar lain yang sedang Anda lakukan, silakan lihat jawaban ini .


83
Masalahnya adalah ketika saya mengatur radius sudut, ia menetapkan maskToBounds: YA, sedangkan bayangan membutuhkan clipToBounds: TIDAK (di mana clipToBounds melakukan hal yang sama dengan maskToBounds)
Aditya Vaidyam

15
Masalah yang sama disini. Jika saya memiliki warna latar belakang saya ingin itu terpotong ke sudut bulat. Untuk melakukan itu saya harus menggunakan maskToBounds = BENAR, tetapi kemudian bayangan menghilang ..
hfossli

3
Untuk pemula seperti saya: Saya harus mengimpor kerangka kerja QuartzCore ke proyek saya untuk memanggil metode pada objek layer.
SilithCrowe

38
Cara untuk mendapatkan ini berfungsi dengan cara yang benar adalah dengan menggunakan tampilan wadah bagian dalam, yang akan menampung perbatasan Anda dan warna latar belakang Anda, keduanya dengan radius sudut. Tampilan ini akan terpotong menjadi batas! Tampilan kontainer kedua yang luar akan menampung yang pertama, memiliki bingkai yang sama, hanya dengan drop shadow. Saya telah melakukan ini beberapa kali untuk menggabungkan garis batas, bayangan, dan sudut. Benar-benar menjengkelkan, tetapi bekerja dengan sangat baik.
Kpmurphy91

23
Tidak bekerja Tidak tahu mengapa ada begitu banyak suara. Apakah ini berlaku di versi yang lebih lama?
Yarneo

628

Cepat

masukkan deskripsi gambar di sini

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

Menjelajahi opsi

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

Masalah 1: Bayangan terpotong

Bagaimana jika ada sublayers atau subview (seperti gambar) yang isinya ingin kita klip ke batas tampilan kita?

masukkan deskripsi gambar di sini

Kita bisa menyelesaikan ini dengan

blueView.layer.masksToBounds = true

(Atau, blueView.clipsToBounds = trueberikan hasil yang sama .)

masukkan deskripsi gambar di sini

Tapi, oh tidak! Bayangan itu juga terpotong karena berada di luar batas! Apa yang harus dilakukan? Apa yang harus dilakukan?

Larutan

Gunakan tampilan terpisah untuk bayangan dan perbatasan. Tampilan dasar transparan dan memiliki bayangan. Tampilan perbatasan klip setiap subkonten lain yang ada di perbatasannya.

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

Ini memberikan hasil sebagai berikut:

masukkan deskripsi gambar di sini

Masalah 2: Performa buruk

Menambahkan sudut bulat dan bayangan bisa menjadi hit kinerja. Anda dapat meningkatkan kinerja dengan menggunakan jalur yang telah ditentukan untuk bayangan dan juga menentukan bahwa itu akan di-raster. Kode berikut dapat ditambahkan pada contoh di atas.

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

Lihat posting ini untuk lebih jelasnya. Lihat di sini dan di sini juga.

Jawaban ini diuji dengan Swift 4 dan Xcode 9.


1
@ EICaptainv2.0, Jika Anda hanya menginginkan batas (dan / atau radius sudut) maka Anda tidak memerlukan tampilan terpisah. Pandangan terpisah adalah untuk situasi di mana Anda membutuhkan sudut dan bayangan bulat .
Suragch

2
Ini tidak bekerja untuk saya. Ketika saya mengatur kembali warna tanah untuk menghapus pada baseView bayangan tidak muncul lagi. Apa yang saya lakukan salah?
Rutger Huijsmans

3
Tidak bekerja, pengaturan baseView.backgroundColor = UIColor.clearmenghapus bayangan. Hanya jika Anda mengatur warna latar belakang Anda akan melihatnya.
Aleksander

2
TIDAK BEKERJA UNTUK SAYA.
Markus

4
FYI Saya awalnya melihat masalah yang sama dengan komentator lain melihat di mana bayangan baseView tidak ditampilkan ketika warna latar belakangnya jelas. Masalahnya adalah bahwa saya hanya menjalankan bagian pertama dari kode (hal-hal baseView). Setelah saya menambahkan borderView sebagai subview, bayangan mulai ditampilkan. Tampaknya untuk menampilkan bayangan harus ada setidaknya satu perbatasan terlihat (atau latar belakang) dalam hierarki tampilan itu. Jadi, pastikan untuk memiliki borderView.layer.borderWidth> = 0 dengan borderView.layer.borderColor yang tidak transparan (atau warna latar yang tidak transparan)
Mike Vosseller

79

Salah satu cara untuk melakukan ini adalah menempatkan tampilan dengan sudut bulat dalam tampilan dengan drop shadow.

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

Kemudian Anda dapat menambahkan shadowView di mana pun Anda inginkan.


5
Amit, Anda harus mengatur maskToBounds / clipToBounds = YA untuk * roundedView saja *. JANGAN atur ini ke shadowView. Saya belum mencoba kode di atas tetapi tahu pasti bahwa solusi ini pasti berfungsi meskipun tidak ideal. ShadowRadius yang lebih tinggi menangani area radius sudut. Atur shadowRadius ke 0 atau 1 dan Anda akan melihat apa yang saya coba katakan.
Deepak GM

2
Sesuatu seperti shadowView.layer.shadowOpacity = 0,6; hilang
Bo.

3
"shadowView.layer.opacity = 1.0" harus "shadowView.layer.shadowOpacity = 1.0"
Chris

Bekerja di iOS 9 jika menggunakan shadowView.layer.shadowOpacity = 1.0
Mansurov Ruslan

Kode diperbaiki untuk shadowOpacity
Softlion

63

Lihat contoh proyek di GitHub untuk memastikan Anda menggunakan komponen dengan benar.

Solusi Simple Swift 5 tanpa subview atau subclassing tambahan:

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

Perhatikan bahwa Anda harus mengatur tampilan Anda dengan jari-jari sudut dan properti lainnya sebelum memanggil addShadow .

Setelah itu, panggil saja ini dari viewDidLoadseperti ini:

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

Hasil akhir:

hasil

Sangat mudah dan sederhana!


Apakah ini berfungsi pada tombol? Karena itu tidak bekerja pada saya.
Cesare

Saya mencoba mengikuti langkah-langkah tepat yang Anda sarankan. Tapi tetap tidak berhasil. Alangkah baiknya jika Anda membagikan sampel (di Github) untuk melihat bagaimana Anda telah melakukan yang tampaknya mustahil bagi saya dan orang lain.
Hemang

Berhasil membuatnya hanya dengan menghapus baris ini layer.shadowPath = UIBezierPath.init(roundedRect: layer.bounds, cornerRadius: layer.cornerRadius).cgPath. Tidak dapat menjelaskan mengapa, apakah seseorang memiliki penjelasan untuk itu?
trupin

@Curnelious merasa bebas untuk melihat jawaban yang diperbarui dengan contoh proyek Xcode. Tidak bisa tidak bekerja :)
Sergey Grischyov

3
Ini bekerja untuk saya juga, hanya perlu satu hal lagi adalah membuat semua warna latar subview menjadi jelas sehingga hanya tampilan wadah yang memiliki latar belakang yang terlihat dan ini menyelesaikan masalah saya. Terima kasih!! @SergeyGrischyov
Rishabh

42

Ini berhasil untuk saya. Triknya adalah memindahkan warna latar belakang dari tampilan utama ke layer.

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 ;

Meskipun semua solusi lain bekerja, dan mungkin lebih umum, ini adalah solusi terbaik untuk masalah ini. Menambahkan subview atau sublayer menciptakan dunia atau rasa sakit yang berusaha mempertahankan ukuran frame, atau, paling-paling, dapat menyebabkan masalah kinerja.
emem

Ini seharusnya jawabannya. Bersih dan elegan.
Axy

Solusi terbaik dan pasti elegan!
Roberto Ferraz

Wow, ini benar-benar berfungsi. Saya tidak mengerti mengapa itu harus bekerja - Anda akan berpikir backgroundColor tampilan dengan benar akan langsung memetakan ke properti layer.backgroundColor di iOS - tetapi TIDAK BEKERJA. (Xcode 8, Swift 3.) Bagus sekali, dan terima kasih. Ini harus menjadi jawaban yang diterima.
Womble

Saya telah membuat versi Swift 3.1 dari jawaban Anda menggunakan di UIView extensionsini - stackoverflow.com/a/43295741/1313939 terima kasih atas inspirasinya!
Sergey Grischyov

26

Saya memecahkan masalah menggunakan trik berikut saat menetapkan jalur bayangan untuk tampilan wadah:

[UIBezierPath bezierPathWithRoundedRect:cell.bounds cornerRadius:12]

Perhatikan bahwa jalur yang diberikan ke bayangan adalah persegi panjang bulat dengan jari-jari sudut yang sama dengan latar belakang sel:

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

Jawaban terbaik karena ini menjelaskan cara yang benar untuk menambahkan bayangan ke tampilan sudut yang lebih bulat. Terima kasih @Alex Stone
programmer

17

Jika Anda berjuang karena dibulatkan cornersvs subviewsvs masksToBounds, maka coba gunakan fungsi saya:

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

sebut saja pada pandangan Anda. apakah sudut pandang Anda membulat, tidak peduli ukurannya, bentuknya - bayangan yang bagus akan digambar.

Simpan saja nilai pengembalian fungsi sehingga Anda dapat merujuknya saat Anda ingin menghapus tabel (atau misalnya digunakan insertSubview:aboveView:)


ini bekerja dengan baik. Tetapi jika tampilan memiliki pengenal isyarat, maka itu tidak akan berfungsi. bagaimana kita bisa menyelesaikannya?
manujmv

@manujmv Apakah Anda melihat baris di mana "// Ubah ini jika perlu" ditentukan? Itu yang kamu butuhkan. shadow.userInteractionEnabled = YA;
daniel.gindi

@manujmv maka Anda harus menguji bingkai tampilan dan subview untuk melihat alasannya. sesuatu yang mungkin tidak ada di sana. kode persis ini bekerja untuk saya dalam beberapa aplikasi yang sangat bagus
daniel.gindi

2
Solusi ini sangat bagus untuk UITableViews dengan sudut yang membulat. Seandainya saya bisa memberikan lebih banyak suara. Terima kasih!
Chris Hart

@ CarlosEduardoLópez Apakah Anda melihat shadow.userInteractionEnabled = NO; // Modify this if neededgaris? Jadi ini adalah kasus di mana dibutuhkan. userInteractionEnabledadalah properti dasar dan populer yang harus Anda kenal :-)
daniel.gindi

12

Menggunakan Swift 4 dan Xcode 9 , ini adalah contoh yang berhasil dari pembulatan ImageViewdengan drop shadow, dan perbatasan.

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

masukkan deskripsi gambar di sini

Jika Anda ingin gambar menjadi lingkaran: (dan ditampilkan tanpa batas)

let cornerRadius = imageWidth / 2

masukkan deskripsi gambar di sini


7

Saya telah membuat pembantu di UIView

@interface UIView (Helper)

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

Anda bisa menyebutnya seperti ini

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

Inilah implementasinya

- (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
Ini adalah solusi elegan yang bagus. Pastikan bahwa tampilan Anda telah ditambahkan ke superview sebelum digunakan. Saya menambahkan beberapa parameter untuk memberi saya lebih banyak kontrol atas bayangan, tetapi secara keseluruhan berfungsi sempurna. Terima kasih!
Aaron Vegh

Ini adalah solusi yang bagus tetapi tidak bekerja dengan autolayout: tampilan akan diambil pada asal 0,0
gderaco

5

Setelah satu hari penuh meneliti tampilan sudut bulat dengan bayangan, saya senang memposting kelas uiview kebiasaan saya di sini, berharap untuk mengakhiri pertanyaan ini:

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

jadi, TIDAK perlu menambahkan tampilan subview atau di bawah ini dalam tampilan target, cukup tambahkan satu layer dalam tampilan saat ini, dan lakukan 3 langkah untuk menyelesaikannya!

perhatikan komentar di dalam kode, sangat membantu untuk memahami komponen!


5

Sesuatu yang cepat diuji dalam Swift 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
        }
    }
}

Menghasilkan

masukkan deskripsi gambar di sini

Jika Anda mengaktifkannya di Inspektur seperti ini:

masukkan deskripsi gambar di sini

Ini akan menambahkan Atribut Runtime yang Ditentukan Pengguna, menghasilkan:

masukkan deskripsi gambar di sini

(Saya menambahkan sebelumnya cornerRadius = 8)

:)


5

Anda harus menggunakan gunakan shadowViewdanroundView

masukkan deskripsi gambar di sini

shadowView

  • Harus memiliki warna latar belakang
  • Harus berbaring roundView
  • Caranya adalah dengan tata letak shadowViewsedikit di dalam, dan bayangannya perlu menyala. Sesuaikan insetssehingga shadowViewbenar-benar tidak terlihat di belakangroundView

roundView

  • Harus klip subview

Kode

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
}

Atau Anda bisa melakukan di bawah ini tanpa menentukan clipToBounds/maskToBounds

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

4

Solusi Swift 3 & IBInspectable:
Terinspirasi oleh solusi Ade

Pertama, buat ekstensi 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
          }
     }
}

Kemudian, cukup pilih UIView Anda di pengaturan antarmuka, bayangan, ON, dan radius sudut , seperti di bawah ini:

Memilih UIView Anda

Mengatur bayangan ON & radius sudut

Hasil!

Hasil


Seperti setiap "solusi" lainnya di utas ini, itu tidak berfungsi, setidaknya tidak pada iOS 11.0 / Swift 4.1.
inexcitus

Apakah Anda membaca "Swift 3" di awal utas? Jadi, itu berarti solusi Swift 3, saya tidak mengujinya di Swift 4.1 karena saya tidak membutuhkannya lagi. Jangan ragu untuk mengedit jawaban dan memberikan solusi. ;) Cheers
Thomás Calmon

3

Inilah solusi untuk masalah konflik masksToBounds, ini berhasil untuk saya.

Setelah Anda mengatur corderRadius / borderColor / shadow dan sebagainya, atur masksToBounds sebagai NO:

v.layer.masksToBounds = NO;

Ini berhasil bagi saya !! omg Saya hampir melakukan semua trik di atas yang Anda jawab! terima kasih Shaopeng.
MontDeska

3

Shadow + Border + Radius Pojok masukkan deskripsi gambar di sini

    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

Ini adalah versi saya di Swift 3 untuk 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: Buat Subclass dari 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
    }

}

Menggunakan ..

Gunakan Tampilan Bayangan Kelas


2

Jika Anda tidak ingin mengubah nib dan melihat hierarki seperti yang disarankan David C. metode ini akan melakukannya untuk Anda. Untuk menambahkan sudut bulat dan bayangan ke UIImageView Anda, cukup gunakan metode ini, misalnya:

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

(!) Untuk alasan kinerja, saya rasa ini bukan ide yang baik untuk menggunakan kode ini dalam sesuatu seperti UITableView, karena kode ini mengubah hierarki tampilan. Jadi saya akan menyarankan untuk mengubah pena Anda dan menambahkan tampilan wadah untuk efek bayangan dan menggunakan kode 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

Utas lama masih berlaku ...

Saya telah mengedit metode Daniel Gindi untuk memungkinkannya menggunakannya dengan tombol dll. Jika ada yang membutuhkan sudut bulat atau ingin menggabungkan sudut bulat dan perbatasan, maka harus ditetapkan pada layer view yang dilewatkan ke metode ini. Saya juga mengatur rasterisasi untuk mempercepatnya sedikit.

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

Berikut ini bekerja paling baik untuk saya (kode ini terletak pada ekstensi UIView, jadi self menunjukkan beberapa UIView yang harus kita tambahkan bayangan dan sudut bundar)

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

Perbedaan utama antara ini dan contoh kode lainnya adalah bahwa ini menambahkan tampilan bayangan sebagai tampilan saudara (dibandingkan dengan menambahkan tampilan saat ini sebagai subview tampilan bayangan), sehingga menghilangkan kebutuhan untuk mengubah hierarki tampilan yang ada dengan cara apa pun.


1

Jawaban daniel.gindi di atas telah membantu saya! (+1 daniel) Namun, saya harus melakukan sedikit penyesuaian - ubah ukuran shadowFrame menjadi sama dengan ukuran bingkai tampilan, dan aktifkan interaksi pengguna. Berikut kode yang diperbarui:

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

Saya ingin menambahkan bahwa dalam kasus saya, saya mencoba untuk menambahkan ini ke pengontrol tampilan pihak ke-3, yaitu saya tidak memiliki kontrol langsung atas kode. Jadi, inilah cara saya menggunakan fungsi di atas:

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

Saya membuat beberapa perubahan pada kode daniel.gindi

Ini semua yang Anda butuhkan untuk membuatnya bekerja.

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

Anda perlu menggunakan dua UIViewsuntuk mencapai ini. Satu UIViewakan bekerja seperti bayangan dan yang lainnya akan bekerja untuk perbatasan bulat.

Berikut ini cuplikan kode a Class Methoddengan bantuan 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;
}

Dalam kode di atas btnCompose_click:akan menjadi @requiredmetode delegasi yang akan diaktifkan pada klik tombol.

Dan di sini saya menambahkan tombol ke saya UIViewControllerseperti ini:

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

Hasilnya akan terlihat seperti ini:

masukkan deskripsi gambar di sini


1

Saya telah mencoba banyak solusi dari posting ini dan berakhir dengan solusi di bawah ini. Ini adalah solusi penuh bukti kecuali Anda perlu menjatuhkan bayangan pada tampilan warna yang jelas .

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

Ungkapannya adalah "bukti bodoh". :)
Ben Thomas

Saya hanya mengoreksi bahasa Inggris. :) Solusinya bekerja.
Ben Thomas

1

Inilah solusi yang pasti akan berhasil!

Saya telah membuat ekstensi UIView dengan tepi yang diperlukan untuk menerapkan bayangan seperti di bawah ini


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

Akhirnya, Anda dapat memanggil fungsi bayangan seperti di bawah ini untuk setiap subkelas UIView Anda, Anda juga dapat menentukan tepi untuk menerapkan bayangan pada, coba berbagai variasi sesuai kebutuhan Anda mengubah parameter panggilan metode di bawah ini.

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

Gambar hasil

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini


0

Jawaban yang diberikan oleh Evan Mulawski akan bekerja dengan sempurna. Tangkapannya adalah Anda harus mengatur warna latar belakang agar tampilan menjadi clearColor dan properti masksToBounds menjadi NO.

Anda dapat mengatur warna apa pun yang Anda inginkan untuk tampilan, mengaturnya seperti

v.layer.backgroundColor = your color;

Semoga ini membantu..


0

Ini adalah bagaimana Anda melakukannya, dengan sudut bulat dan bayangan bulat tanpa repot dengan jalan.

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

Tampilan dengan konten, dalam kasus saya sebuah UIImageView, memiliki jari-jari sudut dan karenanya harus ditutup-tutupi.

Kami membuat tampilan berukuran sama lain untuk bayangan, mengatur maskToBounds menjadi NO dan kemudian menambahkan tampilan konten ke tampilan wadah (mis. ShadowContainer).


0

Saya menulis metode kategori UIView ini untuk menyelesaikan masalah ini, menggunakan tampilan terpisah untuk bayangan dan radius sudut.

-(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 Solusi untuk membuat UICollectionViewCell putaran dan menambahkan Shadows , tanpa ekstensi dan komplikasi :)

Catatan: Untuk tampilan sederhana mis. Tombol. Lihat Jawaban @ suragch di pos ini. https://stackoverflow.com/a/34984063/7698092 . Diuji berhasil untuk tombol

Seandainya ada orang yang masih berjuang untuk berbelok di tikungan dan menambahkan bayangan pada saat yang sama. Meskipun solusi ini berfungsi dengan UICollectionViewCell, solusi ini dapat digeneralisasikan ke semua tampilan.

Teknik ini bekerja untuk saya tanpa membuat ekstensi dan semua hal yang rumit. Saya bekerja dengan storyBoard.

Teknik

Anda harus menambahkan UIView (katakanlah "containerView") di dalam UICollectionViewCell Anda di storyBoard dan tambahkan semua tampilan yang diperlukan (tombol, gambar, dll.) Di dalam containerView ini. Lihat Screenshot. Struktur sel

Hubungkan outlet untuk containerView. Tambahkan baris kode berikut dalam fungsi delegasi 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

Keluaran

Lihat Screenshot simulator Sudut membulat dengan Shadows (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)
        }

    }
}

Hai, terima kasih atas jawaban Anda, Anda harus menambahkan beberapa komentar ke kode Anda untuk menjelaskan sedikit seperti yang dijelaskan dalam Cara Menjawab .
Baptiste Mille-Mathias
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.