Thursday, September 11, 2025
HomeiOS Developmentios - Cannot click on and drag and SwiftUI what am I...

ios – Cannot click on and drag and SwiftUI what am I lacking?


I’m attempting to construct a easy sport and having hassle getting the click and monitoring to work and AI has been no use. Can somebody assist me?

`

import SwiftUI
import AVFoundation

struct ContentView: View {
    @StateObject non-public var gameModel = GameModel()
    
    var physique: some View {
        VStack {
            HStack {
                Textual content("Rating: (gameModel.rating)")
                    .font(.headline)
                Spacer()
                HStack {
                    Textual content("Goal:")
                    Circle()
                        .fill(Colour(gameModel.targetColor))
                        .body(width: 20, peak: 20)
                }
                Spacer()
                Button(motion: gameModel.toggleMusic) {
                    Textual content(gameModel.isMusicPlaying ? "Mute" : "Unmute")
                        .padding(5)
                        .background(Colour.blue)
                        .foregroundColor(.white)
                        .cornerRadius(5)
                }
            }
            .padding()
            
            if gameModel.gameOver {
                GameOverView(gameModel: gameModel)
            } else {
                GridView(gameModel: gameModel)
            }
        }
        .onAppear {
            gameModel.initializeGame()
        }
    }
}

struct GridView: View {
    @ObservedObject var gameModel: GameModel
    
    let columns: [GridItem] = Array(repeating: .init(.versatile(), spacing: 10), depend: 4)
    
    var physique: some View {
        LazyVGrid(columns: columns, spacing: 10) {
            ForEach(gameModel.grid.indices, id: .self) { index in
                ColorTile(coloration: gameModel.grid[index].coloration, isSpecial: gameModel.grid[index].coloration == .black)
                    .aspectRatio(1, contentMode: .match)
                    .gesture(
                        DragGesture(minimumDistance: 0)
                            .onChanged { worth in
                                // Log the drag begin
                                print("Drag began/modified on tile (index) at: (worth.location)")
                                gameModel.draggedTileIndex = index // Monitor which tile is being dragged
                            }
                            .onEnded { worth in
                                // Log the drag finish
                                print("Drag ended on tile (index) at: (worth.location)")
                                let course = gameModel.getSwipeDirection(begin: worth.startLocation, finish: worth.location)
                                gameModel.handleSwipe(draggedTileIndex: index, course: course) // Deal with swipe completion
                            }
                    )
                    .id(gameModel.grid[index].id)
            }
        }
        .padding()
        .background(Colour.white)
        .cornerRadius(10)
        .padding()
    }
}

struct ColorTile: View {
    let coloration: Colour
    let isSpecial: Bool
    @State non-public var isDragging = false
    
    var physique: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 12)
                .fill(coloration)
            if isSpecial {
                RoundedRectangle(cornerRadius: 12)
                    .fill(Colour.white.opacity(0.3))
            }
        }
        .scaleEffect(isDragging ? 1.1 : 1.0)
        .animation(.easeInOut(period: 0.2), worth: isDragging)
        .gesture(
            DragGesture(minimumDistance: 0)
                .onChanged { _ in 
                    self.isDragging = true 
                    print("Dragging began")
                }
                .onEnded { _ in 
                    self.isDragging = false 
                    print("Dragging ended")
                }
        )
        .contentShape(Rectangle())
    }
}

struct GameOverView: View {
    @ObservedObject var gameModel: GameModel
    
    var physique: some View {
        VStack {
            Textual content("Recreation Over!")
                .font(.largeTitle)
                .foregroundColor(.white)
            Textual content("Your Rating: (gameModel.rating)")
                .font(.title)
                .foregroundColor(.white)
            Button("Play Once more") {
                gameModel.initializeGame()
            }
            .padding()
            .background(Colour.blue)
            .foregroundColor(.white)
            .cornerRadius(10)
            .padding(.prime)
        }
        .body(maxWidth: .infinity, maxHeight: .infinity)
        .background(Colour.black.opacity(0.8))
    }
}

class GameModel: ObservableObject {
    @Revealed var grid: [Tile] = []
    @Revealed var targetColor: Colour = .clear
    @Revealed var rating: Int = 0
    @Revealed var gameOver: Bool = false
    @Revealed var isMusicPlaying: Bool = false
    
    var draggedTileIndex: Int?
    non-public var audioPlayer: AVAudioPlayer?
    
    non-public let gridSize = 4
    non-public let rows = 6
    non-public let totalTiles: Int
    
    non-public let primaryColors: [Color] = [.red, .blue, .yellow]
    non-public let secondaryColors: [Color] = [.purple, .green, .orange]
    
    init() {
        totalTiles = gridSize * rows
    }
    
    func initializeGame() {
        grid = generateGrid()
        targetColor = generateTargetColor()
        rating = 0
        gameOver = false
    }
    
    non-public func generateGrid() -> [Tile] {
        var newGrid = (0.. Colour {
        let color1 = primaryColors.randomElement()!
        var color2: Colour
        repeat {
            color2 = primaryColors.randomElement()!
        } whereas color1 == color2
        return mixColors(color1: color1, color2: color2) ?? .clear
    }
    
    non-public func mixColors(color1: Colour, color2: Colour) -> Colour? {
        let mixPairs: [Set: Color] = [
            [.red, .blue]: .purple,
            [.red, .yellow]: .orange,
            [.blue, .yellow]: .inexperienced
        ]
        return mixPairs[Set([color1, color2])]
    }
    
    func getSwipeDirection(begin: CGPoint, finish: CGPoint) -> SwipeDirection {
        let deltaX = finish.x - begin.x
        let deltaY = finish.y - begin.y
        
        if abs(deltaX) > abs(deltaY) {
            return deltaX > 0 ? .proper : .left
        } else {
            return deltaY > 0 ? .down : .up
        }
    }
    
    func handleSwipe(draggedTileIndex: Int, course: SwipeDirection) {
        print("Dealing with swipe. Dragged tile index: (draggedTileIndex), Route: (course)")
        
        let targetIndex: Int?
        change course {
        case .up:
            targetIndex = draggedTileIndex - gridSize
        case .down:
            targetIndex = draggedTileIndex + gridSize
        case .left:
            targetIndex = draggedTileIndex - 1
        case .proper:
            targetIndex = draggedTileIndex + 1
        }
        
        guard let droppedOnIndex = targetIndex, droppedOnIndex >= 0, droppedOnIndex < totalTiles else {
            print("Invalid goal index for swipe")
            return
        }
        
        print("Swiped to tile index: (droppedOnIndex)")
        
        let draggedColor = grid[draggedTileIndex].coloration
        let droppedColor = grid[droppedOnIndex].coloration
        
        print("Dragged tile coloration: (draggedColor), Dropped tile coloration: (droppedColor)")
        
        if draggedColor == droppedColor {
            print("Colours match. Eradicating matching tiles.")
            removeMatchingTiles(at: droppedOnIndex, coloration: droppedColor)
        } else if let newColor = mixColors(color1: draggedColor, color2: droppedColor) {
            print("Colours blended. New coloration: (newColor)")
            grid[droppedOnIndex].coloration = newColor
            grid[draggedTileIndex].coloration = getRandomColor()
            playMatchSound()
            
            if newColor == targetColor {
                print("New coloration matches goal coloration. Rating elevated.")
                rating += 5
            }
        } else {
            print("Colours do not match and cannot be blended. No motion taken.")
        }
        
        DispatchQueue.important.async {
            self.objectWillChange.ship()
        }
        
        checkGameOver()
    }
    
    non-public func findTileIndex(at level: CGPoint) -> Int? {
        let gridSize = CGFloat(self.gridSize)
        let tileSize = UIScreen.important.bounds.width / gridSize
        
        let column = Int(level.x / tileSize)
        let row = Int(level.y / tileSize)
        
        print("Contact at ((level.x), (level.y)) translated to grid place: row (row), column (column)")
        
        guard column >= 0, column < self.gridSize, row >= 0, row < rows else {
            print("Contact outdoors grid boundaries")
            return nil
        }
        
        let index = row * self.gridSize + column
        print("Calculated index: (index)")
        return index
    }
    
    non-public func isAdjacent(index1: Int, index2: Int) -> Bool {
        let row1 = index1 / gridSize
        let col1 = index1 % gridSize
        let row2 = index2 / gridSize
        let col2 = index2 % gridSize
        return abs(row1 - row2) + abs(col1 - col2) == 1
    }
    
    non-public func removeMatchingTiles(at index: Int, coloration: Colour) {
        var tilesToRemove = Set()
        var queue = [index]
        
        whereas !queue.isEmpty {
            let present = queue.removeFirst()
            tilesToRemove.insert(present)
            
            let adjacentIndices = [
                current - 1, current + 1, current - gridSize, current + gridSize
            ].filter { $0 >= 0 && $0 < totalTiles && grid[$0].coloration == coloration && !tilesToRemove.accommodates($0) }
            
            queue.append(contentsOf: adjacentIndices)
        }
        
        for i in tilesToRemove {
            grid[i].coloration = getRandomColor()
        }
        
        let factors = tilesToRemove.cut back(0) { $0 + (grid[$1].coloration == targetColor ? tilesToRemove.depend * 5 : 1) }
        rating += factors
        
        playMatchSound()
        if tilesToRemove.depend > 2 {
            playComplexMatchSound()
        }
    }
    
    non-public func getRandomColor() -> Colour {
        let randomValue = Double.random(in: 0...1)
        if rating >= 400 && randomValue < Double(rating) / 4000 {
            return .black
        } else if rating >= 200 && randomValue < Double(rating) / 1000 {
            return secondaryColors.randomElement()!
        } else {
            return primaryColors.randomElement()!
        }
    }
    
    non-public func checkGameOver() {
        for i in 0..= 0 && $0 < totalTiles && grid[$0].coloration != .black }
            for j in adjacentIndices {
                if mixColors(color1: grid[i].coloration, color2: grid[j].coloration) != nil || grid[i].coloration == grid[j].coloration {
                    return
                }
            }
        }
        gameOver = true
    }
    
    func toggleMusic() {
        isMusicPlaying.toggle()
        if isMusicPlaying {
            playBackgroundMusic()
        } else {
            stopBackgroundMusic()
        }
    }
    
    non-public func playMatchSound() {
        // Implement sound enjoying logic
    }
    
    non-public func playComplexMatchSound() {
        // Implement sound enjoying logic
    }
    
    non-public func playBackgroundMusic() {
        // Implement background music enjoying logic
    }
    
    non-public func stopBackgroundMusic() {
        // Implement background music stopping logic
    }
}

enum SwipeDirection {
    case up, down, left, proper
}

struct Tile: Identifiable {
    let id = UUID()
    var coloration: Colour
}

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

I’ve appeared on-line, attempting just a few alternative ways to get the gesture of swiping to work and I can not seem to get it to work. I’ve additionally requested Chad GPT and it does not appear to assist both.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments