मैं CAShapeLayer का एक गुच्छा बना रहा हूं, इसलिए मुझे यह पता लगाने की आवश्यकता है कि मैं किसको छू रहा हूं इसलिए मैं इसका उपयोग करता हूं

if let sublayers = self.layer.sublayers as? [CAShapeLayer]{ //get all CAShape and stored as an array
            print("loop sublayer")
            for layer in sublayers{ // go through each CAShape
                print("loop layer")
                if let path = layer.path, path.contains(currentPanPoint) { // if there is a path at that point then return, else create a path
                    print("detecting")
                    startPointOfTouchedRuler = detectWhichRuler(layer: layer)
                    if startPointOfTouchedRuler != zeroPoint{
                        //  drawCircle(point: startPointOfTouchedRuler)
                        break
                    }else{
                    }
                }
            }
        }

अब मैं एक UIView जोड़ना चाहता हूं जब भी मैं उन्हें प्रबंधित करने और उन्हें आसान बनाने के लिए CAShapeLayer बनाता हूं, मैं इसका उपयोग CAShapeLayer स्थान पर एक नया Uiview जोड़ने के लिए करता हूं:

  func createUIViewOutSideRuler(startPoint:CGPoint, currentPoint:CGPoint, angle: CGFloat){
        let viewWidth = distanceFromTwoPoints(startPoint, currentPoint)
        print(viewWidth)
        let view = UIView(frame: CGRect(x:currentPoint.x, y: currentPoint.y , width:  viewWidth, height: dotLineSize * 3))
        view.backgroundColor = .orange
        view.transform = CGAffineTransform(rotationAngle: angle);
        
        self.addSubview(view)
    }

नया UIview जोड़े जाने के बाद, जिस लूप को प्राप्त करने के लिए CAShapeLayer बिल्कुल भी सक्रिय नहीं होगा, कमांड लाइन प्रिंट नहीं करती print("loop sublayer")

पी/एस: यह लेबल, बटन आदि पर भी लागू होता है। और अगर मैं print(self.layer.sublayers as? [CAShapeLayer]) एक UIView UIButton जोड़ने के बाद, यह nil लौटाता है


0
bao le 8 अक्टूबर 2020, 10:38

1 उत्तर

सबसे बढ़िया उत्तर

त्वरित स्पष्टीकरण:

जब आप self.layer.sublayers as? [CAShapeLayer] करते हैं, तो आप मान रहे हैं कि सभी self.layer.sublayers CAShapeLayer प्रकार के हैं। लेकिन, क्या आप इसके बारे में निश्चित हैं, आपको यह किसने बताया? अन्य प्रकार के CALayer हैं, और डिफ़ॉल्ट घटक पहले से ही कुछ के साथ आ सकते हैं। इसलिए यह विफल हो रहा है। केवल CAShapeLayer रखने के लिए compactMap() का उपयोग करने का विचार है:

let sublayers = self.layer.sublayers.compactMap { $0 as? [CAShapeLayer] }

विस्तृत विवरण:

if let sublayers = self.layer.sublayers as? [CAShapeLayer] {} else {}

else को इसलिए बुलाया जाता है क्योंकि self.layer.sublayers कार्टेबल नहीं है, यह [CAShapeLayer] नहीं है। हमारे मामले में, वे परतें हैं, इसलिए इसका मतलब है कि सभी उपपरत एक CAShapeLayer नहीं हैं। तो, चलिए केवल CAShapeLayer रखते हैं, और दूसरे के बारे में भूल जाते हैं (CAGradientLayer, CALayer, आदि)। उसके लिए, हम compactMap() का उपयोग कर सकते हैं।

self.layer.sublayers.compactMap { aSublayer in
 
}

बंद करने का तर्क सरल है: सरणी पुनरावृत्त है। प्रत्येक पुनरावृत्ति पर, आइटम को aSublayer कहा जाता है। हम जो चाहते हैं वह करते हैं, और यदि आवश्यक हो तो हम एक परिवर्तित मूल्य, एक इंट इत्यादि लौटाते हैं। यदि हम परिवर्तित मूल्य को नहीं रखना चाहते हैं, तो हम शून्य लौटाते हैं, और फिर इसे छोड़ दिया जाएगा।

चूँकि हम केवल सबलेयर्स रखना चाहते हैं जो CAShapeLayer हैं, हम उन पर एक साधारण कास्ट का उपयोग कर सकते हैं:

if let aSubLayerAsShapeLayer = aSubLayer as? CAShapeLayer {
    return aSubLayerAsShapeLayer
} else { //We won't keep it
    return nil
}

जो के बराबर है

return aSubLayer as? CAShapeLayer

फिर, और अधिक सरलीकरण के साथ (एकल-अभिव्यक्ति क्लोजर से लागू रिटर्न, Shorthand Argument Names, doc), हमें मिलता है:

let sublayers = self.layer.sublayers.compactMap { $0 as? [CAShapeLayer] }

साथ ही, चूंकि यह "निश्चित" है कि एक सरणी है (खाली हो सकती है), यह अब वैकल्पिक नहीं है, हम if let को let में हटा देते हैं।

1
Larme 8 अक्टूबर 2020, 11:39