Intereting Posts
आईपैड एकल ऐप डिवाइस (या स्टार्टअप लॉक करें)? स्विफ्ट में कोको टच फ्रेमवर्क प्रोजेक्ट वर्जन स्ट्रिंग प्राप्त करें MFMailComposeViewController के लिए वैकल्पिक? ऑब्जेक्ट मानों द्वारा एक NSMutableArray सॉर्ट करें एक JSON सरणी को एक NSArray में कनवर्ट कैसे करें स्टोरीबोर्ड से टैब बार आइकन / टेक्स्ट टिंट रंग बदलें मैं एक स्थानीय मूवी यूआरएल को ठीक से कैसे बनाऊँ? छवि कैशिंग के साथ टेबल दृश्य और "अपडेट करने के लिए खींचें" विकल्प अंतरफलक नियंत्रकों के साथ x86_64 वास्तुकला के लिए डुप्लिकेट प्रतीकों आयनिक आईओएस एप: एक्सकोड यूआईकेट क्रैश ठीक से कैसे पता चलेगा कि जब यूआईएसक्रोलवियस का स्क्रोलिंग बंद हो गया है? सभी कुंजीचेन आइटम को ऐप के लिए सुलभ कैसे हटाना है? क्या मैं किसी ऐसे उपकरण से संबंधित किसी आईओएस डिवाइस पर ऐप का परीक्षण कर सकता हूं जो दुनिया के दूसरे भाग में रहता है? अनुरोध विफल: "AFMultipartFormData" में खराब अनुरोध (400) नेविगेशन छुपाएं जब स्क्रॉलिंग टेबल दृश्य संग्रह में देखेंगे?

UIView परत के sublayers अलग / बेतरतीब ढंग से प्रदर्शित प्रत्येक बार दृश्य दिखाई देता है

मेरे UIView पर एक overlaying gradient प्रभाव बनाने के लिए मेरे पास एक सरल कस्टम कॉलर है यहां कोड है:

class GradientLayer: CALayer { var locations: [CGFloat]? var origin: CGPoint? var radius: CGFloat? var color: CGColor? convenience init(view: UIView, locations: [CGFloat]?, origin: CGPoint?, radius: CGFloat?, color: UIColor?) { self.init() self.locations = locations self.origin = origin self.radius = radius self.color = color?.CGColor self.frame = view.bounds } override func drawInContext(ctx: CGContext) { super.drawInContext(ctx) guard let locations = self.locations else { return } guard let origin = self.origin else { return } guard let radius = self.radius else { return } let colorSpace = CGColorGetColorSpace(color) let colorComponents = CGColorGetComponents(color) let gradient = CGGradientCreateWithColorComponents(colorSpace, colorComponents, locations, locations.count) CGContextDrawRadialGradient(ctx, gradient, origin, CGFloat(0), origin, radius, [.DrawsAfterEndLocation]) } } 

मैं इन परतों को आरंभ और सेट करता हूं:

 override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() let gradient1 = GradientLayer(view: view, locations: [0.0,1.0], origin: CGPoint(x: view.frame.midX, y: view.frame.midY), radius: 100.0, color: UIColor(white: 1.0, alpha: 0.2)) let gradient2 = GradientLayer(view: view, locations: [0.0,1.0], origin: CGPoint(x: view.frame.midX-20, y: view.frame.midY+20), radius: 160.0, color: UIColor(white: 1.0, alpha: 0.2)) let gradient3 = GradientLayer(view: view, locations: [0.0,1.0], origin: CGPoint(x: view.frame.midX+30, y: view.frame.midY-30), radius: 300.0, color: UIColor(white: 1.0, alpha: 0.2)) gradient1.setNeedsDisplay() gradient2.setNeedsDisplay() gradient3.setNeedsDisplay() view.layer.addSublayer(gradient1) view.layer.addSublayer(gradient2) view.layer.addSublayer(gradient3) } 

इस दृश्य को ज्यादातर समय ठीक से प्रदर्शित होने लगता है, लेकिन (प्रतीत होता है) बेतरतीब ढंग से मुझे अलग-अलग संदर्भ मिलेंगे, जैसा कि आप नीचे देखेंगे यहां कुछ उदाहरण दिए गए हैं (सबसे पहला जो मैं चाहता हूं):

यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें

इस खराबी का कारण क्या है? मैं केवल हर बार पहली बार कैसे लोड करता हूं?

Solutions Collecting From Web of "UIView परत के sublayers अलग / बेतरतीब ढंग से प्रदर्शित प्रत्येक बार दृश्य दिखाई देता है"

आपके पास कई समस्याएं हैं

सबसे पहले, आपको स्टैप्स की एक सरणी के रूप में एक ढाल के बारे में सोचना चाहिए, जहां एक स्टॉप के दो भाग हैं: एक रंग और एक स्थान। आपके पास बराबर संख्या में रंग और स्थान होना चाहिए, क्योंकि प्रत्येक स्टॉप में प्रत्येक में से एक है आप इसे देख सकते हैं, उदाहरण के लिए, आप CGGradientCreateWithColorComponents दस्तावेज components तर्क के बारे में CGGradientCreateWithColorComponents :

इस सरणी में आइटम्स की संख्या को count के उत्पाद और रंगीन स्थान में घटकों की संख्या होना चाहिए।

