-
Notifications
You must be signed in to change notification settings - Fork 0
Adding SwiftUI Ingredient List #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
38f6bc9
92ce045
8af356f
bc49463
5fbed12
15f6e32
ede39a8
3196bfe
3766ae6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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] { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor: I would name it |
||
| let groups: [CSIngredientGroup] = (0 ..< countOfIngredientGroups()).map { ingredientGroup(at: $0) } | ||
| return groups | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmmm... that sounds like we have some kind of a problem with the view lifecycle. It sounds like this is being called when unitsPerTile is zero? |
||
| 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; | ||
| } | ||
|
Comment on lines
+213
to
+215
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had some weird crashes that I needed to fix with this. 🤷♂ Should be fine once this is converted to Swift
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. |
||
| id delegate = scaleView.delegate; | ||
| scaleView.delegate = nil; | ||
| if (cancelDeceleration) | ||
| { | ||
| NSLog(@"%f", newContentOffset.y); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clean up. |
||
| [scaleView setContentOffset:newContentOffset animated:NO]; | ||
| } | ||
| else | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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<IngredientListView> { | ||
| 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() | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmmm, why is the CSIngredients optional? When might it be missing? Might it make sense to just throw when it's not available inside the
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. or is the optional just the artifact of Objective C interop?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, shouldn't this go into viewWillAppear or something like that, i.e. wouldn't we want to refresh recents every time this view is shown. |
||
| } | ||
| } | ||
|
|
||
| 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") | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to fill in the action here. |
||
| }, label: { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I hope all this indentation looks better in XCode than it does here. |
||
| Image(systemName: "xmark") | ||
| .foregroundColor(SwiftUI.Color(Color.redLineColor)) | ||
| .font(Font.system(size: 20, weight: .medium, design: .default)) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we try Avenir here?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wait, why is there font in here at all? This is the closing |
||
| }), | ||
| trailing: | ||
| NavigationLink(destination: EditIngredientViewControllerRepresentable(), | ||
| label: { Image(systemName: "plus") | ||
| .foregroundColor(SwiftUI.Color(Color.redLineColor)) | ||
| .font(Font.system(size: 20, weight: .medium, design: .default)) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. Why do we need a font here at all? |
||
| })) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aren't we missing the "Reset to Defaults" button here somewhere? |
||
| } | ||
| } | ||
| } | ||
|
|
||
| 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") | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to fill in action here. |
||
| }, label: { | ||
| Image(systemName: "pencil.circle") | ||
| .foregroundColor(SwiftUI.Color(Color.redLineColor)) | ||
| .font(Font.system(size: 22, weight: .regular, design: .default)) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same question regarding font. |
||
| }).buttonStyle(BorderlessButtonStyle()) | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private struct SearchBar: UIViewRepresentable { | ||
| @Binding var text: String | ||
|
|
||
| class Coordinator: NSObject, UISearchBarDelegate { | ||
| @Binding var text: String | ||
|
|
||
| init(text: Binding<String>) { | ||
| _text = text | ||
| } | ||
|
|
||
| func searchBar(_: UISearchBar, textDidChange searchText: String) { | ||
| text = searchText | ||
| } | ||
| } | ||
|
|
||
| func makeCoordinator() -> SearchBar.Coordinator { | ||
| Coordinator(text: $text) | ||
| } | ||
|
|
||
| func makeUIView(context: UIViewRepresentableContext<SearchBar>) -> UISearchBar { | ||
| let searchBar = UISearchBar(frame: .zero) | ||
| searchBar.placeholder = "Search" | ||
| searchBar.delegate = context.coordinator | ||
| searchBar.searchBarStyle = .minimal | ||
| return searchBar | ||
| } | ||
|
|
||
| func updateUIView(_ uiView: UISearchBar, context _: UIViewRepresentableContext<SearchBar>) { | ||
| uiView.text = text | ||
| } | ||
| } | ||
|
|
||
| struct IngredientListViewController_Previews: PreviewProvider { | ||
| static var previews: some View { | ||
| IngredientListView() | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clean up the comments.