programing

UI뷰 아래에 그림자를 그리려면 어떻게 해야 합니까?

megabox 2023. 5. 29. 10:30
반응형

UI뷰 아래에 그림자를 그리려면 어떻게 해야 합니까?

저는 아래 가장자리에 그림자를 그리려고 합니다.UIView코코아 터치로.사용해야 한다는 것을 이해합니다.CGContextSetShadow()그림자를 그리려면 Quartz 2D 프로그래밍 가이드가 약간 모호합니다.

  1. 그래픽 상태를 저장합니다.
  2. 합니다.CGContextSetShadow적절한 값을 전달합니다.
  3. 그림자를 적용할 도면을 모두 수행합니다.
  4. 그래픽 상태 복원

나는다시니다습에서 .UIView하위 클래스:

- (void)drawRect:(CGRect)rect {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGContextSaveGState(currentContext);
    CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);
    CGContextRestoreGState(currentContext);
    [super drawRect: rect];
}

. 는 (a) 다음에 어디로 가야 그리고 제가 할대해 하지만 이것은 저에게 효과가 없습니다. 그리고 저는 (a) 다음에 어디로 가야 할지 그리고 (b) 제가 해야 할 일이 있는지에 대해 약간 고민하고 있습니다.UIView이 일을 성공시키기 위해?

훨씬 쉬운 접근 방식은 초기화 시 뷰의 일부 계층 속성을 설정하는 것입니다.

self.layer.masksToBounds = NO;
self.layer.shadowOffset = CGSizeMake(-15, 20);
self.layer.shadowRadius = 5;
self.layer.shadowOpacity = 0.5;

Quartz Core를 수입해야 합니다.

#import <QuartzCore/QuartzCore.h>
self.layer.masksToBounds = NO;
self.layer.cornerRadius = 8; // if you like rounded corners
self.layer.shadowOffset = CGSizeMake(-15, 20);
self.layer.shadowRadius = 5;
self.layer.shadowOpacity = 0.5;

이렇게 하면 응용 프로그램 속도가 느려집니다.다음 선을 추가하면 보기가 직사각형인 경우 성능이 향상될 수 있습니다.

self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath;

같은 해결책이지만, 여러분에게 상기시켜 드리자면, 스토리보드에서 바로 그림자를 정의할 수 있습니다.

예:

여기에 이미지 설명 입력

현코드저것은는장하를 합니다.GState현재 컨텍스트에서 섀도를 그리도록 구성하고 섀도를 그리도록 구성하기 전의 상태로 복원합니다.인 그런지다, ▁ofclass▁then▁implement다'▁invoke▁super니s▁you호,합을 실행합니다.drawRect: .

섀도 설정의 영향을 받아야 하는 도면은 다음 이후에 수행해야 합니다.

CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);

그러나 그 전에

CGContextRestoreGState(currentContext);

그래서 만약 당신이 슈퍼클래스를 원한다면,drawRect:그림자 속에서 '흔들림'을 당하려면, 코드를 이렇게 다시 정렬하면 어떨까요?

- (void)drawRect:(CGRect)rect {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGContextSaveGState(currentContext);
    CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);
    [super drawRect: rect];
    CGContextRestoreGState(currentContext);
}

이을시도수할 ▁you다▁values. 값을 가지고놀 수.값을 가지고 놀 수 있습니다.shadowRadius흐림의 양을 나타냅니다. shadowOffset그림자가 어디로 가는지 지시합니다.

스위프트 2.0

let radius: CGFloat = demoView.frame.width / 2.0 //change it to .height if you need spread for height
let shadowPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 2.1 * radius, height: demoView.frame.height))
//Change 2.1 to amount of spread you need and for height replace the code for height

demoView.layer.cornerRadius = 2
demoView.layer.shadowColor = UIColor.blackColor().CGColor
demoView.layer.shadowOffset = CGSize(width: 0.5, height: 0.4)  //Here you control x and y
demoView.layer.shadowOpacity = 0.5
demoView.layer.shadowRadius = 5.0 //Here your control your blur
demoView.layer.masksToBounds =  false
demoView.layer.shadowPath = shadowPath.CGPath

스위프트 3.0

let radius: CGFloat = demoView.frame.width / 2.0 //change it to .height if you need spread for height 
let shadowPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 2.1 * radius, height: demoView.frame.height)) 
//Change 2.1 to amount of spread you need and for height replace the code for height

demoView.layer.cornerRadius = 2
demoView.layer.shadowColor = UIColor.black.cgColor
demoView.layer.shadowOffset = CGSize(width: 0.5, height: 0.4)  //Here you control x and y
demoView.layer.shadowOpacity = 0.5
demoView.layer.shadowRadius = 5.0 //Here your control your blur
demoView.layer.masksToBounds =  false
demoView.layer.shadowPath = shadowPath.cgPath

산포가 있는 예제

산포가 있는 예제