यह एक उत्पाद (गुणन का परिणाम) है क्योंकि आपके पास count बंद हो जाती है और आपको प्रत्येक स्टॉप के लिए रंग घटकों का एक पूरा सेट की आवश्यकता होती है।

आप पर्याप्त रंग घटकों प्रदान नहीं कर रहे हैं आपके GradientLayer कितने स्थान हो सकते हैं (और आप इसे दो दे रहे हैं), लेकिन इसका केवल एक रंग है आप एक रंग के घटकों को प्राप्त कर रहे हैं और गुजर रहा है कि घटक के रूप में CGGradientCreateWithColorComponents , लेकिन सरणी बहुत छोटी है। स्विफ्ट इस त्रुटि-नोटिस को नहीं पकड़ता है कि आपके colorComponents का प्रकार colorComponents UnsafePointer<CGFloat> Unsafe हिस्सा आपको बताता है कि आप खतरनाक क्षेत्र में हैं (आप colorComponents में विकल्प-क्लिक करके colorComponents का प्रकार देख सकते हैं।)

चूंकि आप components लिए एक बड़ी पर्याप्त सरणी प्रदान नहीं कर रहे हैं, इसलिए आईओएस अपने एक रंग के घटकों के बाद मेमोरी में याद किए जाने वाले यादृच्छिक मानों का उपयोग कर रहा है। वे चलने से चलाने के लिए बदल सकते हैं और अक्सर वे नहीं होते जो आप चाहते हैं

वास्तव में, आप भी CGGradientCreateWithColorComponents उपयोग नहीं करना चाहिए। आपको CGGradientCreateWithColors उपयोग करना चाहिए, जो CGColor की एक सरणी लेता है, इसलिए यह केवल उपयोग करने के लिए सरल नहीं है, लेकिन सुरक्षित है क्योंकि यह एक कम UnsafePointer आसपास UnsafePointer

यहाँ GradientLayer जैसा दिखना चाहिए:

 class RadialGradientLayer: CALayer { struct Stop { var location: CGFloat var color: UIColor } var stops: [Stop] { didSet { self.setNeedsDisplay() } } var origin: CGPoint { didSet { self.setNeedsDisplay() } } var radius: CGFloat { didSet { self.setNeedsDisplay() } } init(stops: [Stop], origin: CGPoint, radius: CGFloat) { self.stops = stops self.origin = origin self.radius = radius super.init() needsDisplayOnBoundsChange = true } override init(layer other: AnyObject) { guard let other = other as? RadialGradientLayer else { fatalError() } stops = other.stops origin = other.origin radius = other.radius super.init(layer: other) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func drawInContext(ctx: CGContext) { let locations = stops.map { $0.location } let colors = stops.map { $0.color.CGColor } locations.withUnsafeBufferPointer { pointer in let gradient = CGGradientCreateWithColors(nil, colors, pointer.baseAddress) CGContextDrawRadialGradient(ctx, gradient, origin, 0, origin, radius, [.DrawsAfterEndLocation]) } } } 

अगला समस्या हर बार जब सिस्टम कॉल viewWillLayoutSubviews कॉल करता है, आप अधिक ढाल परतों को जोड़ रहे हैं viewWillLayoutSubviews यह उस समारोह को कई बार कॉल कर सकता है! उदाहरण के लिए, यह आपका कॉल करेगा यदि आपका ऐप इंटरफ़ेस रोटेशन का समर्थन करता है, या यदि कोई कॉल आता है और आईओएस स्थिति बार लम्बे बनाता है (आप हार्डवेयर> टॉगल इन-कॉल स्टेटस बार चुनकर सिम्युलेटर में जांच सकते हैं।)

आपको एक बार में ढाल परतें बनाने की आवश्यकता होती है, जो उन्हें एक संपत्ति में संग्रहीत करते हैं। यदि वे पहले से ही बनाए गए हैं, तो आपको अपने फ़्रेम को अपडेट करने और नई परतें बनाने की आवश्यकता नहीं है:

 class ViewController: UIViewController { private var gradientLayers = [RadialGradientLayer]() override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() if gradientLayers.isEmpty { createGradientLayers() } for layer in gradientLayers { layer.frame = view.bounds } } private func createGradientLayers() { let bounds = view.bounds let mid = CGPointMake(bounds.midX, bounds.midY) typealias Stop = RadialGradientLayer.Stop for (point, radius, color) in [ (mid, 100, UIColor(white:1, alpha:0.2)), (CGPointMake(mid.x - 20, mid.y + 20), 160, UIColor(white:1, alpha:0.2)), (CGPointMake(mid.x + 30, mid.y - 30), 300, UIColor(white:1, alpha:0.2)) ] as [(CGPoint, CGFloat, UIColor)] { let stops: [RadialGradientLayer.Stop] = [ Stop(location: 0, color: color), Stop(location: 1, color: color.colorWithAlphaComponent(0))] let layer = RadialGradientLayer(stops: stops, origin: point, radius: radius) view.layer.addSublayer(layer) gradientLayers.append(layer) } } } 

आपकी समस्या यह है कि आपने जो कोड लिखा है उसे देखने के लिए WillLayoutSubviews फ़ंक्शन को इसे कई बार कहा जाता है जब विचार लोड होता है तो बस एक बार इसे चलाने के लिए एक चेक जोड़ते हैं, फिर भी इसे एक बार चलाने के लिए viewdidlayoutsubviews में कोई चेक जोड़ें