Mobile App Dev 2021W: Tutorial 4

From Soma-notes
Revision as of 04:50, 8 February 2021 by Soma (talk | contribs) (Created page with "'''This tutorial is still in development.''' In this tutorial you will be playing with [https://homeostasis.scs.carleton.ca/~soma/mad-2021w/code/1601picviewer-1.zip 1601picvi...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This tutorial is still in development.

In this tutorial you will be playing with 1601picviewer-1, a simple image viewer in Swift. Note that this code has two embedded images in it, so it is a bit bigger than past ones.

Submit your answers by 11:59 PM on Sunday, February 21, 2021 via cuLearn. Please submit a text file following this template. Note that you only need to cite sources that weren't covered in lecture and aren't listed below.

Code

1601picviewer-1.zip

import SwiftUI

struct ContentView: View {
    @State private var theImage = "kittens"
    @State private var moved = false
    @State private var finalAmount: CGFloat = 1
    @State private var angle = Angle(degrees: 0.0)

    func resetState() {
        moved = false
        finalAmount = 1
        angle = Angle(degrees: 0.0)
    }
    
    var body: some View {
        VStack {
            Menu("Animals!") {
                    Button("Kittens", action: {
                        theImage = "kittens"
                        resetState()
                    })
                    Button("Sad Dog", action: {
                        theImage = "sadDog"
                        resetState()
                    })
                }
            ActiveImage(theImage: $theImage, moved: $moved, finalAmount: $finalAmount, angle: $angle)
        }
    }
}

struct ActiveImage: View {
    @State private var position = CGPoint(x: 0, y: 0)
    @State private var currentAmount: CGFloat = 0

    @Binding var theImage: String
    @Binding var moved: Bool
    @Binding var finalAmount: CGFloat
    @Binding var angle: Angle
    
    var body: some View {
        GeometryReader {g in
                Image(theImage)
                    .resizable()
                    .scaledToFit()
                    .position(moved ? position :
                            CGPoint(x: g.size.width / 2, y: g.size.height / 2))
                    .scaleEffect(finalAmount + currentAmount)
                    .gesture(dragging)
                    .gesture(SimultaneousGesture(magnifying, rotating))
                    .rotationEffect(self.angle)
                    .onTapGesture(count: 1, perform: tapReset)
        }
    }

    func tapReset() {
        self.finalAmount = 1
        self.moved = false
        self.angle = Angle(degrees: 0.0)
    }
    
    var rotating: some Gesture {
        RotationGesture()
            .onChanged { angle in
                self.angle = angle
            }
    }

    var magnifying: some Gesture {
        MagnificationGesture().onChanged { amount in
            self.currentAmount = amount - 1
        }
        .onEnded { amount in
            self.finalAmount += self.currentAmount
            self.currentAmount = 0
        }
    }
    
    var dragging: some Gesture {
        DragGesture()
            .onChanged {s in
                self.moved = true
                self.position = s.location
            }
            .onEnded {s in
                self.moved = true
                self.position = s.location
            }
    }
}