Skip to content

Commit

Permalink
Merge pull request #152 from DimensionSrl/feature/new_filter_bar_view
Browse files Browse the repository at this point in the history
New filter bar view UI component
  • Loading branch information
RudiThoeni authored Nov 15, 2024
2 parents dfd4a4d + dca9e6a commit d12b817
Show file tree
Hide file tree
Showing 9 changed files with 367 additions and 342 deletions.
7 changes: 7 additions & 0 deletions NOICommunity.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
313FB0B72719C518000AD9DA /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 313FB0B62719C518000AD9DA /* GoogleService-Info.plist */; };
313FB0B92719CFA9000AD9DA /* EventsMainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 319C0EA226F4A43C00C6D38B /* EventsMainViewController.xib */; };
314263A5271F048800DA4429 /* AppFeatureSwitches.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314263A4271F048800DA4429 /* AppFeatureSwitches.swift */; };
3145054D2CE39190000F3E9F /* CoreUI in Frameworks */ = {isa = PBXBuildFile; productRef = 3145054C2CE39190000F3E9F /* CoreUI */; };
3145D23126B3F73F00F16787 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3145D23026B3F73F00F16787 /* AppDelegate.swift */; };
3145D23326B3F73F00F16787 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3145D23226B3F73F00F16787 /* SceneDelegate.swift */; };
3145D23A26B3F74000F16787 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3145D23926B3F74000F16787 /* Images.xcassets */; };
Expand Down Expand Up @@ -468,6 +469,7 @@
3182F4A227DB3841005ADDAF /* AppPreferencesClient in Frameworks */,
3182F4A627DB3841005ADDAF /* EventShortClient in Frameworks */,
3181B9212B1E12BD000D2A0F /* Core in Frameworks */,
3145054D2CE39190000F3E9F /* CoreUI in Frameworks */,
3182F4AA27DB3841005ADDAF /* EventShortTypesClient in Frameworks */,
31E058F22812F18800D1F7FE /* KeychainAccess in Frameworks */,
319C4653282BB32400946AC7 /* ArticlesClient in Frameworks */,
Expand Down Expand Up @@ -1094,6 +1096,7 @@
317EC88A283BB83E00F30B95 /* PeopleClientLive */,
3181B9202B1E12BD000D2A0F /* Core */,
31B1926E2C6A2136009872E9 /* FirebaseCrashlytics */,
3145054C2CE39190000F3E9F /* CoreUI */,
);
productName = NOICommunity;
productReference = 3145D22D26B3F73F00F16787 /* NOICommunity.app */;
Expand Down Expand Up @@ -2307,6 +2310,10 @@
package = 311E0EC42825157800404DCE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseMessaging;
};
3145054C2CE39190000F3E9F /* CoreUI */ = {
isa = XCSwiftPackageProductDependency;
productName = CoreUI;
};
317B6F9B28118BD6008D07C0 /* AuthClient */ = {
isa = XCSwiftPackageProductDependency;
productName = AuthClient;
Expand Down
38 changes: 0 additions & 38 deletions NOICommunity/Extensions/UIScrollView+ScrollToView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,6 @@

import UIKit

public extension UIScrollView {

func scrollToView(
view: UIView,
position: UITableView.ScrollPosition = .top,
animated: Bool
) {
if position == .none && bounds.intersects(view.frame) {
return
}

guard let origin = view.superview
else { return }

let childStartPoint = origin.convert(view.frame.origin, to: self)
let scrollPointY: CGFloat
switch position {
case .bottom:
let childEndY = childStartPoint.y + view.frame.height
scrollPointY = .maximum(childEndY - frame.size.height, 0)
case .middle:
let childCenterY = childStartPoint.y + view.frame.height / 2.0
let scrollViewCenterY = frame.size.height / 2.0
scrollPointY = .maximum(childCenterY - scrollViewCenterY, 0)
default:
scrollPointY = childStartPoint.y
}

let targetRect = CGRect(
x: 0,
y: scrollPointY,
width: 1,
height: frame.height
)
scrollRectToVisible(targetRect, animated: animated)
}
}

extension UIScrollView {
enum ScrollDirection {
case top, bottom, left, right
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ final class CompaniesFiltersViewController: UIViewController {

@IBOutlet private var filtersBarView: FiltersBarView! {
didSet {
filtersBarView.delegate = self
filtersBarView.items = companyViewModel
.filterItems
.map(\.title)
filtersBarView.scrollView.contentInset = .init(
filtersBarView.contentInset = .init(
top: 0,
left: 8,
bottom: 0,
Expand Down Expand Up @@ -58,14 +59,6 @@ final class CompaniesFiltersViewController: UIViewController {
}
}

private var filters: UISegmentedControl {
filtersBarView.segmentedControl
}

private var filtersScrollView: UIScrollView {
filtersBarView.scrollView
}

private var subscriptions: Set<AnyCancellable> = []

private lazy var companyViewModel = peopleViewModel.makeCompanyViewModel()
Expand Down Expand Up @@ -196,49 +189,12 @@ private extension CompaniesFiltersViewController {

companyViewModel
.$activeFilter
.sink { [weak filters, weak companyViewModel] newActiveFilter in
guard let filters,
.sink { [weak filtersBarView, weak companyViewModel] newActiveFilter in
guard let filtersBarView,
let companyViewModel
else { return }

if let matchingIndex = companyViewModel.filterItems.firstIndex(of: newActiveFilter) {
filters.selectedSegmentIndex = matchingIndex
} else {
filters.selectedSegmentIndex = UISegmentedControl.noSegment
}
}
.store(in: &subscriptions)

filters
.publisher(for: .valueChanged)
.sink { [weak filters, weak companyViewModel, weak filtersScrollView] in
guard let filters,
let companyViewModel,
let filtersScrollView
else { return }

let selectedSegmentIndex = filters.selectedSegmentIndex
let newSelectedFilter = companyViewModel.filterItems[selectedSegmentIndex]
companyViewModel.filterBy(filter: newSelectedFilter)

let convertRect: (UIView) -> CGRect = {
$0.convert($0.frame, to: filtersScrollView)
}
let selectedControls = filters
.recursiveSubviews { $0 is UILabel }
.sorted { convertRect($0).minX < convertRect($1).minX }
let selectedControl = selectedControls[selectedSegmentIndex]
let selectedControlRect = convertRect(selectedControl)
if !filtersScrollView.bounds.contains(
selectedControlRect
) {
let targetScrollingRect = selectedControlRect
.insetBy(dx: -100, dy: 0)
filtersScrollView.scrollRectToVisible(
targetScrollingRect,
animated: true
)
}
filtersBarView.indexOfSelectedItem = companyViewModel.filterItems.firstIndex(of: newActiveFilter)
}
.store(in: &subscriptions)
}
Expand Down Expand Up @@ -468,6 +424,20 @@ private extension CompaniesFiltersViewController.CollectionViewController {

}

// MARK: FilterBarViewDelegate

extension CompaniesFiltersViewController: FiltersBarViewDelegate {

func filtersBarView(
_ filtersBarView: FiltersBarView,
didSelectItemAt index: Int
) {
let newSelectedFilter = companyViewModel.filterItems[index]
companyViewModel.filterBy(filter: newSelectedFilter)
}

}

// MARK: UISearchBarDelegate {

extension CompaniesFiltersViewController.CollectionViewController: UISearchBarDelegate {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,19 @@ final class EventsMainViewController: UIViewController {
}

@IBOutlet private var filterBarContainerView: UIView!
@IBOutlet private var filterBarView: EventsFiltersBarView!
@IBOutlet private var contentContainerView: UIView!

private var dateIntervalsControl: UISegmentedControl {
filterBarView.dateIntervalsControl
@IBOutlet private var filterBarView: EventsFiltersBarView! {
didSet {
filterBarView.filtersBarView.delegate = self
}
}

@IBOutlet private var contentContainerView: UIView!

private var filtersButton: UIButton {
filterBarView.filtersButton
}

private var dateIntervalsScrollView: UIScrollView {
filterBarView.scrollView
}

private lazy var resultsVC = makeResultsViewController()

init(viewModel: EventsViewModel) {
Expand Down Expand Up @@ -153,38 +151,6 @@ private extension EventsMainViewController {
}

func configureBindings() {
dateIntervalsControl.publisher(for: .valueChanged)
.sink { [unowned dateIntervalsControl, weak viewModel, weak dateIntervalsScrollView] in
let selectedSegmentIndex = dateIntervalsControl.selectedSegmentIndex

let newDateIntervalFilter = DateIntervalFilter
.allCases[dateIntervalsControl.selectedSegmentIndex]
viewModel?.dateIntervalFilter = newDateIntervalFilter
viewModel?.refreshEvents()

if let dateIntervalsScrollView = dateIntervalsScrollView {
let convertRect: (UIView) -> CGRect = {
$0.convert($0.frame, to: dateIntervalsScrollView)
}
let selectedControls = dateIntervalsControl
.recursiveSubviews { $0 is UILabel }
.sorted { convertRect($0).minX < convertRect($1).minX }
let selectedControl = selectedControls[selectedSegmentIndex]
let selectedControlRect = convertRect(selectedControl)
if !dateIntervalsScrollView.bounds.contains(
selectedControlRect
) {
let targetScrollingRect = selectedControlRect
.insetBy(dx: -100, dy: 0)
dateIntervalsScrollView.scrollRectToVisible(
targetScrollingRect,
animated: true
)
}
}
}
.store(in: &subscriptions)

filtersButton.publisher(for: .primaryActionTriggered)
.sink { [weak viewModel] in
viewModel?.showFilters()
Expand Down Expand Up @@ -267,5 +233,29 @@ private extension EventsMainViewController {
filtersButton.setTitle(title, for: .normal)
}
.store(in: &subscriptions)

viewModel.$dateIntervalFilter
.sink { [weak self] newActiveFilter in
guard let self
else { return }

self.filterBarView.filtersBarView.indexOfSelectedItem = DateIntervalFilter.allCases.firstIndex(of: newActiveFilter)
}
.store(in: &subscriptions)
}
}

// MARK: FilterBarViewDelegate

extension EventsMainViewController: FiltersBarViewDelegate {

func filtersBarView(
_ filtersBarView: FiltersBarView,
didSelectItemAt index: Int
) {
let newDateIntervalFilter = DateIntervalFilter.allCases[index]
viewModel.dateIntervalFilter = newDateIntervalFilter
viewModel.refreshEvents()
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class EventsFiltersBarView: UIView {
@IBOutlet private(set) var filtersBarView: FiltersBarView! {
didSet {
filtersBarView.items = DateIntervalFilter.allCases.map(\.localizedString)
filtersBarView.scrollView.contentInset = .init(
filtersBarView.contentInset = .init(
top: 0,
left: 17,
bottom: 0,
Expand All @@ -35,14 +35,6 @@ class EventsFiltersBarView: UIView {
}
}

var dateIntervalsControl: UISegmentedControl {
filtersBarView.segmentedControl
}

var scrollView: UIScrollView {
filtersBarView.scrollView
}

override init(frame: CGRect) {
super.init(frame: frame)
setup()
Expand Down
Loading

0 comments on commit d12b817

Please sign in to comment.