Adds ability to create notes and a pager to switch

main
Laurent 3 years ago
parent 514794f91d
commit e73305ba59
  1. 4
      Notes.xcodeproj/project.pbxproj
  2. 2
      Notes/AppDelegate.swift
  3. 19
      Notes/Base.lproj/Main.storyboard
  4. 6
      Notes/Model/Note+CoreDataProperties.swift
  5. 31
      Notes/NoteViewController.swift
  6. 121
      Notes/NotesPageViewController.swift
  7. 2
      Notes/ViewController.swift

@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
C4B45E8928FC348900AC6DAF /* NotesPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B45E8828FC348900AC6DAF /* NotesPageViewController.swift */; };
C4EEE41F28DB33D8003DDC24 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE41E28DB33D8003DDC24 /* AppDelegate.swift */; };
C4EEE42128DB33D8003DDC24 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE42028DB33D8003DDC24 /* SceneDelegate.swift */; };
C4EEE42328DB33D8003DDC24 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EEE42228DB33D8003DDC24 /* ViewController.swift */; };
@ -46,6 +47,7 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
C4B45E8828FC348900AC6DAF /* NotesPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesPageViewController.swift; sourceTree = "<group>"; };
C4EEE41B28DB33D8003DDC24 /* Notes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Notes.app; sourceTree = BUILT_PRODUCTS_DIR; };
C4EEE41E28DB33D8003DDC24 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
C4EEE42028DB33D8003DDC24 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
@ -127,6 +129,7 @@
C4EEE42028DB33D8003DDC24 /* SceneDelegate.swift */,
C4EEE42228DB33D8003DDC24 /* ViewController.swift */,
C4EEE45128DB3422003DDC24 /* NoteViewController.swift */,
C4B45E8828FC348900AC6DAF /* NotesPageViewController.swift */,
C4EEE45228DB3423003DDC24 /* UIViewController+Extensions.swift */,
C4EEE46B28DB379B003DDC24 /* Storage */,
C4EEE46228DB3714003DDC24 /* Model */,
@ -321,6 +324,7 @@
C4EEE42328DB33D8003DDC24 /* ViewController.swift in Sources */,
C4EEE46928DB3790003DDC24 /* FileStorage.swift in Sources */,
C4EEE41F28DB33D8003DDC24 /* AppDelegate.swift in Sources */,
C4B45E8928FC348900AC6DAF /* NotesPageViewController.swift in Sources */,
C4EEE42128DB33D8003DDC24 /* SceneDelegate.swift in Sources */,
C4EEE45328DB3423003DDC24 /* NoteViewController.swift in Sources */,
C4EEE46728DB3790003DDC24 /* FileOperator.swift in Sources */,

@ -70,7 +70,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}
})
// container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
// container.viewContext.automaticallyMergesChangesFromParent = true
return container

@ -2,7 +2,6 @@
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="TxU-Fl-tNx">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
@ -18,12 +17,22 @@
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="NKc-C6-bTZ" kind="relationship" relationship="rootViewController" id="08b-m4-FZS"/>
<segue destination="bLT-f5-baA" kind="relationship" relationship="rootViewController" id="zSe-W8-vnK"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="It9-d6-eH5" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="939" y="82"/>
<point key="canvasLocation" x="810" y="-664"/>
</scene>
<!--Notes Page View Controller-->
<scene sceneID="mCo-Xm-AqT">
<objects>
<pageViewController autoresizesArchivedViewToFullSize="NO" transitionStyle="scroll" navigationOrientation="horizontal" spineLocation="none" id="bLT-f5-baA" customClass="NotesPageViewController" customModule="Notes" customModuleProvider="target" sceneMemberID="viewController">
<navigationItem key="navigationItem" id="1nB-b5-m4A"/>
</pageViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="XzJ-cd-L4C" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1594" y="-664"/>
</scene>
<!--Note View Controller-->
<scene sceneID="3me-1s-GmT">
@ -34,7 +43,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="zPN-eq-BkD">
<rect key="frame" x="8" y="100" width="398" height="754"/>
<rect key="frame" x="8" y="56" width="398" height="798"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<color key="textColor" systemColor="labelColor"/>
<fontDescription key="fontDescription" name="DINAlternate-Bold" family="DIN Alternate" pointSize="14"/>
@ -58,7 +67,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="BQh-DG-myD" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1736" y="82"/>
<point key="canvasLocation" x="2291" y="-664"/>
</scene>
</scenes>
<resources>

