2016-11-15 8 views
5

मैं एक परिपत्र चार्ट पर काम कर रहा हूं, और मुझे लक्षित मूल्य पर इंगित करने के लिए हाइलाइट किए गए सर्कल (छाया नहीं) के अंत में छोटा दृश्य जोड़ने की आवश्यकता है। क्या मुझे स्ट्रोक एंड पॉइंट पर आधारित सर्कल (हाइलाइट) सुपर व्यू एक्स, वाई पोजीशन मिल सकता है?कैशपलेयर पर्यवेक्षण की स्थिति कैसे प्राप्त करें?

UIView->Circle (CAShapeLayer और UIBezierPath का उपयोग करके)। Circle स्ट्रोक वैल्यू को समाप्त करने के आधार पर मुझे UIView की स्थिति प्राप्त करने की आवश्यकता है।

इस लिंक (जैसे 23% बिंदीदार रेखा के साथ) http://support.softwarefx.com/media/74456678-5a6a-e211-84a5-0019b9e6b500/large

अग्रिम धन्यवाद देखें! Need to find green end circle position

अद्यतन: मैं alexburtnik कोड की कोशिश की है, वास्तव में उद्देश्य सी में घड़ी के लिहाज से ग्राफ पर काम कर रहा हूँ, लेकिन यह एक समस्या यहाँ नहीं है। मैंने एलेक्सबर्टनिक के रूप में उल्लेख किया, मेरा मानना ​​है कि यह पूरी तरह से विरोधी घड़ी के ग्राफ के लिए काम करता है। क्लॉक वार के लिए हमें कोड में कुछ बदलाव करने की ज़रूरत है, अगर आपको पता है तो कृपया समाधान दें।

CGFloat radiusCircle = (self.frame.size.height * 0.5) - ([_lineWidth floatValue]/2.0f); 
-(void)addTargetViewWithOptions:(CGFloat)progress andRadius:(CGFloat)radius{ 

CGFloat x = radius * (1 + (cos(M_PI * (2 * progress + 0.5)))); 
CGFloat y = radius * (1 - (sin(M_PI * (2 * progress + 0.5)))); 
UIView *targetView = [[UIView alloc]initWithFrame:CGRectMake(x, y, 40, 30)]; 
targetView.backgroundColor = [UIColor greenColor]; 
[self addSubview:targetView];} 

Please check my orignal graph

और मुझे esthepiking के रूप में उल्लेख किया है, यहाँ मैं कोड और स्क्रीनशॉट

-(void)addTargetView{ 

CGFloat endAngle = -90.01f; 
radiusCircle = (self.frame.size.height * 0.5) - ([_lineWidth floatValue]/2.0f); 
endAngleCircle = DEGREES_TO_RADIANS(endAngle);//-1.570971 

// Size for the text 
CGFloat width = 75; 
CGFloat height = 30; 

// Calculate the location of the end of the stroke 
// Cos calculates the x position of the point (in unit coordinates) 
// Sin calculates the y position of the point (in unit coordinates) 
// Then scale this to be on the range [0, 1] to match the view 
CGFloat endX = (cos(endAngleCircle)/2 + 0.5); 
CGFloat endY = (sin(endAngleCircle)/2 + 0.5); 

// Scale the coordinates to match the diameter of the circle 
endX *= radiusCircle * 2; 
endY *= radiusCircle * 2; 

// Translate the coordinates based on the location of the frame 
endX -= self.frame.origin.x; 
endY -= self.frame.origin.y; 

// Vertically align the label 
endY += height; 

// Setup the label 

UIView *targetView = [[UIView alloc]initWithFrame:CGRectMake(endX, endY, width, height)]; 
targetView.backgroundColor = [UIColor redColor]; 
[self addSubview:targetView];} 

Please check this result

+0

कन्वर्टपॉइंट: toView: अपनी मदद के लिए चाल – Alex

उत्तर

5

1. गणित

के एक पल के लिए iOS के बारे में भूल जाते हैं और एक गणित की समस्या को हल करते हैं।

समस्या: किसी दिए गए α के लिए (x; y) बिंदु खोजें।

समाधान: x = cos (α); y = पाप (α)

