Mobile App Dev 2021W: Assignment 2

From Soma-notes
Revision as of 02:49, 13 February 2021 by Soma (talk | contribs) (→‎Questions)

This assignment is still being developed.

Questions

  1. At the bottom of the screen it shows the current rotation of the image in degrees. This rotation information stored in a different format as it was in Tutorial 4's 1601picviewer-1.
    1. What is the difference?
    2. Change the program to store the rotation information the same way 1601picviewer-1 did. Be sure to add no new state variables. (Hint: Look at the documentation for TextField.)

Code

1601picviewer-2.zip

//
//  ContentView.swift
//  1601picviewer-2
//  COMP 1601 Winter 2021, Carleton University
//

import SwiftUI

struct ContentView: View {
    @State private var theImage = "kittens"
    @State private var moved = false
    @State private var magnification: CGFloat = 1
    @State private var angleS = "0"

    func resetState() {
        moved = false
        magnification = 1
        angleS = "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: $magnification,
                        angleS: $angleS)
            HStack{
                Text("D:")
                TextField("", text: $angleS, onCommit: {
                    if Double(angleS) == nil {
                        angleS = "0"
                    }
                })
            }.padding()
        }
    }
}

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 angleS: String
    
    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)
                    .rotationEffect(currentAngle())
                    .gesture(dragging)
                    .gesture(SimultaneousGesture(rotating, magnifying))
                    .onTapGesture(count: 1, perform: tapReset)
        }
    }

    func currentAngle() -> Angle {
        if let a = Double(self.angleS) {
            return Angle(degrees: a)
        } else {
            return Angle(degrees: 0)
        }
    }
    
    func tapReset() {
        self.finalAmount = 1
        self.moved = false
        self.angleS = "0"
    }
        
    var rotating: some Gesture {
        RotationGesture()
            .onChanged { angle in
                self.angleS = String(format: "%.0f", angle.degrees)
            }
    }

    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
            }
    }
}