আমার ইউআইভিউতে ড্রপ শেড যুক্ত করার সর্বোত্তম উপায় way


108

আমি একে অপরের উপরে স্তরযুক্ত এমন দৃশ্যে একটি ড্রপ শ্যাডো যুক্ত করার চেষ্টা করছি, অন্য ভিউগুলিতে থাকা সামগ্রীগুলি দেখার জন্য ভিউগুলি ধসে পড়েছে, এই শিরাতে আমি চালিয়ে যেতে চাই view.clipsToBoundsযাতে দর্শনগুলি যখন ভেঙে যায় তখন তাদের বিষয়বস্তুগুলি কেটে যায়।

এটি মনে হয় স্তরগুলিতে একটি ড্রপ ছায়া যুক্ত করা আমার পক্ষে মুশকিল হয়ে পড়েছে যেমন আমি clipsToBoundsছায়াগুলি চালু করি তখন তাও ক্লিপ হয়ে যায়।

আমি হেরফের করার চেষ্টা করছি view.frameএবং view.boundsফ্রেমে একটি ড্রপ ছায়া যুক্ত করার জন্য কিন্তু সীমানাগুলি এটির চারপাশে যথেষ্ট বড় হতে দেবে, তবে এটির সাথে আমার ভাগ্য নেই।

আমি শ্যাডো যুক্ত করতে যে কোডটি ব্যবহার করছি তা এখানে (এটি কেবল clipsToBoundsপ্রদর্শিত হিসাবে বন্ধ হিসাবে কাজ করে )

view.clipsToBounds = NO;
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowOffset = CGSizeMake(0,5);
view.layer.shadowOpacity = 0.5;

শীর্ষে হালকা ধূসর স্তরটিতে ছায়ার স্ক্রিনশট প্রয়োগ করা হচ্ছে। আশা করি clipsToBoundsএটি বন্ধ থাকলে আমার সামগ্রীটি কীভাবে ওভারল্যাপ হবে তা একটি ধারণা দেয় ।

ছায়া অ্যাপ্লিকেশন।

কীভাবে আমি আমার ছায়া যুক্ত করতে পারি UIViewএবং আমার সামগ্রীটি ক্লিপড রাখতে পারি?

সম্পাদনা: কেবলমাত্র যুক্ত করতে চেয়েছিলাম যে আমি ছায়াছবিযুক্ত ব্যাকগ্রাউন্ড চিত্র ব্যবহার করেও প্রায় খেলেছি যা ভাল কাজ করে, তবে আমি এখনও এর জন্য সেরা কোডেড সমাধানটি জানতে চাই।

উত্তর:


280

এটা চেষ্টা কর:

UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:view.bounds];
view.layer.masksToBounds = NO;
view.layer.shadowColor = [UIColor blackColor].CGColor;
view.layer.shadowOffset = CGSizeMake(0.0f, 5.0f);
view.layer.shadowOpacity = 0.5f;
view.layer.shadowPath = shadowPath.CGPath;

প্রথমত : UIBezierPathহিসাবে হিসাবে ব্যবহৃত shadowPathগুরুত্বপূর্ণ। যদি আপনি এটি ব্যবহার না করেন তবে আপনি প্রথমে কোনও পার্থক্য লক্ষ্য করতে পারেন না, তবে উত্সাহী চোখটি ডিভাইসটি ঘোরানোর মতো এবং / বা অনুরূপ ইভেন্টের সময় ঘটে যাওয়া একটি নির্দিষ্ট পিছনে পর্যবেক্ষণ করবে। এটি একটি গুরুত্বপূর্ণ পারফরম্যান্স টুইট।

আপনার সমস্যাটি বিশেষভাবে সম্পর্কিত : গুরুত্বপূর্ণ লাইনটি হ'ল view.layer.masksToBounds = NO। এটি দেখার স্তরের সাবলেয়ারগুলির ক্লিপিং অক্ষম করে যা ভিউয়ের সীমা ছাড়িয়ে আরও প্রসারিত করে।

যারা ভাবছেন তাদের masksToBounds(স্তরের উপর) এবং ভিউর নিজস্ব clipToBoundsসম্পত্তিটির মধ্যে পার্থক্য কী: সত্যিকারের কোনওটি নেই। টগলিংয়ের একটির উপর অন্যটির প্রভাব পড়বে। বিমূর্ততার মাত্র একটি আলাদা স্তর।


সুইফট ২.২:

override func layoutSubviews()
{
    super.layoutSubviews()

    let shadowPath = UIBezierPath(rect: bounds)
    layer.masksToBounds = false
    layer.shadowColor = UIColor.blackColor().CGColor
    layer.shadowOffset = CGSizeMake(0.0, 5.0)
    layer.shadowOpacity = 0.5
    layer.shadowPath = shadowPath.CGPath
}

সুইফট 3:

