मैं इस सर्कल को स्क्रीन के किनारों पर ले जाने की कोशिश कर रहा हूं, फिर यह निर्धारित करें कि यह स्क्रीन की सीमा पर है और अलर्ट दिखाएं।

यही मैंने पहले ही कोशिश की है: ऑफसेट() की कोशिश की, अब भाग्य के बिना स्थिति() के साथ खेल रहा हूं। ज्यामिति का उपयोग करने का प्रयास किया रीडर ने मदद नहीं की

मैं माइनस कुछ के मूल्य के लिए हार्ड कोड कर सकता हूं जो काम कर रहा है लेकिन यह जानना चाहता है कि स्क्रीन के किनारों का पता कैसे लगाया जाए और यह भी समझें कि यह तर्क क्यों काम नहीं कर रहा है।

स्क्रीन के किनारों को जानने के लिए मैंने UIScreen.main.boundries का उपयोग करने का भी प्रयास किया

मैं स्विफ्टयूआई के साथ "आरामदायक" पाने के लिए स्विफ्टयूआई अभ्यास कर रहा हूं जो एक वास्तविक दर्द है।

import SwiftUI

struct ContentView: View {
    let buttons1 = ["RESET","UP","COLOR"]
    let buttons2 = ["<","DOWN",">"]
    @State private var colorSelector = 0
    let circleColors:[Color] = [.red,.green,.blue,.black]
    @State private var ballOffset = CGPoint.init(x: 80, y: 80)
    @State private var circleOpacity = 0.5
    @State private var alertActive = false // wall problem 