@ -20,6 +20,12 @@ extension Note {
@NSManaged public var title: String?
@NSManaged public var lastEditDate: Date?
static func fetchByDate() throws -> [Note] {
let request = Note.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(key: "lastEditDate", ascending: false)]
return try AppDelegate.viewContext.fetch(request)
}
}
extension Note : Identifiable {

@ -11,6 +11,8 @@ import CoreData
class NoteViewController : UIViewController, UITextViewDelegate {
var index = 0
var note: Note? = nil
@IBOutlet weak var textView: UITextView!
@ -24,11 +26,7 @@ class NoteViewController : UIViewController, UITextViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let shareButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(shareHandler))
let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addHandler))
self.navigationItem.rightBarButtonItems = [addButton, shareButton]
self._loadLastNote()
self.textView.text = self.note?.content
self.textView.font = UIFont.systemFont(ofSize: 18.0, weight: .regular)
self.textView.delegate = self
@ -38,8 +36,6 @@ class NoteViewController : UIViewController, UITextViewDelegate {
/// Store notifications
print("REGISTER")
NotificationCenter.default.addObserver(self, selector: #selector(self._storeRemoteChange(notification:)), name: NSPersistentCloudKitContainer.eventChangedNotification, object: nil)
/// Keyboard notifications
@ -60,6 +56,10 @@ class NoteViewController : UIViewController, UITextViewDelegate {
}
func loadText() {
self.textView.text = self.note?.content
}
fileprivate func _loadLastNote() {
let request = Note.fetchRequest()
@ -71,7 +71,6 @@ class NoteViewController : UIViewController, UITextViewDelegate {
print("notes in store : \(notes.count)")
self.note = notes.first
self.textView.text = self.note?.content
} catch {
print("Fetch error = \(error)")
}
@ -81,7 +80,7 @@ class NoteViewController : UIViewController, UITextViewDelegate {
@objc fileprivate func _storeRemoteChange(notification: Notification) {
print("_storeRemoteChange...")
DispatchQueue.main.async {
self._loadLastNote()
// self._loadLastNote()
}
}
@ -149,20 +148,6 @@ class NoteViewController : UIViewController, UITextViewDelegate {
}
// MARK: - Business
@objc func shareHandler() {
guard let text = self.textView.text else {
return
}
let activityViewController = UIActivityViewController(activityItems: [text], applicationActivities: nil)
self.present(activityViewController, animated: true)
}
@objc func addHandler() {
}
deinit {
NotificationCenter.default.removeObserver(self)

@ -0,0 +1,121 @@
//
// NotesPageViewController.swift
// Notes
//
// Created by Laurent Morvillier on 16/10/2022.
//
import Foundation
import UIKit
class NotesPageViewController : UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
fileprivate var _notes: [Note] = []
override func viewDidLoad() {
super.viewDidLoad()
self._loadNotes()
let shareButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(shareHandler))
let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addHandler))
self.navigationItem.rightBarButtonItems = [addButton, shareButton]
self.dataSource = self
self.delegate = self
if let note = self._notes.last {
let vc = self.viewController(note: note, index: self._notes.count - 1)
self.setViewControllers([vc], direction: .forward, animated: false)
}
}
fileprivate func _displayNote(note: Note) {
if let index = self._notes.firstIndex(of: note) {
let vc = self.viewController(note: note, index: index)
self.setViewControllers([vc], direction: .forward, animated: false)
} else {
print("note not found")
}
}
fileprivate func viewController(note: Note, index: Int) -> NoteViewController {
if let vc = self.storyboard?.instantiateViewController(withIdentifier: "note") as? NoteViewController {
vc.note = note
vc.index = index
return vc
} else {
fatalError("error with storyboard")
}
}
fileprivate func _loadNotes() {
do {
self._notes = try Note.fetchByDate()
if self._notes.isEmpty {
self._createNote()
self._loadNotes()
}
} catch {
print("error = \(error)")
}
}
// MARK: - UIPageViewControllerDataSource
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let vc = viewController as? NoteViewController else {
return nil
}
let previousIndex = vc.index - 1
if previousIndex < 0 {
return nil
}
let note = self._notes[previousIndex]
return self.viewController(note: note, index: previousIndex)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let vc = viewController as? NoteViewController else {
return nil
}
let nextIndex = vc.index + 1
if nextIndex == self._notes.count {
return nil
}
let note = self._notes[nextIndex]
return self.viewController(note: note, index: nextIndex)
}
// MARK: - Business
@objc func shareHandler() {
guard let vc = self.presentedViewController as? NoteViewController, let text = vc.note?.content else {
return
}
let activityViewController = UIActivityViewController(activityItems: [text], applicationActivities: nil)
self.present(activityViewController, animated: true)
}
@objc func addHandler() {
self._createNote()
}
fileprivate func _createNote() {
let note = Note(context: AppDelegate.viewContext)
self._loadNotes()
self._displayNote(note: note)
}
}

@ -7,7 +7,7 @@
import UIKit
class ViewController: UIViewController {
class ViewController : UIViewController {
override func viewDidLoad() {
super.viewDidLoad()

Loading…
Cancel
Save