From 8d31ab91250b4f70329d12f18fd49764449c382c Mon Sep 17 00:00:00 2001 From: Cora Jacobson Date: Wed, 28 Oct 2020 19:54:24 -0700 Subject: [PATCH 1/5] Started Project --- LambdaTimeline.xcodeproj/project.pbxproj | 4 +++- .../xcshareddata/xcschemes/LambdaTimeline.xcscheme | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/LambdaTimeline.xcodeproj/project.pbxproj b/LambdaTimeline.xcodeproj/project.pbxproj index b2af5414..f8001cfa 100644 --- a/LambdaTimeline.xcodeproj/project.pbxproj +++ b/LambdaTimeline.xcodeproj/project.pbxproj @@ -185,7 +185,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1000; - LastUpgradeCheck = 1000; + LastUpgradeCheck = 1200; ORGANIZATIONNAME = "Lambda School"; TargetAttributes = { 46463777216FDE4B00E7FF73 = { @@ -285,6 +285,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -346,6 +347,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; diff --git a/LambdaTimeline.xcodeproj/xcshareddata/xcschemes/LambdaTimeline.xcscheme b/LambdaTimeline.xcodeproj/xcshareddata/xcschemes/LambdaTimeline.xcscheme index d1c2f96e..8b66f88a 100644 --- a/LambdaTimeline.xcodeproj/xcshareddata/xcschemes/LambdaTimeline.xcscheme +++ b/LambdaTimeline.xcodeproj/xcshareddata/xcschemes/LambdaTimeline.xcscheme @@ -1,6 +1,6 @@ Date: Thu, 29 Oct 2020 16:05:00 -0700 Subject: [PATCH 2/5] Storyboard --- LambdaTimeline/Storyboards/Main.storyboard | 231 +++++++++++++++--- .../ImagePostViewController.swift | 12 +- 2 files changed, 200 insertions(+), 43 deletions(-) diff --git a/LambdaTimeline/Storyboards/Main.storyboard b/LambdaTimeline/Storyboards/Main.storyboard index 9e2d25d6..81e834fd 100644 --- a/LambdaTimeline/Storyboards/Main.storyboard +++ b/LambdaTimeline/Storyboards/Main.storyboard @@ -1,10 +1,11 @@ - - + + - + + @@ -13,9 +14,9 @@ - + - + @@ -24,7 +25,7 @@ - + @@ -108,23 +109,23 @@ - + - + - + - + - + - + + + + + + + + - + + @@ -170,7 +226,6 @@ - @@ -191,6 +246,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -198,7 +352,7 @@ - + @@ -215,35 +369,36 @@ - + - - + - + + @@ -257,7 +412,6 @@ - @@ -273,15 +427,15 @@ - + - + - + - + @@ -290,16 +444,16 @@ - + - + - + - + + + + diff --git a/LambdaTimeline/View Controllers/ImagePostViewController.swift b/LambdaTimeline/View Controllers/ImagePostViewController.swift index 9cffbbbb..18800fae 100644 --- a/LambdaTimeline/View Controllers/ImagePostViewController.swift +++ b/LambdaTimeline/View Controllers/ImagePostViewController.swift @@ -33,12 +33,12 @@ class ImagePostViewController: ShiftableViewController { presentInformationalAlertController(title: "Error", message: "The photo library is unavailable") return } - - let imagePicker = UIImagePickerController() - imagePicker.delegate = self - imagePicker.sourceType = .photoLibrary - - present(imagePicker, animated: true, completion: nil) + DispatchQueue.main.async { + let imagePicker = UIImagePickerController() + imagePicker.delegate = self + imagePicker.sourceType = .photoLibrary + self.present(imagePicker, animated: true, completion: nil) + } } @IBAction func createPost(_ sender: Any) { From 0e22b208f905c7d74b56caa729c0982aca56762a Mon Sep 17 00:00:00 2001 From: Cora Jacobson Date: Thu, 29 Oct 2020 17:31:07 -0700 Subject: [PATCH 3/5] Filters --- LambdaTimeline.xcodeproj/project.pbxproj | 12 +- .../Helpers/Extensions/UIImage+Ratio.swift | 29 ++ LambdaTimeline/Storyboards/Main.storyboard | 72 ++-- .../ImageFilterViewController.swift | 316 ++++++++++++++++++ .../ImagePostViewController.swift | 66 +++- 5 files changed, 462 insertions(+), 33 deletions(-) create mode 100644 LambdaTimeline/View Controllers/ImageFilterViewController.swift diff --git a/LambdaTimeline.xcodeproj/project.pbxproj b/LambdaTimeline.xcodeproj/project.pbxproj index f8001cfa..cf708b98 100644 --- a/LambdaTimeline.xcodeproj/project.pbxproj +++ b/LambdaTimeline.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 1AC9C5CE254B86BD00CDD572 /* ImageFilterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AC9C5CD254B86BD00CDD572 /* ImageFilterViewController.swift */; }; 4646377C216FDE4B00E7FF73 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4646377B216FDE4B00E7FF73 /* AppDelegate.swift */; }; 46463783216FDE4C00E7FF73 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 46463782216FDE4C00E7FF73 /* Assets.xcassets */; }; 46463786216FDE4C00E7FF73 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 46463784216FDE4C00E7FF73 /* LaunchScreen.storyboard */; }; @@ -25,6 +26,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 1AC9C5CD254B86BD00CDD572 /* ImageFilterViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageFilterViewController.swift; sourceTree = ""; }; 46463778216FDE4B00E7FF73 /* LambdaTimeline.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LambdaTimeline.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4646377B216FDE4B00E7FF73 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 46463782216FDE4C00E7FF73 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -128,6 +130,7 @@ 46A0366921700F5100E7FF73 /* PostsCollectionViewController.swift */, 46CFE6F421707D0000E7FF73 /* ImagePostViewController.swift */, 46D571F72173FC2700E7FF73 /* ImagePostDetailTableViewController.swift */, + 1AC9C5CD254B86BD00CDD572 /* ImageFilterViewController.swift */, ); path = "View Controllers"; sourceTree = ""; @@ -232,6 +235,7 @@ files = ( 46A0366D2170158900E7FF73 /* SignInViewController.swift in Sources */, 46CFE6F92170862C00E7FF73 /* ShiftableViewController.swift in Sources */, + 1AC9C5CE254B86BD00CDD572 /* ImageFilterViewController.swift in Sources */, 4646377C216FDE4B00E7FF73 /* AppDelegate.swift in Sources */, 46CFE6F521707D0000E7FF73 /* ImagePostViewController.swift in Sources */, 46463790216FFD1B00E7FF73 /* Post.swift in Sources */, @@ -311,7 +315,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -367,7 +371,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; @@ -384,7 +388,7 @@ CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/LambdaTimeline/Resources/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -403,7 +407,7 @@ CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/LambdaTimeline/Resources/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/LambdaTimeline/Helpers/Extensions/UIImage+Ratio.swift b/LambdaTimeline/Helpers/Extensions/UIImage+Ratio.swift index 79bb32d7..cf844b92 100644 --- a/LambdaTimeline/Helpers/Extensions/UIImage+Ratio.swift +++ b/LambdaTimeline/Helpers/Extensions/UIImage+Ratio.swift @@ -13,3 +13,32 @@ extension UIImage { return size.height / size.width } } + +extension UIImage { + + /// Resize the image to a max dimension from size parameter + func imageByScaling(toSize size: CGSize) -> UIImage? { + guard size.width > 0 && size.height > 0 else { return nil } + + let originalAspectRatio = self.size.width/self.size.height + var correctedSize = size + + if correctedSize.width > correctedSize.width*originalAspectRatio { + correctedSize.width = correctedSize.width*originalAspectRatio + } else { + correctedSize.height = correctedSize.height/originalAspectRatio + } + + return UIGraphicsImageRenderer(size: correctedSize, format: imageRendererFormat).image { context in + draw(in: CGRect(origin: .zero, size: correctedSize)) + } + } + + /// Renders the image if the pixel data was rotated due to orientation of camera + var flattened: UIImage { + if imageOrientation == .up { return self } + return UIGraphicsImageRenderer(size: size, format: imageRendererFormat).image { context in + draw(at: .zero) + } + } +} diff --git a/LambdaTimeline/Storyboards/Main.storyboard b/LambdaTimeline/Storyboards/Main.storyboard index 81e834fd..17631c46 100644 --- a/LambdaTimeline/Storyboards/Main.storyboard +++ b/LambdaTimeline/Storyboards/Main.storyboard @@ -107,7 +107,7 @@ - + @@ -153,9 +153,9 @@ @@ -236,6 +242,9 @@ + + + @@ -246,52 +255,58 @@ - + - + - + - + - + - + - + + + + - + + + + - + + + + @@ -340,10 +361,21 @@ + + + + + + + + + + + - + diff --git a/LambdaTimeline/View Controllers/ImageFilterViewController.swift b/LambdaTimeline/View Controllers/ImageFilterViewController.swift new file mode 100644 index 00000000..524fbd4d --- /dev/null +++ b/LambdaTimeline/View Controllers/ImageFilterViewController.swift @@ -0,0 +1,316 @@ +// +// ImageFilterViewController.swift +// LambdaTimeline +// +// Created by Cora Jacobson on 10/29/20. +// Copyright © 2020 Lambda School. All rights reserved. +// + +import UIKit +import CoreImage +import CoreImage.CIFilterBuiltins + +enum FilterType: String, CaseIterable { + case none = "No Filter" + case hueAdjust = "Hue Adjust" + case colorMonochrome = "Color Monochrome" + case bumpDistortion = "Bump Distortion" + case twirlDistortion = "Twirl Distortion" + case crystallize = "Crystallize" +} + +protocol FilterVCDelegate: AnyObject { + func updateImage(originalImage: UIImage, filteredImage: UIImage?) +} + +class ImageFilterViewController: UIViewController { + + @IBOutlet private var imageView: UIImageView! + @IBOutlet private var pickerView: UIPickerView! + @IBOutlet private var label1: UILabel! + @IBOutlet private var slider1: UISlider! + @IBOutlet private var label2: UILabel! + @IBOutlet private var slider2: UISlider! + @IBOutlet private var label3: UILabel! + @IBOutlet private var slider3: UISlider! + @IBOutlet private var imageHeightConstraint: NSLayoutConstraint! + + var originalImage: UIImage? + var filteredImage: UIImage? + var scaledImage: CIImage? { + didSet { + updateImage() + } + } + + private let filters = FilterType.allCases.map { $0.rawValue } + private var activeFilter: FilterType = .none + private var touchPoint: CGPoint? + private let context = CIContext() + weak var delegate: FilterVCDelegate? + + override func viewDidLoad() { + super.viewDidLoad() + pickerView.delegate = self + pickerView.dataSource = self + setUpView() + } + + @IBAction func slider1Changed(_ sender: UISlider) { + updateImage() + } + + @IBAction func slider2Changed(_ sender: UISlider) { + updateImage() + } + + @IBAction func slider3Changed(_ sender: UISlider) { + updateImage() + } + + @IBAction func applyFilters(_ sender: UIButton) { + if let originImage = originalImage { + self.delegate?.updateImage(originalImage: originImage, filteredImage: filteredImage) + } + dismiss(animated: true, completion: nil) + } + + private func setUpView() { + if let filteredImage = filteredImage { + imageView.image = filteredImage + var scaledSize = imageView.bounds.size + let scale = imageView.contentScaleFactor + scaledSize.width *= scale + scaledSize.height *= scale + + guard let scaledUIImage = filteredImage.imageByScaling(toSize: scaledSize) else { + scaledImage = nil + return + } + scaledImage = CIImage(image: scaledUIImage) + } else if let originalImage = originalImage { + imageView.image = originalImage + var scaledSize = imageView.bounds.size + let scale = imageView.contentScaleFactor + scaledSize.width *= scale + scaledSize.height *= scale + + guard let scaledUIImage = originalImage.imageByScaling(toSize: scaledSize) else { + scaledImage = nil + return + } + scaledImage = CIImage(image: scaledUIImage) + } + imageView.isUserInteractionEnabled = true + label1.isHidden = true + label2.isHidden = true + label3.isHidden = true + slider1.isHidden = true + slider2.isHidden = true + slider3.isHidden = true + } + + private func setImageViewHeight(with aspectRatio: CGFloat) { + imageHeightConstraint.constant = imageView.frame.size.width * aspectRatio + view.layoutSubviews() + } + + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + if let touch = touches.first { + let position = touch.location(in: view) + if imageView.frame.contains(position) { + let xPosition = position.x - imageView.frame.minX + let yPosition = imageView.bounds.height - (position.y - imageView.frame.minY) + touchPoint = CGPoint(x: xPosition, y: yPosition) + updateImage() + } + } + } + + private func updateImage() { + if let scaledImage = scaledImage { + switch activeFilter { + case .hueAdjust: + imageView.image = hueAdjust(byFiltering: scaledImage) + filteredImage = imageView.image + case .colorMonochrome: + imageView.image = colorMonochrome(byFiltering: scaledImage) + filteredImage = imageView.image + case .bumpDistortion: + imageView.image = bumpDistortion(byFiltering: scaledImage) + filteredImage = imageView.image + case .twirlDistortion: + imageView.image = twirlDistortion(byFiltering: scaledImage) + filteredImage = imageView.image + case .crystallize: + imageView.image = crystallize(byFiltering: scaledImage) + filteredImage = imageView.image + default: + imageView.image = originalImage + filteredImage = nil + } + } else { + imageView.image = nil + filteredImage = nil + } + } + + private func noFilterSetUp() { + slider1.isHidden = true + slider2.isHidden = true + slider3.isHidden = true + activeFilter = .none + imageView.image = originalImage + } + + private func hueAdjustSetUp() { + slider1.isHidden = false + slider1.maximumValue = (.pi * 2) + slider1.setValue(.pi, animated: true) + slider2.isHidden = true + slider3.isHidden = true + activeFilter = .hueAdjust + imageView.image = originalImage + updateImage() + } + + private func colorMonochromeSetUp() { + slider1.isHidden = false + slider1.maximumValue = 1 + slider1.setValue(0.75, animated: true) + slider2.isHidden = false + slider2.maximumValue = 1 + slider2.setValue(0, animated: true) + slider3.isHidden = false + slider3.maximumValue = 1 + slider3.setValue(1, animated: true) + activeFilter = .colorMonochrome + imageView.image = originalImage + updateImage() + } + + private func bumpDistortionSetUp() { + slider1.isHidden = false + slider1.maximumValue = 300 + slider1.setValue(150, animated: true) + slider2.isHidden = false + slider2.maximumValue = 1 + slider2.setValue(0.5, animated: true) + slider3.isHidden = true + activeFilter = .bumpDistortion + imageView.image = originalImage + updateImage() + } + + private func twirlDistortionSetUp() { + slider1.isHidden = false + slider1.maximumValue = 200 + slider1.setValue(100, animated: true) + slider2.isHidden = false + slider2.maximumValue = (.pi * 2) + slider2.setValue(.pi, animated: true) + slider3.isHidden = true + activeFilter = .twirlDistortion + imageView.image = originalImage + updateImage() + } + + private func crystallizeSetUp() { + slider1.isHidden = false + slider1.maximumValue = 20 + slider1.setValue(10, animated: true) + slider2.isHidden = true + slider3.isHidden = true + activeFilter = .crystallize + imageView.image = originalImage + updateImage() + } + + private func hueAdjust(byFiltering inputImage: CIImage) -> UIImage? { + let hueAdjustFilter = CIFilter.hueAdjust() + hueAdjustFilter.inputImage = inputImage + hueAdjustFilter.angle = slider1.value + guard let outputImage = hueAdjustFilter.outputImage else { return nil } + guard let renderedCGImage = context.createCGImage(outputImage, from: inputImage.extent) else { return nil } + return UIImage(cgImage: renderedCGImage) + } + + private func colorMonochrome(byFiltering inputImage: CIImage) -> UIImage? { + let colorMonochromeFilter = CIFilter.colorMonochrome() + colorMonochromeFilter.inputImage = inputImage + colorMonochromeFilter.color = CIColor(red: CGFloat(slider1.value), green: CGFloat(slider2.value), blue: CGFloat(slider3.value), alpha: 1) + guard let outputImage = colorMonochromeFilter.outputImage else { return nil } + guard let renderedCGImage = context.createCGImage(outputImage, from: inputImage.extent) else { return nil } + return UIImage(cgImage: renderedCGImage) + } + + private func bumpDistortion(byFiltering inputImage: CIImage) -> UIImage? { + let bumpDistortionFilter = CIFilter.bumpDistortion() + bumpDistortionFilter.inputImage = inputImage + bumpDistortionFilter.radius = slider1.value + bumpDistortionFilter.scale = slider2.value + let centerWidth = CGFloat(inputImage.extent.width / 2) + let centerHeight = CGFloat(inputImage.extent.height / 2) + let center = CGPoint(x: centerWidth, y: centerHeight) + bumpDistortionFilter.center = touchPoint ?? center + guard let outputImage = bumpDistortionFilter.outputImage else { return nil } + guard let renderedCGImage = context.createCGImage(outputImage, from: inputImage.extent) else { return nil } + return UIImage(cgImage: renderedCGImage) + } + + private func twirlDistortion(byFiltering inputImage: CIImage) -> UIImage? { + let twirlDistortionFilter = CIFilter.twirlDistortion() + twirlDistortionFilter.inputImage = inputImage + twirlDistortionFilter.radius = slider1.value + twirlDistortionFilter.angle = slider2.value + let centerWidth = CGFloat(inputImage.extent.width / 2) + let centerHeight = CGFloat(inputImage.extent.height / 2) + let center = CGPoint(x: centerWidth, y: centerHeight) + twirlDistortionFilter.center = touchPoint ?? center + guard let outputImage = twirlDistortionFilter.outputImage else { return nil } + guard let renderedCGImage = context.createCGImage(outputImage, from: inputImage.extent) else { return nil } + return UIImage(cgImage: renderedCGImage) + } + + private func crystallize(byFiltering inputImage: CIImage) -> UIImage? { + let crystallizeFilter = CIFilter.crystallize() + crystallizeFilter.inputImage = inputImage + crystallizeFilter.radius = slider1.value + guard let outputImage = crystallizeFilter.outputImage else { return nil } + guard let renderedCGImage = context.createCGImage(outputImage, from: inputImage.extent) else { return nil } + return UIImage(cgImage: renderedCGImage) + } + +} + +extension ImageFilterViewController: UIPickerViewDelegate, UIPickerViewDataSource { + func numberOfComponents(in pickerView: UIPickerView) -> Int { + 1 + } + + func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + filters.count + } + + func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { + filters[row] + } + + func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { + switch row { + case 1: + hueAdjustSetUp() + case 2: + colorMonochromeSetUp() + case 3: + bumpDistortionSetUp() + case 4: + twirlDistortionSetUp() + case 5: + crystallizeSetUp() + default: + noFilterSetUp() + } + } + +} diff --git a/LambdaTimeline/View Controllers/ImagePostViewController.swift b/LambdaTimeline/View Controllers/ImagePostViewController.swift index 18800fae..6858a9ab 100644 --- a/LambdaTimeline/View Controllers/ImagePostViewController.swift +++ b/LambdaTimeline/View Controllers/ImagePostViewController.swift @@ -11,20 +11,40 @@ import Photos class ImagePostViewController: ShiftableViewController { - @IBOutlet weak var imageView: UIImageView! - @IBOutlet weak var titleTextField: UITextField! - @IBOutlet weak var chooseImageButton: UIButton! - @IBOutlet weak var imageHeightConstraint: NSLayoutConstraint! - @IBOutlet weak var postButton: UIBarButtonItem! + @IBOutlet private var imageView: UIImageView! + @IBOutlet private var titleTextField: UITextField! + @IBOutlet private var chooseImageButton: UIButton! + @IBOutlet private var imageHeightConstraint: NSLayoutConstraint! + @IBOutlet private var postButton: UIBarButtonItem! + + @IBOutlet private var filterImageButton: UIButton! + @IBOutlet private var filterAgainButton: UIButton! + @IBOutlet private var clearFiltersButton: UIButton! var postController: PostController! var post: Post? var imageData: Data? + var originalImage: UIImage? { + didSet { + filterImageButton.isHidden = false + } + } + var filteredImage: UIImage? { + didSet { + self.filterImageButton.isHidden = true + self.filterAgainButton.isHidden = false + self.clearFiltersButton.isHidden = false + self.imageView.image = self.filteredImage + } + } + override func viewDidLoad() { super.viewDidLoad() - setImageViewHeight(with: 1.0) + filterImageButton.isHidden = true + filterAgainButton.isHidden = true + clearFiltersButton.isHidden = true } private func presentImagePickerController() { @@ -86,8 +106,29 @@ class ImagePostViewController: ShiftableViewController { presentImagePickerController() } - @IBAction func addFilter(_ sender: Any) { - + @IBAction func filterImage(_ sender: UIButton) { + let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) + let filterVC = storyBoard.instantiateViewController(withIdentifier: "ImageFilterViewController") as! ImageFilterViewController + filterVC.originalImage = originalImage + filterVC.delegate = self + self.present(filterVC, animated: true, completion: nil) + } + + @IBAction func filterAgain(_ sender: UIButton) { + let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) + let filterVC = storyBoard.instantiateViewController(withIdentifier: "ImageFilterViewController") as! ImageFilterViewController + filterVC.originalImage = originalImage + filterVC.filteredImage = filteredImage + filterVC.delegate = self + self.present(filterVC, animated: true, completion: nil) + } + + @IBAction func clearFilters(_ sender: UIButton) { + filteredImage = nil + imageView.image = originalImage + filterImageButton.isHidden = false + filterAgainButton.isHidden = true + clearFiltersButton.isHidden = true } func setImageViewHeight(with aspectRatio: CGFloat) { @@ -109,7 +150,7 @@ extension ImagePostViewController: UIImagePickerControllerDelegate, UINavigation guard let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else { return } imageView.image = image - + originalImage = image setImageViewHeight(with: image.ratio) } @@ -117,3 +158,10 @@ extension ImagePostViewController: UIImagePickerControllerDelegate, UINavigation picker.dismiss(animated: true, completion: nil) } } + +extension ImagePostViewController: FilterVCDelegate { + func updateImage(originalImage: UIImage, filteredImage: UIImage?) { + self.originalImage = originalImage + self.filteredImage = filteredImage + } +} From 3767ed8245451a6fc88e42aed8a3a55470d24f44 Mon Sep 17 00:00:00 2001 From: Cora Jacobson Date: Thu, 29 Oct 2020 17:36:11 -0700 Subject: [PATCH 4/5] Bug Fix - CommentCell --- LambdaTimeline/Storyboards/Main.storyboard | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LambdaTimeline/Storyboards/Main.storyboard b/LambdaTimeline/Storyboards/Main.storyboard index 17631c46..4e1199c4 100644 --- a/LambdaTimeline/Storyboards/Main.storyboard +++ b/LambdaTimeline/Storyboards/Main.storyboard @@ -506,7 +506,7 @@ - + From a86af4cc28c65a9b4b56063c8e6856e5769fd1bc Mon Sep 17 00:00:00 2001 From: Cora Jacobson Date: Thu, 29 Oct 2020 18:02:15 -0700 Subject: [PATCH 5/5] Bug Fix - imageView in FilterVC --- .../ImageFilterViewController.swift | 43 +++++++++++++++---- .../ImagePostViewController.swift | 1 + 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/LambdaTimeline/View Controllers/ImageFilterViewController.swift b/LambdaTimeline/View Controllers/ImageFilterViewController.swift index 524fbd4d..d50a166d 100644 --- a/LambdaTimeline/View Controllers/ImageFilterViewController.swift +++ b/LambdaTimeline/View Controllers/ImageFilterViewController.swift @@ -146,8 +146,11 @@ class ImageFilterViewController: UIViewController { imageView.image = crystallize(byFiltering: scaledImage) filteredImage = imageView.image default: - imageView.image = originalImage - filteredImage = nil + if let filteredImage = filteredImage { + imageView.image = filteredImage + } else { + imageView.image = originalImage + } } } else { imageView.image = nil @@ -160,7 +163,11 @@ class ImageFilterViewController: UIViewController { slider2.isHidden = true slider3.isHidden = true activeFilter = .none - imageView.image = originalImage + if let filteredImage = filteredImage { + imageView.image = filteredImage + } else { + imageView.image = originalImage + } } private func hueAdjustSetUp() { @@ -170,7 +177,11 @@ class ImageFilterViewController: UIViewController { slider2.isHidden = true slider3.isHidden = true activeFilter = .hueAdjust - imageView.image = originalImage + if let filteredImage = filteredImage { + imageView.image = filteredImage + } else { + imageView.image = originalImage + } updateImage() } @@ -185,7 +196,11 @@ class ImageFilterViewController: UIViewController { slider3.maximumValue = 1 slider3.setValue(1, animated: true) activeFilter = .colorMonochrome - imageView.image = originalImage + if let filteredImage = filteredImage { + imageView.image = filteredImage + } else { + imageView.image = originalImage + } updateImage() } @@ -198,7 +213,11 @@ class ImageFilterViewController: UIViewController { slider2.setValue(0.5, animated: true) slider3.isHidden = true activeFilter = .bumpDistortion - imageView.image = originalImage + if let filteredImage = filteredImage { + imageView.image = filteredImage + } else { + imageView.image = originalImage + } updateImage() } @@ -211,7 +230,11 @@ class ImageFilterViewController: UIViewController { slider2.setValue(.pi, animated: true) slider3.isHidden = true activeFilter = .twirlDistortion - imageView.image = originalImage + if let filteredImage = filteredImage { + imageView.image = filteredImage + } else { + imageView.image = originalImage + } updateImage() } @@ -222,7 +245,11 @@ class ImageFilterViewController: UIViewController { slider2.isHidden = true slider3.isHidden = true activeFilter = .crystallize - imageView.image = originalImage + if let filteredImage = filteredImage { + imageView.image = filteredImage + } else { + imageView.image = originalImage + } updateImage() } diff --git a/LambdaTimeline/View Controllers/ImagePostViewController.swift b/LambdaTimeline/View Controllers/ImagePostViewController.swift index 6858a9ab..9e8899a2 100644 --- a/LambdaTimeline/View Controllers/ImagePostViewController.swift +++ b/LambdaTimeline/View Controllers/ImagePostViewController.swift @@ -110,6 +110,7 @@ class ImagePostViewController: ShiftableViewController { let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) let filterVC = storyBoard.instantiateViewController(withIdentifier: "ImageFilterViewController") as! ImageFilterViewController filterVC.originalImage = originalImage + filterVC.filteredImage = nil filterVC.delegate = self self.present(filterVC, animated: true, completion: nil) }