기본 그림자를 작성하려면

    demoView.layer.cornerRadius = 2
    demoView.layer.shadowColor = UIColor.blackColor().CGColor
    demoView.layer.shadowOffset = CGSizeMake(0.5, 4.0); //Here your control your spread
    demoView.layer.shadowOpacity = 0.5 
    demoView.layer.shadowRadius = 5.0 //Here your control your blur

Swift 2.0의 기본 섀도 예제

산출량

Interface Builder를 사용한 간편하고 깔끔한 솔루션

프로젝트에 UIView.swift라는 파일을 추가합니다(또는 아무 파일에나 붙여넣습니다).

import UIKit

@IBDesignable extension UIView {

    /* The color of the shadow. Defaults to opaque black. Colors created
    * from patterns are currently NOT supported. Animatable. */
    @IBInspectable var shadowColor: UIColor? {
        set {
            layer.shadowColor = newValue!.CGColor
        }
        get {
            if let color = layer.shadowColor {
                return UIColor(CGColor:color)
            }
            else {
                return nil
            }
        }
    }

    /* The opacity of the shadow. Defaults to 0. Specifying a value outside the
    * [0,1] range will give undefined results. Animatable. */
    @IBInspectable var shadowOpacity: Float {
        set {
            layer.shadowOpacity = newValue
        }
        get {
            return layer.shadowOpacity
        }
    }

    /* The shadow offset. Defaults to (0, -3). Animatable. */
    @IBInspectable var shadowOffset: CGPoint {
        set {
            layer.shadowOffset = CGSize(width: newValue.x, height: newValue.y)
        }
        get {
            return CGPoint(x: layer.shadowOffset.width, y:layer.shadowOffset.height)
        }
    }

    /* The blur radius used to create the shadow. Defaults to 3. Animatable. */
    @IBInspectable var shadowRadius: CGFloat {
        set {
            layer.shadowRadius = newValue
        }
        get {
            return layer.shadowRadius
        }
    }
}

그런 다음 유틸리티 패널 > 속성 검사기의 모든 보기에 대해 인터페이스 작성기에서 사용할 수 있습니다.

유틸리티 패널

이제 그림자를 쉽게 설정할 수 있습니다.

사항
그림자는 IB에는 나타나지 않고 런타임에만 나타납니다.
카세르가 말했듯이 ▁as대말▁ma마의젠.

([...] 서브뷰)를 확인하십시오.clipsToBounds)가 활성화되지 않았습니다.

저는 이것을 제 활용의 일부로 사용합니다.이것으로 우리는 그림자를 설정할 수 있을 뿐만 아니라 어떤 것에 대해서도 둥근 모서리를 얻을 수 있습니다.UIView또한 선호하는 색상 그림자를 설정할 수 있습니다.일반적으로 검은색을 선호하지만 배경이 흰색이 아닌 경우에는 다른 것을 원할 수도 있습니다.제가 사용하는 것은...

in utils.m
+ (void)roundedLayer:(CALayer *)viewLayer 
              radius:(float)r 
              shadow:(BOOL)s
{
    [viewLayer setMasksToBounds:YES];
    [viewLayer setCornerRadius:r];        
    [viewLayer setBorderColor:[RGB(180, 180, 180) CGColor]];
    [viewLayer setBorderWidth:1.0f];
    if(s)
    {
        [viewLayer setShadowColor:[RGB(0, 0, 0) CGColor]];
        [viewLayer setShadowOffset:CGSizeMake(0, 0)];
        [viewLayer setShadowOpacity:1];
        [viewLayer setShadowRadius:2.0];
    }
    return;
}

이걸 사용하기 위해서 우리는 이것을-[utils roundedLayer:yourview.layer radius:5.0f shadow:YES];

스위프트 3

extension UIView {
    func installShadow() {
        layer.cornerRadius = 2
        layer.masksToBounds = false
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 1)
        layer.shadowOpacity = 0.45
        layer.shadowPath = UIBezierPath(rect: bounds).cgPath
        layer.shadowRadius = 1.0
    }
}

StoryBoard를 사용하고 런타임 속성을 계속 입력하지 않으려면 보기에 대한 확장을 쉽게 만들어 스토리보드에서 사용할 수 있도록 할 수 있습니다.

1단계. 확장자 만들기

extension UIView {

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

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

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

@IBInspectable var maskToBound: Bool {
    get {
        return layer.masksToBounds
    }
    set {
        layer.masksToBounds = newValue
    }
}
}

2단계. 이제 스토리보드에서스토리보드 이미지 이러한 속성을 사용할 수 있습니다.

Swift 4에서 IBDesignable 및 IBInspectable을 사용하여 섀도 스케치

사용 방법

데모

스케치 및 X코드 나란히 표시

섀도 예제

코드

@IBDesignable class ShadowView: UIView {

    @IBInspectable var shadowColor: UIColor? {
        get {
            if let color = layer.shadowColor {
                return UIColor(cgColor: color)
            }
            return nil
        }
        set {
            if let color = newValue {
                layer.shadowColor = color.cgColor
            } else {
                layer.shadowColor = nil
            }
        }
    }

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