math

2. प्रतिस्थापन

आपका शुरुआती बिंदु 0 पर त्रिकोणमिति के संदर्भ में नहीं है, बल्कि पर π/2। इसके अलावा अपने चाप कोण प्रगति पैरामीटर द्वारा परिभाषित किया गया है, तो यह इस पर ले आता है:

एक्स = cos (प्रगति * 2 * π + π/2) = -पाप (प्रगति * 2 * π)
y = पाप (प्रगति * 2 * π + π/2) = cos (प्रगति * 2 * π)

3. अब आईओएस पर लौटने करते हैं:

के बाद से आईओएस में मूल शीर्ष में है बाएं कोने में एक वाई अक्ष वापस आती है आपको पिछले समाधान को इस तरह से परिवर्तित करना चाहिए:

एक्स '= 0.5 * (1 + x)
वाई' = 0.5 * (1 - y)

ग्रीन गणितीय निर्देशांक के लिए, नीले है आईओएस प्रणाली है, जो हम करने के लिए बदल समन्वय के लिए :

:

iOS

अब सब कुछ आप क्या करने की जरूरत चौड़ाई और ऊंचाई से परिणाम गुणा करने के लिए है

एक्स '= 0.5 * चौड़ाई * (1 - पाप (प्रगति * 2 * π))
वाई' = 0.5 * ऊंचाई * (1 - cos (प्रगति * 2 * π))

4 । कोड:

func point(progress: Double, radius: CGFloat) -> CGPoint { 
    let x = radius * (1 - CGFloat(sin(progress * 2 * Double.pi)))) 
    let y = radius * (1 - CGFloat(cos(progress * 2 * Double.pi)))) 
    return CGPoint(x: x, y: y) 
} 

संपादित

आप, घड़ी की दिशा के लिए यह स्विच करने के लिए सिर्फ -1 द्वारा कोण गुणा करना चाहते हैं:

012,351,

एक्स = cos (-progress * 2 * π + π/2) = -पाप (-progress * 2 * π) = पाप (प्रगति * 2 * π)
y = पाप (-progress * 2 * π + π/2) = कॉस (प्रगति * 2 * π) = कॉस (प्रगति * 2 * π)

x '= 0.5 * चौड़ाई * (1 + पाप (प्रगति * 2 * π))
वाई '= 0.5 * ऊंचाई * (1 - cos (प्रगति * 2 * π))

func point(progress: Double, radius: CGFloat) -> CGPoint { 
    let x = radius * (1 + CGFloat(sin(progress * 2 * Double.pi)))) 
    let y = radius * (1 - CGFloat(cos(progress * 2 * Double.pi)))) 
    return CGPoint(x: x, y: y) 
} 

आशा इस मदद करता है।

+0

उत्तर के लिए धन्यवाद! असल में उद्देश्य सी में घड़ी के अनुसार ग्राफ पर काम कर रहा हूं लेकिन यह कोई समस्या नहीं है। मैंने आपके जैसा उल्लेख किया है, मुझे विश्वास है कि यह पूरी तरह से घड़ी के अनुसार ग्राफ के लिए काम करता है। क्लॉक वार के लिए हमें कोड में कुछ बदलाव करने की ज़रूरत है, अगर आपको पता है तो कृपया समाधान दें। मैंने उपरोक्त मेरे मूल प्रश्न में अपना कोड और स्क्रीनशॉट जोड़ा है। – Gopik

+0

फिर आपका प्रश्न भ्रामक है क्योंकि स्क्रीनशॉट घड़ी की प्रगति पट्टी की तरह नहीं दिखता है। – alexburtnik

+0

हाँ, यह मेरी गलती थी। उसके लिए खेद है! क्या आपके पास समाधान समाधान भी हो सकता है? – Gopik

2

बिंदु प्राप्त करने के लिए जोड़ा की कोशिश की है, तो आप एक छोटे से करने की आवश्यकता होगी गणित का थोड़ा सा।

जब आप UIBezierPath में एक आर्क को परिभाषित करते हैं, तो आप startAngle और endAngle में पास करते हैं। इस मामले में, मेरा मानना ​​है कि आप स्ट्रोक के अंत के साथ एक और दृश्य को लाइन करना चाहते हैं।

