DEV Community

Lankinen
Lankinen

Posted on

CS193p Notes - Lecture 8: Gestures JSON

UserDefaults

  • Numerous ways to make data persists in iOS:
    • FileManager filesystem
    • CoreData SQL database
    • CloudKit database in the cloud
    • 3rd party options
    • UserDefaults simplest to use but only for lightweight data. Like dictionary.
  • UserDefaults is most often used by making one instance and using it everywhere
    • let defaults = UserDefaults.standard
  • defaults.set(object, forKey: "SomeKey")
    • let i: Int = defaults.integer(forKey: "MyInteger")
    • let b: Data? = defaults.data(forKey: "MyData")
    • let a = array(forKey: "MyArray") this returns Array<Any>
      • To use Any type it's possible to change the type with as

Gestures (8:37)

  • myView.gesture(theGesture)
  • gesture is implemented in func or computer var
var theGesture: some Gesture {
  return TapGesture(count: 2).onEnded { }
}

non-discrete gestures

To see end result

var theGesture: some Gesture {
  DragGesture(...)
    .onEnded { value in ... }
}

To see the value of gesture

@GestureState var myGestureState: MyGestureStateType = <starting value>

Returns <starting value> always when the gesture ends.

var theGesture: some Gesture {
  DragGesture(...)
    .updating($myGestureState) { value, myGestureState, transaction in
      myGestureState = /* usually something related to value */
    }
    .onEnded { value in /* do something */ }
}

myGestureState can be modified only inside .updating

var theGesture: some Gesture {
  DragGesture(...)
    .onChanged { value in
      /* do something with value (which is the state of the fingers) */
    .onEnded { value in /* do something */ }
}
  • .updating is better in most of the cases because you care only the relative change

Demo (22:21)

  • UserDefaults.standard.set(emojiArt.json, forKey: "EmojiArtDocument.Untitled")
  • Codable property means that struct can be encoded and decoded
var json: Data? {
  return try? JSONEncoder().encode(self)
}

init?(json: Data?) {
  if json != nil, let newEmojiArt = try? JSONDecoder().decode(EmojiArt.self, from: json!) {
    self = newEmojiArt
  } else {
    return nil
  }
}

Double tap makes zooms in a way that you can see the full image

...
.gesture(self.doubleTapToZoom(in: geometry.size))

...

private func doubleTapToZoom(in size: CGSize) -> some Gesture {
  TapGesture(count: 2)
    .onEnded {
      withAnimation {
        self.zoomToFit(self.document.backgroundImage, in: size)
      }
    }
}

private func zoomToFit(_ image: UIImage?, in size: CGSize) {
  if let image = image, image.size.width > 0, image.size.height > 0 {
    let hZoom = size.width / image.size.width
    let vZoom = size.height / image.size.height
    self.zoomScale = min(hZoom, vZoom)
  }
}

@RealLankinen

Originally published here

Top comments (0)