    var body: some View {

            ZStack{
                Color.init("Grayish")
                VStack{
                    Circle()
                        .fill(circleColors[colorSelector]).opacity(circleOpacity)
                        .position(ballOffset)
                        .frame(width: 160, height: 160)
                }

                VStack(spacing:10){
                    Spacer()

                    Slider(value: $circleOpacity)

                    HStack{
                        ForEach(0..<buttons1.count,id:\.self){ text in
                            Button(action: {
                                switch text{
                                case 0:
                                    colorSelector = 0
                                    ballOffset = .zero

                                case 1:
                                    ballOffset.y -= 3

                                case 2:
                                    if colorSelector == circleColors.count - 1{
                                            colorSelector = 0
                                        }
                                        else {
                                            colorSelector += 1
                                        }
                                default: break
                                }

                            }, label: {
                                Text(buttons1[text])
                                    .foregroundColor(text == 1 ? Color.white:Color.accentColor)

                            })
                            .buttonModifier()
                            .background(RoundedRectangle(cornerRadius: 10).fill(Color.accentColor).opacity(text == 1 ? 1 : 0))

                        }
                    }.padding(.horizontal,5)

                    HStack{
                        ForEach(0..<buttons2.count,id:\.self){text in
                            Button(action:{
                                switch text{
                                case 0:
                                    ballOffset.x -= 3

                                case 1:
                                    ballOffset.y += 3

                                case 2:
                                    ballOffset.x += 3
                                default:break
                                }
                            },
                            label:{
                                Text(buttons2[text])
                                    .foregroundColor(Color.white)
                            })
                            .buttonModifier()
                            .background(RoundedRectangle(cornerRadius: 10).fill(Color.blue))
                        }
                    }.padding([.bottom,.horizontal],5)

                }
                .alert(isPresented: $alertActive, content: {
                    Alert(title: Text("out of bounds"), message: Text("out"), dismissButton: .default(Text("OK")))
                }) // alert not working have to figure out wall problem first
            }.edgesIgnoringSafeArea(.all)

    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct ButtonModifier: ViewModifier{
    func body(content: Content) -> some View {
        content
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 44, idealHeight: 44, maxHeight: 44)
            .padding(.horizontal)
            .foregroundColor(Color.accentColor)
            .background(RoundedRectangle(cornerRadius: 10)
                        .stroke(Color.accentColor))

    }
}

extension View{
    func buttonModifier() -> some View{
        modifier(ButtonModifier())
    }
}
0
Surepic 30 पद 2020, 22:01
आपको उस नेमस्पेस में गेंद के निर्देशांक प्राप्त करने के लिए बाहरी ZStack और GeometryReader पर नामित समन्वय स्थान का उपयोग करने की आवश्यकता है। अगला उपयोगी होना चाहिए stackoverflow.com/a/60495440/12299030
 – 
Asperi
30 पद 2020, 22:13
अलर्ट तभी मौजूद होगा जब आप शो अलर्ट को सही पर टॉगल करेंगे। मुझे आपके कोड में कहीं भी दिखाई नहीं दे रहा है जो शो अलर्ट को टॉगल कर रहा है?
 – 
nicksarno
31 पद 2020, 00:50
अलर्ट काम कर रहा है मैंने इस पर टिप्पणी की और कोड का हिस्सा निकाल लिया जो राज्य को बदलने के लिए जिम्मेदार है। समस्या दीवारों या फ्रेम की सीमाओं के साथ है। अभी तक उस समस्या का समाधान नहीं हो सका है।
 – 
Surepic
31 पद 2020, 01:52
UIScreen.main.bounds को संदर्भित करना मेरे लिए काम कर रहा है। क्षमा करें, मैं थोड़ा भ्रमित हूँ कि समस्या क्या है?
 – 
nicksarno
31 पद 2020, 02:45
समस्या यह है कि मैं बाध्य सीमाओं को हार्डकोड नहीं करना चाहता हूं। अर्थात। चौड़ाई 100 कॉन्स्ट कुछ (cgfloat/cgsize/cgpoint) लेकिन इसे गतिशील बनाना चाहते हैं। जैसे ज्योमेट्रीरीडर ऐसा कर रहा है, वहां कोई स्थिरांक तय नहीं है, कोई भी स्क्रीन काम करेगी। UIScreenbound के साथ फिर से मुझे ऊपरी/निचले/बाएं/दाएं सीमाओं को स्थिर रूप से बांधना होगा, मैं इसे गतिशील रूप से नहीं कर सकता। यदि आप मेरा कोड संकलित करेंगे तो आप देखेंगे कि आप आसानी से स्क्रीन की सीमाओं को पार कर सकते हैं।
 – 
Surepic
31 पद 2020, 03:00

1 उत्तर

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

यहाँ GeometryReader का उपयोग करते हुए एक समाधान दिया गया है, जो गतिशील है और डिवाइस ओरिएंटेशन के साथ बदल जाएगा। यह गेंद को हिलाने से पहले भविष्य की गेंद की स्थिति की जांच करता है और विफलता पर अलर्ट दिखाता है।

struct ContentView: View {
    let buttons1 = ["RESET","UP","COLOR"]
    let buttons2 = ["<","DOWN",">"]
    @State private var colorSelector = 0
    let circleColors:[Color] = [.red,.green,.blue,.black]
    let ballSize = CGSize(width: 160, height: 160)
    @State private var ballOffset: CGSize = .zero
    @State private var circleOpacity = 0.5
    @State private var alertActive = false

