Zoom

Source Code

Zooming the game board is a more complex user interaction. We need to interact with the touch API of the different target platforms.

We implement this in Android first.

private val zoomListener = object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
    override fun onScale(detector: ScaleGestureDetector): Boolean {

        val newCellSize = cellSize * detector.scaleFactor
        val oldCellSize = cellSize

        cellSize = when {
            newCellSize < minCellSize -> minCellSize
            newCellSize > maxCellSize -> maxCellSize
            else -> newCellSize
        }

        val realScaleFactor = cellSize / oldCellSize

        val distX = detector.focusX - offsetX
        val distY = detector.focusY - offsetY

        val corrX = distX - distX * realScaleFactor
        val corrY = distY - distY * realScaleFactor

        offsetX += corrX
        offsetY += corrY

        invalidate()
        return true
    }

}

Then the iOS version.

    @ViewBuilder
    var body: some View {
        if self.board != nil {
            VStack(spacing: 2) {
                ForEach(0..<Int(self.board!.rows)) { rowIdx in
                    HStack(spacing: 2) {
                        ForEach(0..<Int(self.board!.columns)) { columnIdx in
                            self.createCell(board: self.board!, rowIdx: rowIdx, columnIdx: columnIdx)
                        }
                    }
                }
            }
            .gesture(MagnificationGesture()
                .onChanged{value in
                    let delta = value / self.lastScaleValue
                    self.lastScaleValue = value
                    self.scale = self.scale * delta
                }
                .onEnded{value in
                    self.lastScaleValue = 1.0
                }
            )

        }
        else {
            EmptyView()
        }
    }
    

The implementation of the zoom logic for the iOS version is quite distinct from the Android version because both platform handle touch events differently.

Zoom Android

Zoom iOS