سؤال

أحاول رسم الظل تحت الحافة السفلية من UIView في الكاكاو تعمل باللمس.أنا أفهم أنني يجب أن تستخدم CGContextSetShadow() رسم الظل ، ولكن الكوارتز 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];
}

لكن هذا لا ينفع معي و أنا عالقة قليلا عن (أ) إلى أين يذهبون المقبل و (ب) إذا كان هناك أي شيء كنت بحاجة إلى القيام به بلدي UIView لجعل هذا العمل ؟

هل كانت مفيدة؟

المحلول

في القانون الحالي الخاص بك ، يمكنك حفظ GState من السياق الحالي ، تكوين رسم الظل ..و إعادته إلى ما كان عليه قبل تكوينه رسم الظل.ثم أخيرا تستدعي الفائقة في تنفيذ 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);
}

نصائح أخرى

وهو إلى حد بعيد أسهل أسلوب هو تعيين بعض طبقة سمات عرض على التهيئة:

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

تحتاج إلى استيراد QuartzCore.

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

نفس الحل لكن فقط أذكركم:يمكنك تحديد الظل مباشرة في القصة المصورة.

مثلا:

enter image description here

يمكنك أن تجرب هذا ....يمكنك أن تلعب مع القيم.على 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 Swift

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

على سبيل المثال مع انتشار

Example with spread

لإنشاء الأساسية الظل

    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

الأساسية الظل سبيل المثال في سويفت 2.0

OUTPUT

بسيطة ونظيفة الحل باستخدام واجهة البناء

إضافة ملف اسمه UIView.سويفت في المشروع الخاص بك (أو فقط لصق هذا في أي ملف) :

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

ثم هذا سوف تكون متاحة في واجهة البناء لكل وجهة نظر في المرافق الفريق > سمات المفتش :

Utilities Panel

يمكنك بسهولة ضبط الظل الآن.

ملاحظات:
- الظل لا تظهر في البكالوريا فقط في وقت التشغيل.
- كما مازن كاسر قال

إلى أولئك الذين فشلوا في الحصول على هذا العمل [...] تأكد من مقطع Subviews (clipsToBounds) عدم تمكين

أنا استخدم هذا كجزء من utils.مع هذا نحن لا يمكن فقط تعيين الظل ولكن أيضا يمكن الحصول على تقريب الزاوية لأي 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
    }
}

إذا كنت ترغب في استخدام القصة المصورة و لن ترغب في الحفاظ على الكتابة في وقت سمات يمكنك بسهولة إنشاء امتداد آراء وجعلها صالحة للاستعمال في القصة المصورة.

الخطوة 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.يمكنك الآن استخدام هذه السمات في القصة المصورةstoryboard image

إلى أولئك الذين فشلوا في الحصول على هذا العمل (مثلي!) بعد محاولة كل الإجابات هنا فقط تأكد مقطع Subviews لم يتم تمكين في صفات المفتش...

سويفت 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

يمكنك استخدام وظيفة الأداة إنشاء الظل دائرة نصف قطرها الزاوية على النحو التالي:

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

نأمل أن تساعدك!!!

كل إجابة كل شيء بشكل جيد ولكن أريد أن أضيف نقطة واحدة

إذا كنت تواجه مشكلة عندما يكون لديك خلايا الجدول أو Deque خلية جديدة هناك عدم تطابق في الظل حتى في هذه الحالة ، تحتاج إلى وضع الظل الخاص بك التعليمات البرمجية في layoutSubviews طريقة لذلك أن تتصرف بشكل جيد في جميع الظروف.

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

الزميل Xamarians ، Xamarin.دائرة الرقابة الداخلية/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 على دعوة مباشرة الأساليب المناسبة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top