    var body: some View {
            ZStack {
                Color.green.opacity(0.4)
                    .edgesIgnoringSafeArea(.all)
                
                Circle()
                    .fill(circleColors[colorSelector])
                    .opacity(circleOpacity)
                    .frame(width: ballSize.width, height: ballSize.height)
                    .offset(ballOffset)

                GeometryReader { geometry in
                    VStack(spacing:10) {
                        Spacer()

                        Slider(value: $circleOpacity)
                        
                        HStack {
                            ForEach(0..<buttons1.count,id:\.self){ text in
                                Button(action: {
                                    switch text{
                                    case 0:
                                        colorSelector = 0
                                        ballOffset = .zero
                                    case 1:
                                        handleMove(incrementY: -3, geometryProxy: geometry)
                                    case 2:
                                        colorSelector = colorSelector == (circleColors.count - 1) ? 0 : colorSelector + 1
                                    default:
                                        break
                                    }

                                }, label: {
                                    Text(buttons1[text])
                                        .foregroundColor(text == 1 ? Color.white:Color.accentColor)
                                })
                                .buttonModifier()
                                .background(RoundedRectangle(cornerRadius: 10).fill(Color.accentColor).opacity(text == 1 ? 1 : 0))

                            }
                        }.padding(.horizontal,5)

                        HStack{
                            ForEach(0..<buttons2.count,id:\.self){text in
                                Button(action:{
                                    switch text{
                                    case 0:
                                        handleMove(incrementX: -3, geometryProxy: geometry)
                                    case 1:
                                        handleMove(incrementY: 3, geometryProxy: geometry)
                                    case 2:
                                        handleMove(incrementX: 3, geometryProxy: geometry)
                                    default:break
                                    }
                                },
                                label:{
                                    Text(buttons2[text])
                                        .foregroundColor(Color.white)
                                })
                                .buttonModifier()
                                .background(RoundedRectangle(cornerRadius: 10).fill(Color.blue))
                            }
                        }.padding([.bottom,.horizontal],5)

                    }
                    .background(Color.orange.opacity(0.5))
                }

                .alert(isPresented: $alertActive, content: {
                    Alert(title: Text("out of bounds"), message: Text("out"), dismissButton: .default(Text("OK")))
                })
            }

    }
    
    
    func handleMove(incrementX: CGFloat = 0, incrementY: CGFloat = 0, geometryProxy: GeometryProxy) {

        let newOffset = CGSize(width: ballOffset.width + incrementX, height: ballOffset.height + incrementY)
        
        let standardXOffset =
            (geometryProxy.size.width) / 2 // width (excluding safe area)
            - (ballSize.width / 2) // subtract 1/2 of ball width (anchor is in the center)
        let maxXOffset = standardXOffset + geometryProxy.safeAreaInsets.trailing // + trailing safe area
        let minXOffset = -standardXOffset - geometryProxy.safeAreaInsets.leading // + leading safe area

        let standardYOffset =
            (geometryProxy.size.height / 2) // height (excluding safe area)
            - (ballSize.height / 2) // subtract 1/2 of ball height (anchor is in the center)
        let maxYOffset = standardYOffset + geometryProxy.safeAreaInsets.bottom // + bottom safe area
        let minYOffset = -standardYOffset - geometryProxy.safeAreaInsets.top // + top safe area
        
        if
            (newOffset.width >= maxXOffset) ||
            (newOffset.width <= minXOffset) ||
            (newOffset.height >= maxYOffset) ||
            (newOffset.height <= minYOffset) {
            alertActive.toggle()
        } else {
            ballOffset = newOffset
        }
    }
    
}
0
nicksarno 31 पद 2020, 03:58
1
मैंने सुझाव के अनुसार ज्यामिति रीडर का उपयोग करके समस्या के अपने कार्यान्वयन को समाप्त कर दिया और यह काम करता है। लेकिन अब आपका कोड पढ़ने के बाद यह और अधिक समझ में आता है जो मैं समझ नहीं पाया।
 – 
Surepic
31 पद 2020, 07:08
मैंने इसे एक नए स्विफ्टयूआई प्रोजेक्ट (एक्सकोड संस्करण 12.5) में कॉपी और पेस्ट किया, लेकिन संदेश मिला "कंपाइलर उचित समय में इस अभिव्यक्ति को टाइप-चेक करने में असमर्थ है, अभिव्यक्ति को अलग-अलग उप-अभिव्यक्तियों में तोड़ने का प्रयास करें" :(
 – 
Mark Highton Ridley
7 जून 2021, 00:42