override func layoutSubviews()
{
    super.layoutSubviews()

    let shadowPath = UIBezierPath(rect: bounds)
    layer.masksToBounds = false
    layer.shadowColor = UIColor.black.cgColor
    layer.shadowOffset = CGSize(width: 0.0, height: 5.0)
    layer.shadowOpacity = 0.5
    layer.shadowPath = shadowPath.cgPath
}

1
ধন্যবাদ, আমি আপনার কোডটি চেষ্টা করেছিলাম এবং তারপরে masksToBounds = NO;আমার আসলটিতে যুক্ত করার চেষ্টা করেছি - উভয় প্রয়াস দিয়েই আমি clipsToBounds = YES;চালিয়েছি - উভয়ই সামগ্রীটি ক্লিপ করতে ব্যর্থ হয়েছিল। আপনার উদাহরণটি> youtu.be/tdpemc_Xdps
ওয়েজ

1
কীভাবে কোনও কোণটি বর্গক্ষেত্রের চেয়ে রেন্ডারিংয়ের চেয়ে বৃত্তাকার কোণাকে আলিঙ্গন করতে কীভাবে ড্রপ ছায়া পাওয়া যায় সে সম্পর্কে কোনও ধারণা?
জন এর্ক

7
@JohnErck এই চেষ্টা: UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds cornerRadius:5.0];। পরীক্ষিত নয় তবে আপনি যে ফলাফলটি চান তা ফলানো উচিত।
pkluz

1
আমি শিখেছি ভিউ অ্যানিমেট করার সময়, ছায়া চলার সময় ধূসর ট্র্যাকগুলি ছেড়ে যায়। ছায়াপথ লাইনগুলি সরানো এটি সমাধান করেছে
ইসহাক

1
@ শু, কারণ দেখার যে কোনও সময়ের আকার পরিবর্তিত হয়, layoutSubviews()বলা হয়। এবং যদি আমরা সেই জায়গায় shadowPathবর্তমান আকারটি প্রতিফলিত করার জন্য সামঞ্জস্য করে ক্ষতিপূরণ না দিয়ে থাকি তবে আমাদের একটি পুনরায় আকার দেওয়া হয়েছে তবে ছায়াটি এখনও পুরাতন (প্রাথমিক) আকারের হবে এবং হয় যেখানে দেখাবে না বা উঁকি দেবে না ।
pkluz

65

সুইফট ২.৩-এ ওয়াসাবির উত্তর:

let shadowPath = UIBezierPath(rect: view.bounds)
view.layer.masksToBounds = false
view.layer.shadowColor = UIColor.blackColor().CGColor
view.layer.shadowOffset = CGSize(width: 0, height: 0.5)
view.layer.shadowOpacity = 0.2
view.layer.shadowPath = shadowPath.CGPath

এবং সুইফ্ট 3/4/5 এ:

let shadowPath = UIBezierPath(rect: view.bounds)
view.layer.masksToBounds = false
view.layer.shadowColor = UIColor.black.cgColor
view.layer.shadowOffset = CGSize(width: 0, height: 0.5)
view.layer.shadowOpacity = 0.2
view.layer.shadowPath = shadowPath.cgPath

আপনি যদি অটোলআউট ব্যবহার করছেন তবে এই কোডটি লেআউটউবুউভিউগুলিতে রাখুন।

SwiftUI এ, এটি অনেক সহজ:

Color.yellow  // or whatever your view
    .shadow(radius: 3)
    .frame(width: 200, height: 100)

11
লক্ষ করার জন্য ধন্যবাদlayoutSubviews
ইসলাম প্র।

1
বা এমনকি viewDidLayoutSubviews () ভালো
ম্যাক্স ম্যাকলিয়ড

1
মেক ভেরিয়েন্টের CGSize(width: 0, height: 0.5)
অলিভার অ্যাটকিনসন

আমি এই কোডটি লেআউটসুবউভিউগুলিতে যুক্ত করব (), এটি এখনও আইবিতে রেন্ডার করে নি। আমার অন্যান্য বিকল্পগুলি বেছে নিতে হবে?
গাধা

ধন্যবাদ। আমি অটো লেআউটটি ব্যবহার করছিলাম এবং আমি আমার নিজের মনে করলাম - ভাল .. view.boundsএতটা স্পষ্টতই তৈরি করা যায় shadowPathনি যা ভিউটির পুনঃস্থাপনের CGRectZeroপরিবর্তে কিছু উল্লেখ করতে পারে না । যাইহোক, এটিকে layoutSubviewsআমার সমস্যার সমাধান করার পরে!
devdc

13

কৌশলটি masksToBoundsআপনার দর্শনের স্তরটির সম্পত্তিটি সঠিকভাবে সংজ্ঞায়িত করছে:

view.layer.masksToBounds = NO;

এবং এটি কাজ করা উচিত।

( উত্স )


13

