diff --git a/CookSmart/CookSmart.xcodeproj/project.pbxproj b/CookSmart/CookSmart.xcodeproj/project.pbxproj index 0d6ab91..d16b3a6 100644 --- a/CookSmart/CookSmart.xcodeproj/project.pbxproj +++ b/CookSmart/CookSmart.xcodeproj/project.pbxproj @@ -7,7 +7,10 @@ objects = { /* Begin PBXBuildFile section */ + 39024F62243174BB0063725D /* CSIngredientsExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39024F61243174BB0063725D /* CSIngredientsExt.swift */; }; 392D8645242FD0FF002064D6 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 392D8644242FD0FF002064D6 /* Colors.swift */; }; + 392D865424304F2D002064D6 /* IngredientListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 392D865324304F2D002064D6 /* IngredientListViewController.swift */; }; + 392D865724306D0D002064D6 /* CSConversionVCExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 392D865624306D0D002064D6 /* CSConversionVCExt.swift */; }; 396E363D2439684E00C2815B /* UnitPickerCenterLineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 396E363C2439684E00C2815B /* UnitPickerCenterLineView.swift */; }; 396E363F24396D5900C2815B /* UnitPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 396E363E24396D5900C2815B /* UnitPickerView.swift */; }; 396E3643243976A000C2815B /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 396E3642243976A000C2815B /* GradientView.swift */; }; @@ -83,7 +86,10 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 39024F61243174BB0063725D /* CSIngredientsExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CSIngredientsExt.swift; sourceTree = ""; }; 392D8644242FD0FF002064D6 /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = ""; }; + 392D865324304F2D002064D6 /* IngredientListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IngredientListViewController.swift; sourceTree = ""; }; + 392D865624306D0D002064D6 /* CSConversionVCExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CSConversionVCExt.swift; sourceTree = ""; }; 396E363C2439684E00C2815B /* UnitPickerCenterLineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitPickerCenterLineView.swift; sourceTree = ""; }; 396E363E24396D5900C2815B /* UnitPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitPickerView.swift; sourceTree = ""; }; 396E3642243976A000C2815B /* GradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = ""; }; @@ -232,6 +238,7 @@ 93D0993B18977D320014DB3E /* Units */, 80592C0318924B010082D4E1 /* CSIngredients.h */, 80592C0418924B010082D4E1 /* CSIngredients.m */, + 39024F61243174BB0063725D /* CSIngredientsExt.swift */, 80592C0618924B0F0082D4E1 /* CSIngredient.h */, 80592C0718924B0F0082D4E1 /* CSIngredient.m */, 80592C091892541D0082D4E1 /* CSIngredientGroup.h */, @@ -271,6 +278,7 @@ 9368096F1891059700655B89 /* CSIngredientListVC.m */, 807C0B6A1BB3DD4D007D2C03 /* CSIngredientListViewCell.h */, 807C0B6B1BB3DD4D007D2C03 /* CSIngredientListViewCell.m */, + 392D865324304F2D002064D6 /* IngredientListViewController.swift */, ); name = "Ingredient List UI"; sourceTree = ""; @@ -332,6 +340,7 @@ 9358BD6B1891CAAA00A99D51 /* CSConversionVC.h */, 9358BD6C1891CAAA00A99D51 /* CSConversionVC.m */, 9358BD6D1891CAAA00A99D51 /* CSConversionVC.xib */, + 392D865624306D0D002064D6 /* CSConversionVCExt.swift */, 8000355C18B3CBF50032BF91 /* Scales */, 80592C0218924AEA0082D4E1 /* Model */, 807C0B681BB3DD04007D2C03 /* Ingredient List UI */, @@ -575,6 +584,8 @@ 774EBD6524426CC2002A59AC /* Double+StringUtils.swift in Sources */, 396E363F24396D5900C2815B /* UnitPickerView.swift in Sources */, 77479AEA242FB9C8000CFB0E /* ScaleTile.swift in Sources */, + 392D865424304F2D002064D6 /* IngredientListViewController.swift in Sources */, + 392D865724306D0D002064D6 /* CSConversionVCExt.swift in Sources */, 774EBD802442EC26002A59AC /* UIView+Constraints.swift in Sources */, 392D8645242FD0FF002064D6 /* Colors.swift in Sources */, 80A614DE18BF3D4100A205BB /* CSGlassView.m in Sources */, @@ -600,6 +611,7 @@ 396E3643243976A000C2815B /* GradientView.swift in Sources */, 396E363D2439684E00C2815B /* UnitPickerCenterLineView.swift in Sources */, 936809701891059700655B89 /* CSIngredientListVC.m in Sources */, + 39024F62243174BB0063725D /* CSIngredientsExt.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/CookSmart/CookSmart/CSConversionVC.m b/CookSmart/CookSmart/CSConversionVC.m index fc28dd8..c5585ce 100644 --- a/CookSmart/CookSmart/CSConversionVC.m +++ b/CookSmart/CookSmart/CSConversionVC.m @@ -15,6 +15,7 @@ #import "CSUnit.h" #import "CSUnitCollection.h" #import "CSScaleVC.h" +#import "cake-Swift.h" #define CHOOSE_UNITS_TEXT @"Choose Units" @@ -153,9 +154,10 @@ - (void)refreshIngredientNameUI - (void)handleIngredientTap:(id)sender { - CSIngredientListVC* ingrListVC = [[CSIngredientListVC alloc] initWithDelegate:self]; - UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:ingrListVC]; - [self presentViewController:nav animated:YES completion:nil]; + [self showIngredientList]; +// CSIngredientListVC* ingrListVC = [[CSIngredientListVC alloc] initWithDelegate:self]; +// UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:ingrListVC]; +// [self presentViewController:nav animated:YES completion:nil]; } - (void)scrollViewDidScroll:(UIScrollView *)scrollView diff --git a/CookSmart/CookSmart/CSConversionVCExt.swift b/CookSmart/CookSmart/CSConversionVCExt.swift new file mode 100644 index 0000000..53ff50b --- /dev/null +++ b/CookSmart/CookSmart/CSConversionVCExt.swift @@ -0,0 +1,17 @@ +// +// CSConversionVCExt.swift +// cake +// +// Created by Alex King on 3/28/20. +// Copyright © 2020 Olga Galchenko. All rights reserved. +// + +import Foundation + +extension CSConversionVC { + @objc + func showIngredientList() { + let ingredientListViewController = IngredientListViewController() + present(ingredientListViewController, animated: true, completion: nil) + } +} diff --git a/CookSmart/CookSmart/CSIngredientListVC.m b/CookSmart/CookSmart/CSIngredientListVC.m index 9a644bd..481511c 100644 --- a/CookSmart/CookSmart/CSIngredientListVC.m +++ b/CookSmart/CookSmart/CSIngredientListVC.m @@ -171,52 +171,6 @@ - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *) ((numGroups > 1) || (numGroups == 1 && [[[CSIngredients sharedInstance] ingredientGroupAtIndex:0] countOfIngredients] > 1)); } -- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath -{ - if (editingStyle == UITableViewCellEditingStyleDelete) - { - CSIngredients *ingredients = [self ingredientsToSupplyData]; - CSRecentsIngredientGroup *beforeChangeRecents = ingredients.recents; - CSIngredientGroup *ingredientGroup = [ingredients ingredientGroupAtIndex:indexPath.section]; - CSIngredient *ingredientToDelete = [ingredientGroup ingredientAtIndex:indexPath.row]; - BOOL needToDeleteFromRecents = beforeChangeRecents && [beforeChangeRecents indexOfIngredient:ingredientToDelete] != NSNotFound; - BOOL deleteSuccess = [ingredients deleteIngredientAtGroupIndex:indexPath.section ingredientIndex:indexPath.row]; - if (deleteSuccess) - { - logUserAction(@"ingredient_delete", [ingredientToDelete dictionaryForAnalytics]); - - [tableView beginUpdates]; - if (ingredientGroup.countOfIngredients == 0) - { - [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic]; - } - else - { - [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; - } - - if (needToDeleteFromRecents) - { - CSRecentsIngredientGroup *afterChangeRecents = ingredients.recents; - if (afterChangeRecents == nil) - { - [tableView deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic]; - } - else - { - [tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:[beforeChangeRecents indexOfIngredient:ingredientToDelete] inSection:0]] - withRowAnimation:UITableViewRowAnimationAutomatic]; - } - } - [tableView endUpdates]; - } - else - { - logIssue(@"ingredient_delete_fail", [ingredientToDelete dictionaryForAnalytics]); - } - } -} - - (void)editIngredient:(id)sender { UIViewController *editVC; diff --git a/CookSmart/CookSmart/CSIngredientsExt.swift b/CookSmart/CookSmart/CSIngredientsExt.swift new file mode 100644 index 0000000..945746f --- /dev/null +++ b/CookSmart/CookSmart/CSIngredientsExt.swift @@ -0,0 +1,30 @@ +// +// CSIngredientsExt.swift +// cake +// +// Created by Alex King on 3/29/20. +// Copyright © 2020 Olga Galchenko. All rights reserved. +// + +import Foundation + +extension CSIngredient: Identifiable { + public var id: String { name } +} + +extension CSIngredientGroup: Identifiable { + public var id: String { name } +} + +extension CSIngredientGroup { + var ingredients: [CSIngredient] { + (0 ..< countOfIngredients()).map { ingredient(at: $0) } + } +} + +extension CSIngredients { + var ingredientList: [CSIngredientGroup] { + let groups: [CSIngredientGroup] = (0 ..< countOfIngredientGroups()).map { ingredientGroup(at: $0) } + return groups + } +} diff --git a/CookSmart/CookSmart/CSScaleView.m b/CookSmart/CookSmart/CSScaleView.m index 41f720b..41e4e2f 100644 --- a/CookSmart/CookSmart/CSScaleView.m +++ b/CookSmart/CookSmart/CSScaleView.m @@ -195,7 +195,11 @@ static inline CGFloat unitsPerPoint(CSScaleView *scaleView) static inline CGFloat ptsPerUnit(CSScaleView *scaleView) { - return (SCALE_TILE_HEIGHT/scaleView.unitsPerTile); + CGFloat pts = (SCALE_TILE_HEIGHT/scaleView.unitsPerTile); + if (isnan(pts)) { + return 0; + } + return pts; } static inline CGFloat getTargetContentOffset(CSScaleView *scaleView) @@ -206,10 +210,14 @@ static inline CGFloat getTargetContentOffset(CSScaleView *scaleView) static inline void setScrollViewOffset(CSScaleView *scaleView, CGPoint newContentOffset, BOOL cancelDeceleration) { + if (isnan(newContentOffset.y)) { + return; + } id delegate = scaleView.delegate; scaleView.delegate = nil; if (cancelDeceleration) { + NSLog(@"%f", newContentOffset.y); [scaleView setContentOffset:newContentOffset animated:NO]; } else diff --git a/CookSmart/CookSmart/Core/Colors.swift b/CookSmart/CookSmart/Core/Colors.swift index 479dfd9..5304b96 100644 --- a/CookSmart/CookSmart/Core/Colors.swift +++ b/CookSmart/CookSmart/Core/Colors.swift @@ -11,7 +11,7 @@ import UIKit enum Color { static let redLineColor = Color.color( light: UIColor(red: 187.0 / 255.0, green: 1.0 / 255.0, blue: 3.0 / 255.0, alpha: 1.0), - dark: UIColor(red: 187.0 / 255.0, green: 1.0 / 255.0, blue: 3.0 / 255.0, alpha: 1.0) + dark: UIColor(red: 234.0 / 255.0, green: 110.0 / 255.0, blue: 104.0 / 255.0, alpha: 1.0) ) static let background = Color.color( diff --git a/CookSmart/CookSmart/Edit Ingredient/EditIngredientViewController.swift b/CookSmart/CookSmart/Edit Ingredient/EditIngredientViewController.swift index 878a413..069907e 100644 --- a/CookSmart/CookSmart/Edit Ingredient/EditIngredientViewController.swift +++ b/CookSmart/CookSmart/Edit Ingredient/EditIngredientViewController.swift @@ -7,6 +7,15 @@ // import Foundation +import SwiftUI + +struct EditIngredientViewControllerRepresentable: UIViewControllerRepresentable { + func makeUIViewController(context: Context) -> EditIngredientViewController { + EditIngredientViewController() + } + + func updateUIViewController(_ uiViewController: EditIngredientViewController, context: Context) {} +} class EditIngredientViewController: UIViewController { diff --git a/CookSmart/CookSmart/IngredientListViewController.swift b/CookSmart/CookSmart/IngredientListViewController.swift new file mode 100644 index 0000000..f0d85a8 --- /dev/null +++ b/CookSmart/CookSmart/IngredientListViewController.swift @@ -0,0 +1,127 @@ +// +// IngredientListViewController.swift +// cake +// +// Created by Alex King on 3/28/20. +// Copyright © 2020 Olga Galchenko. All rights reserved. +// + +import Foundation +import SwiftUI + +class IngredientListViewController: UIHostingController { + init() { + super.init(rootView: IngredientListView()) + } + + @objc + dynamic required init?(coder _: NSCoder) { + assertionFailure("init(coder:) has not been implemented") + return nil + } + + override func viewDidLoad() { + super.viewDidLoad() + CSIngredients.sharedInstance()?.refreshRecents() + } +} + +struct IngredientListView: View { + @State private var searchText: String = "" + + var body: some View { + NavigationView { + List { + SearchBar(text: $searchText) + ForEach(CSIngredients.sharedInstance()!.ingredientList) { group in + Section(header: Text(group.name)) { + ForEach(group.ingredients) { ingredient in + IngredientListCell(ingredientName: ingredient.name) + } + } + } + } + .listStyle(GroupedListStyle()) + .navigationBarTitle("Ingredients") + .navigationBarItems(leading: + Button(action: { + print("Pressed") + }, label: { + Image(systemName: "xmark") + .foregroundColor(SwiftUI.Color(Color.redLineColor)) + .font(Font.system(size: 20, weight: .medium, design: .default)) + }), + trailing: + NavigationLink(destination: EditIngredientViewControllerRepresentable(), + label: { Image(systemName: "plus") + .foregroundColor(SwiftUI.Color(Color.redLineColor)) + .font(Font.system(size: 20, weight: .medium, design: .default)) + })) + } + } +} + +struct IngredientListCell: View { + private let ingredientName: String + + init(ingredientName: String = "Sugar") { + self.ingredientName = ingredientName + } + + var body: some View { + ZStack { + NavigationLink(destination: EditIngredientViewControllerRepresentable()) { + EmptyView() + }.buttonStyle(PlainButtonStyle()) + HStack { + Text(ingredientName) + Spacer() + Button(action: { + print("Edit Tapped") + }, label: { + Image(systemName: "pencil.circle") + .foregroundColor(SwiftUI.Color(Color.redLineColor)) + .font(Font.system(size: 22, weight: .regular, design: .default)) + }).buttonStyle(BorderlessButtonStyle()) + } + } + } +} + +private struct SearchBar: UIViewRepresentable { + @Binding var text: String + + class Coordinator: NSObject, UISearchBarDelegate { + @Binding var text: String + + init(text: Binding) { + _text = text + } + + func searchBar(_: UISearchBar, textDidChange searchText: String) { + text = searchText + } + } + + func makeCoordinator() -> SearchBar.Coordinator { + Coordinator(text: $text) + } + + func makeUIView(context: UIViewRepresentableContext) -> UISearchBar { + let searchBar = UISearchBar(frame: .zero) + searchBar.placeholder = "Search" + searchBar.delegate = context.coordinator + searchBar.searchBarStyle = .minimal + return searchBar + } + + func updateUIView(_ uiView: UISearchBar, context _: UIViewRepresentableContext) { + uiView.text = text + } +} + +struct IngredientListViewController_Previews: PreviewProvider { + static var previews: some View { + IngredientListView() + } +} diff --git a/CookSmart/CookSmart/cake-Bridging-Header.h b/CookSmart/CookSmart/cake-Bridging-Header.h index 042f261..9922305 100644 --- a/CookSmart/CookSmart/cake-Bridging-Header.h +++ b/CookSmart/CookSmart/cake-Bridging-Header.h @@ -11,3 +11,6 @@ #import "CSIngredient.h" #import "CSIngredients.h" #import "CSIngredientListVC.h" +#import "CSIngredientGroup.h" +#import "CSRecentsIngredientGroup.h" +#import "CSIngredientGroupInternals.h"