-
Notifications
You must be signed in to change notification settings - Fork 385
Query for label on tap in RepoIssuesVC #2414
base: master
Are you sure you want to change the base?
Conversation
0a1e5b8
to
d349bfb
Compare
Classes/Section Controllers/SearchBar/SearchBarSectionController.swift
Outdated
Show resolved
Hide resolved
Classes/Section Controllers/SearchBar/SearchBarSectionController.swift
Outdated
Show resolved
Hide resolved
@jdisho Thanks for your review! I'm not 100% sure why this is, but I don't see the pattern of conforming to protocols in extensions used elsewhere in the app. I'm just trying to stay consistent with the rest of the codebase; I don't have any strong opinion on the issue. See IssuesViewController for an example of conforming to a lot of delegates inside the class. |
+1 on not using |
placeholder: Constants.Strings.search, | ||
delegate: self, | ||
query: previousSearchString | ||
) | ||
self?.setSearchBarTextSectionControllerDelegate = sectionController |
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.
This is a bit of a backwards pattern. Delegates should be communicating "back up" instead of sending info down.
Instead, can we just get the search VC from the adapter and set its text?
func didTap(label: String) {
// probably move "header" to an actual property in the VC
guard let controller = feed.swiftAdapter.sectionController(for: "header") as SearchBarSectionController
else { return }
controller.append(query: " label:\(label)")
}
Much more straightforward
func append(query: String) { | ||
searchBar.text?.append(query) | ||
guard let text = searchBar.text else { return } | ||
delegate?.didChangeSearchText(cell: self, query: text) |
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.
Is this not triggered when setting the text in the bar?
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.
Yeah the delegate method is not triggered here on it's own. The text in the search bar changes but no fetch/update happens.
Classes/Section Controllers/SearchBar/SearchBarSectionController.swift
Outdated
Show resolved
Hide resolved
@@ -35,6 +40,7 @@ final class SearchBarSectionController: ListSwiftSectionController<String>, Sear | |||
guard let `self` = self else { return } | |||
cell.delegate = self | |||
cell.configure(query: self.query, placeholder: self.placeholder) | |||
self.setSearchBarTextDelegate = cell |
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.
I think we should follow the same pattern of fetching the SC explicitly and instead of backwards-wiring the delegate to the cell, just find the cell and set the text in the SC:
func append(query: String) {
guard let cell = collectionContext?.cellForItemAt(index: 0) as? SearchBarCell { else return }
cell.searchBar.text = query
}
Classes/Views/LabelListView.swift
Outdated
guard let lastCell = collectionView.cellForItem(at: [0, labels.count - 1]) | ||
else { return self } | ||
return point.x > lastCell.frame.maxX ? self : super.hitTest(point, with: event) | ||
} |
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.
Eep, mucking w/ hitTest
makes me so nervous. Why is this necessary?
Also simply checking for x > maxX looks too limited, should there be some point-in-rect math?
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.
I highlighted the LabelListView
frame in orange. The UicollectionView's frame is set to its bounds.
Without the HitTest override, if you click inside the orange border on an area that's not a LabelCell, nothing happens. In the HitTest override, I'm trying to process taps that land on a label cell, and pass through taps that touchdown right of the right-most label cell.
Perhaps setting the CollectionView's frame is more appropriate, so that it's only as wide as it needs to be given the number of labels that it presents?
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.
This seems to send the taps to the right places:
// this is copied/pasted from existing methods to find width
static func labelTextTotalWidth(labels: [RepositoryLabel]) -> CGFloat {
let interitemSpacing = labels.count > 1 ? CGFloat(labels.count - 1) * Styles.Sizes.labelSpacing : 0.0
return labels.reduce(0, { $0 + LabelListCell.size($1.name).width }) + interitemSpacing
}
override func layoutSubviews() {
super.layoutSubviews()
collectionView.frame = CGRect(
x: bounds.minX,
y: bounds.minY,
width: min(LabelListView.labelTextTotalWidth(labels: labels), bounds.width)
height: bounds.height
)
}
a005ab3
to
650e620
Compare
@@ -14,11 +14,12 @@ protocol SearchBarSectionControllerDelegate: class { | |||
} | |||
|
|||
final class SearchBarSectionController: ListSwiftSectionController<String>, SearchBarCellDelegate { | |||
|
|||
|
|||
static let listSwiftId = "header" |
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.
Okay with this name?
searchBarCell?.configure(query: query, placeholder: placeholder) | ||
self.query = query | ||
delegate?.didChangeSelection(sectionController: self, query: query) | ||
} |
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.
Reason for keeping a reference to SearchBarCell
and using it here:
let cell = collectionContext?.cellForItemAt(index: 0) as? SearchBarCell
Above code was returning nil
if the searchBar was scrolled out of view. Eg scroll down a little, tap a label, and the collectionContext.cellForItem
method would return nil.
Wanted to add this screenshot with the updated method used to calculate the CollectionView's frame. See this comment above. Here, the CollectionView's border is Orange. Seems like it's working correctly: |
Connected to #2263
Summary:
In
RepositoryIssuesViewController
, when a user taps a label, the label is appended to the searchBar text and the query is fetched.Test Notes:
Manually:
How:
There's a lot of chaining delegates involved. Reviewers: it will help to look at this view hierarchy:
The label is inside the
LabelListView
. It tellsRepositorySummaryCell
, which tellsRepositorySummarySectionController
, which tellsRepositoryIssuesViewController
that it has been tapped.Then:
The
RepoIssueViewController
then tellsSearchBarSectionController
to tellSearchBarCell
to set the searchBar text appropriately. Then the fetch proceeds as it currently would, as though the user entered the text in the searchBar. My hope is that this preserves a "one-way data flow".