আপনি ডিজাইন সম্পাদকটিতে এই মানগুলি অ্যাক্সেস করতে ইউআইভিউয়ের জন্য একটি এক্সটেনশন তৈরি করতে পারেন

নকশা সম্পাদক এ ছায়া বিকল্প

extension UIView{

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

    @IBInspectable var shadowColor: UIColor{
        get{
            return UIColor(cgColor: self.layer.shadowColor!)
        }
        set{
            self.layer.shadowColor = newValue.cgColor
        }
    }

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

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

ইন্টারফেস বিল্ডারে সেই এক্সটেনশানটিকে কীভাবে উল্লেখ করবেন
আম্র রাগ

আইবিআই স্পেসটেবল এটিকে ইন্টারফেস বিল্ডারে উপলব্ধ করে
নীতেশ

আমি কি এটি উদ্দেশ্য সিতে অর্জন করতে পারি?
হরিশ পাঠক

2
আপনি যদি রিয়েল-টাইম পূর্বরূপ দেখতে চান (ইন্টারফেস নির্মাতায়), এখানে আপনি এটি সম্পর্কে একটি ভাল নিবন্ধটি পেতে পারেন sp.atomicobject.com/2017/07/18/swift-interface-builder
মেডস্কিল

7

আপনি স্টোরিবোর্ড থেকেও নিজের দৃষ্টিতে ছায়া সেট করতে পারেন

এখানে চিত্র বর্ণনা লিখুন


2

ভিউলিলআউটসুবভিউগুলিতে:

override func viewWillLayoutSubviews() {
    sampleView.layer.masksToBounds =  false
    sampleView.layer.shadowColor = UIColor.darkGrayColor().CGColor;
    sampleView.layer.shadowOffset = CGSizeMake(2.0, 2.0)
    sampleView.layer.shadowOpacity = 1.0
}

ইউআইভিউয়ের সম্প্রসারণ ব্যবহার:

extension UIView {

    func addDropShadowToView(targetView:UIView? ){
        targetView!.layer.masksToBounds =  false
        targetView!.layer.shadowColor = UIColor.darkGrayColor().CGColor;
        targetView!.layer.shadowOffset = CGSizeMake(2.0, 2.0)
        targetView!.layer.shadowOpacity = 1.0
    }
}

ব্যবহার:

sampleView.addDropShadowToView(sampleView)

1
কেবল targetView: UIViewঠুং ঠুং শব্দ প্রয়োগ করুন এবং সরান।
ব্লু বাঁশ

6
কেন ব্যবহার selfকরবেন না ? আমার কাছে অনেক বেশি সুবিধাজনক বলে মনে হচ্ছে।
লিনাসগেফার্থ

3
এটি করার আরও ভাল উপায় হ'ল টার্গেটভিউকে প্যারামিটার হিসাবে সরিয়ে নেওয়া এবং টার্গেটভিউয়ের পরিবর্তে স্ব ব্যবহার করা। এটি অপ্রয়োজনীয়তা দূর করে এবং একজনকে এটির মতো এটির কল করার অনুমতি দেয়: স্যাম্পেলভিউ.অ্যাডড্রপশ্যাডো টুভিউ ()
ম্যাক্সকোডস

ম্যাক্স নেলসনের মন্তব্য দুর্দান্ত। আমার পরামর্শটির if letপরিবর্তে সিনট্যাক্স ব্যবহার করা হচ্ছে!
জনি

0

সুতরাং হ্যাঁ, আপনার পারফরম্যান্সের জন্য শ্যাডোপাথ সম্পত্তি পছন্দ করা উচিত, তবে এটিও: CALayer.ShadowPath এর শিরোনাম ফাইল থেকে From

এই সম্পত্তিটি স্পষ্টভাবে ব্যবহার করে পাথ নির্দিষ্ট করা সাধারণত * রেন্ডারিংয়ের কার্যকারিতা উন্নত করে তোলে, একই পথটি ভাগ করে নেওয়ার ফলে * একাধিক স্তর জুড়ে রেফারেন্স

কম পরিচিত কৌশলটি একাধিক স্তর জুড়ে একই রেফারেন্স ভাগ করে নিচ্ছে। অবশ্যই তাদের একই আকার ব্যবহার করতে হবে, তবে এটি টেবিল / সংগ্রহ ভিউ সেলগুলির সাথে সাধারণ।

আপনি যদি উদাহরণগুলি ভাগ করে নেন তবে কেন তা দ্রুত হয় তা আমি জানি না, আমি অনুমান করছি যে এটি ছায়ার উপস্থাপনকে ক্যাশে করে এবং দর্শনীয় ক্ষেত্রে অন্যান্য দৃষ্টান্তগুলির জন্য এটি পুনরায় ব্যবহার করতে পারি। আমি আরও অবাক হই যদি এটি আরও দ্রুত হয়

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.