UIBezierPath(arcCenter center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool) 

अब आप साइन और उस endAngle पैरामीटर की कोज्या लेने के लिए की आवश्यकता होगी। अंत कोण की साइन आपको इकाई निर्देशांक में वाई स्थिति प्रदान करेगी, सीमा [-1, 1] पर उर्फ, और अंत कोण के कोसाइन आपको इकाई समन्वय में एक्स स्थिति भी प्रदान करेगी। उन निर्देशांकों को तब चाप के आकार से स्केल किया जा सकता है और समायोजित किया जाता है, इसलिए यह दृश्य से मेल खाता है, फिर स्ट्रोक के अंत की स्थिति प्राप्त करने के लिए दृश्य की स्थिति से स्थानांतरित किया जाता है।

यहां इस प्रभाव के लिए एक उदाहरण का मैदान है। मैंने एक UILabel गठबंधन किया ताकि पाठ अंत बिंदु पर केंद्रित हो। अपने आप को आज़माने के लिए इसे आईओएस खेल के मैदान में पेस्ट करें।

Demonstrating the centered view

import UIKit 
import PlaygroundSupport 

PlaygroundPage.current.needsIndefiniteExecution = true 

// Frame to wrap all of this inside of 
let frame = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300)) 
frame.backgroundColor = .white 

let radius = 100 as CGFloat 

// Outermost gray circle 
let grayCircle = CAShapeLayer() 
grayCircle.frame = frame.frame 
grayCircle.path = UIBezierPath(arcCenter: frame.center, radius: radius, startAngle: 0, endAngle: CGFloat(M_PI * 2), clockwise: true).cgPath 
grayCircle.strokeColor = UIColor.lightGray.cgColor 
grayCircle.lineWidth = 10 
grayCircle.fillColor = UIColor.clear.cgColor 

frame.layer.addSublayer(grayCircle) 

// Ending angle for the arc 
let endAngle = CGFloat(M_PI/5) 

// Inner green arc 
let greenCircle = CAShapeLayer() 
greenCircle.frame = frame.frame 
greenCircle.path = UIBezierPath(arcCenter: frame.center, radius: radius, startAngle: CGFloat(-M_PI_2), endAngle: endAngle, clockwise: false).cgPath 
greenCircle.strokeColor = UIColor.green.cgColor 
greenCircle.lineWidth = 10 
greenCircle.fillColor = UIColor.clear.cgColor 
greenCircle.lineCap = kCALineCapRound 

frame.layer.addSublayer(greenCircle) 

// Size for the text 
let width = 75 as CGFloat 
let height = 30 as CGFloat 

// Calculate the location of the end of the stroke 
// Cos calculates the x position of the point (in unit coordinates) 
// Sin calculates the y position of the point (in unit coordinates) 
// Then scale this to be on the range [0, 1] to match the view 
var endX = (cos(endAngle)/2 + 0.5) 
var endY = (sin(endAngle)/2 + 0.5) 

// Scale the coordinates to match the diameter of the circle 
endX *= radius * 2 
endY *= radius * 2 

// Translate the coordinates based on the location of the frame 
endX -= frame.frame.origin.x 
endY -= frame.frame.origin.y 

// Vertically align the label 
endY += height 

// Setup the label 
let text = UILabel(frame: CGRect(x: endX, y: endY, width: width, height: height)) 
text.text = "Stroke end!" 
text.font = UIFont.systemFont(ofSize: 14) 
frame.addSubview(text) 

PlaygroundPage.current.liveView = frame 
+0

धन्यवाद करना चाहिए। मैंने ऊपर अपना परिणाम जोड़ा है। क्या आप कृपया इसे चेक कर सकते। – Gopik

+0

@ user1591698 ऐसा लगता है कि आपको यह काम मिल गया है, या कम से कम बहुत करीब है। यह संभव है कि आपको अपने उपयोग के मामले के लिए 'endY + = height' से छुटकारा पाना पड़े। – esthepiking

+0

हां! धन्यवाद फिर से :) – Gopik

संबंधित मुद्दे