    @IBInspectable var shadowOffset: CGPoint {
        get {
            return CGPoint(x: layer.shadowOffset.width, y:layer.shadowOffset.height)
        }
        set {
            layer.shadowOffset = CGSize(width: newValue.x, height: newValue.y)
        }

     }

    @IBInspectable var shadowBlur: CGFloat {
        get {
            return layer.shadowRadius
        }
        set {
            layer.shadowRadius = newValue / 2.0
        }
    }

    @IBInspectable var shadowSpread: CGFloat = 0 {
        didSet {
            if shadowSpread == 0 {
                layer.shadowPath = nil
            } else {
                let dx = -shadowSpread
                let rect = bounds.insetBy(dx: dx, dy: dx)
                layer.shadowPath = UIBezierPath(rect: rect).cgPath
            }
        }
    }
}

산출량

데모 출력

여기에 있는 모든 답변을 시도한 후 이 작업을 수행하는 데 실패한 사용자(나 자신!)에게 속성 검사기에서 하위 보기 클립이 활성화되지 않았는지 확인하십시오.

아래와 같이 섀도 및 코너 반경에 대해 생성된 내 유틸리티 기능을 사용할 수 있습니다.

- (void)addShadowWithRadius:(CGFloat)shadowRadius withShadowOpacity:(CGFloat)shadowOpacity withShadowOffset:(CGSize)shadowOffset withShadowColor:(UIColor *)shadowColor withCornerRadius:(CGFloat)cornerRadius withBorderColor:(UIColor *)borderColor withBorderWidth:(CGFloat)borderWidth forView:(UIView *)view{

    // drop shadow
    [view.layer setShadowRadius:shadowRadius];
    [view.layer setShadowOpacity:shadowOpacity];
    [view.layer setShadowOffset:shadowOffset];
    [view.layer setShadowColor:shadowColor.CGColor];

    // border radius
    [view.layer setCornerRadius:cornerRadius];

    // border
    [view.layer setBorderColor:borderColor.CGColor];
    [view.layer setBorderWidth:borderWidth];
}

그것이 당신에게 도움이 되기를 바랍니다!

스위프트 3

self.paddingView.layer.masksToBounds = false
self.paddingView.layer.shadowOffset = CGSize(width: -15, height: 10)
self.paddingView.layer.shadowRadius = 5
self.paddingView.layer.shadowOpacity = 0.5

모두 잘 대답하지만 한 가지 더 추가하고 싶습니다.

테이블 셀이 있을 때 문제가 발생하면 새 셀 디큐 새 셀의 섀도 불일치가 있으므로 이 경우 섀도 코드를 레이아웃Subviews 메서드에 배치하여 모든 조건에서 올바르게 동작하도록 해야 합니다.

-(void)layoutSubviews{
    [super layoutSubviews];

    [self.contentView setNeedsLayout];
    [self.contentView layoutIfNeeded];
    [VPShadow applyShadowView:self];
}

또는 특정 보기에 대한 ViewControllers에서 섀도 코드를 다음 메소드 안에 배치하여 잘 작동하도록 합니다.

-(void)viewDidLayoutSubviews{
    [super viewDidLayoutSubviews];

    [self.viewShadow layoutIfNeeded];
    [VPShadow applyShadowView:self.viewShadow];
}

좀 더 일반화된 형태의 새로운 개발을 위해 섀도 구현을 수정했습니다.

/*!
 @brief Add shadow to a view.

 @param layer CALayer of the view.

 */
+(void)applyShadowOnView:(CALayer *)layer OffsetX:(CGFloat)x OffsetY:(CGFloat)y blur:(CGFloat)radius opacity:(CGFloat)alpha RoundingCorners:(CGFloat)cornerRadius{
    UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:layer.bounds cornerRadius:cornerRadius];
    layer.masksToBounds = NO;
    layer.shadowColor = [UIColor blackColor].CGColor;
    layer.shadowOffset = CGSizeMake(x,y);// shadow x and y
    layer.shadowOpacity = alpha;
    layer.shadowRadius = radius;// blur effect
    layer.shadowPath = shadowPath.CGPath;
}

동료 사마리아인들을 위해, 사마린.i.OS/C# 버전의 답변은 다음과 같습니다.

public override void DrawRect(CGRect area, UIViewPrintFormatter formatter)
{
    CGContext currentContext = UIGraphics.GetCurrentContext();
    currentContext.SaveState();
    currentContext.SetShadow(new CGSize(-15, 20), 5);
    base.DrawRect(area, formatter);
    currentContext.RestoreState();                
}

주요 차이점은 당신이 다음의 인스턴스를 획득한다는 것입니다.CGContext사용자가 직접 적절한 방법을 호출할 수 있습니다.

이것을 사용할 수 있습니다.Extension그림자를 더하다, 그림자를 더함

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

당신은 그것을 이렇게 부를 수 있습니다.

your_Custom_View.addShadow(offset: CGSize(width: 0, height: 1), color: UIColor.black, radius: 2.0, opacity: 1.0)

언급URL : https://stackoverflow.com/questions/805872/how-do-i-draw-a-shadow-under-a-uiview

반응형