Mobile App Dev 2021W: Assignment 2
This assignment is still being developed.
Questions
- [3] 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.)
- [3] currentAngle() (lines 71-77):
- [1] What does currentAngle() do? (Explain what the function does in English.)
- [1] When is it called?
- [1] Replace the call to currentAngle() with an expression using the ?? operator (the "Nil-Coalescing Operator").
Code
//
// 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
}
}
}