Modify the searchBar module

dev
wenlei 1 year ago
parent 53fde354c9
commit c8a3ef59ca

@ -138,6 +138,8 @@
77FAF7622B07434A00FC2CA1 /* AudioMoreActionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77FAF7612B07434A00FC2CA1 /* AudioMoreActionController.swift */; };
77FAF7642B075FEB00FC2CA1 /* JournalDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77FAF7632B075FEB00FC2CA1 /* JournalDetailViewModel.swift */; };
77FB7A702B48074600B64030 /* MusicStyleViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77FB7A6F2B48074600B64030 /* MusicStyleViewModel.swift */; };
77FB7A722B48E93100B64030 /* SearchResultsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77FB7A712B48E93100B64030 /* SearchResultsViewModel.swift */; };
77FB7A742B49944E00B64030 /* ScrollSegmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77FB7A732B49944E00B64030 /* ScrollSegmentView.swift */; };
B570F70B7040469E9D729E7E /* Pods_IndieMusic.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BA421D41748C113CCE36A32 /* Pods_IndieMusic.framework */; };
/* End PBXBuildFile section */
@ -298,6 +300,8 @@
77FAF7612B07434A00FC2CA1 /* AudioMoreActionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioMoreActionController.swift; sourceTree = "<group>"; };
77FAF7632B075FEB00FC2CA1 /* JournalDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JournalDetailViewModel.swift; sourceTree = "<group>"; };
77FB7A6F2B48074600B64030 /* MusicStyleViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicStyleViewModel.swift; sourceTree = "<group>"; };
77FB7A712B48E93100B64030 /* SearchResultsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultsViewModel.swift; sourceTree = "<group>"; };
77FB7A732B49944E00B64030 /* ScrollSegmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollSegmentView.swift; sourceTree = "<group>"; };
A90C808FB1B74BB851FB67CB /* Pods-IndieMusic-IndieMusicUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IndieMusic-IndieMusicUITests.debug.xcconfig"; path = "Target Support Files/Pods-IndieMusic-IndieMusicUITests/Pods-IndieMusic-IndieMusicUITests.debug.xcconfig"; sourceTree = "<group>"; };
B4D1DC4EEC82560A8FAECF4A /* Pods-IndieMusic-IndieMusicUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IndieMusic-IndieMusicUITests.release.xcconfig"; path = "Target Support Files/Pods-IndieMusic-IndieMusicUITests/Pods-IndieMusic-IndieMusicUITests.release.xcconfig"; sourceTree = "<group>"; };
C8F1B981837A2D1AAE58D709 /* Pods-IndieMusic.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IndieMusic.release.xcconfig"; path = "Target Support Files/Pods-IndieMusic/Pods-IndieMusic.release.xcconfig"; sourceTree = "<group>"; };
@ -454,6 +458,7 @@
774399A92AFE3170006F8EEA /* PaddingLabel.swift */,
774A17F62B04932100F56DF1 /* SegmentControl.swift */,
77FA0B3F2B0D8E9300404C5E /* LayoutableButton.swift */,
77FB7A732B49944E00B64030 /* ScrollSegmentView.swift */,
);
path = Common;
sourceTree = "<group>";
@ -661,6 +666,7 @@
7751D3732B43C9FA00F1F2BD /* MusicStyleViewController.swift */,
77FB7A6F2B48074600B64030 /* MusicStyleViewModel.swift */,
7751D3772B43EA1200F1F2BD /* SearchResultsController.swift */,
77FB7A712B48E93100B64030 /* SearchResultsViewModel.swift */,
);
path = Search;
sourceTree = "<group>";
@ -984,6 +990,7 @@
778B8A9C2AF8ECFC0034AFD4 /* LogManager.swift in Sources */,
778B8A992AF8ECFC0034AFD4 /* Reachability.swift in Sources */,
774A18092B06120000F56DF1 /* Home.swift in Sources */,
77FB7A742B49944E00B64030 /* ScrollSegmentView.swift in Sources */,
778B8ABF2AF8ED280034AFD4 /* NavigationController.swift in Sources */,
774399AA2AFE3170006F8EEA /* PaddingLabel.swift in Sources */,
77FB7A702B48074600B64030 /* MusicStyleViewModel.swift in Sources */,
@ -1056,6 +1063,7 @@
77FA0B3E2B0C573600404C5E /* Filter.swift in Sources */,
77165D742B464493002AE0A5 /* BarButtonItem.swift in Sources */,
7751D3662B42BE7F00F1F2BD /* FeedbackViewController.swift in Sources */,
77FB7A722B48E93100B64030 /* SearchResultsViewModel.swift in Sources */,
774A18142B07329600F56DF1 /* MultiUserAvatarView.swift in Sources */,
778B8AAA2AF8ED0E0034AFD4 /* AVPlayer.swift in Sources */,
77FA0B442B0DFABD00404C5E /* LoginView.swift in Sources */,

@ -27,6 +27,7 @@ class Navigator {
case share(viewModel: ShareActionViewModel)
case musicStyle(viewModel: MusicStyleViewModel)
case searchResults(viewModel: SearchResultsViewModel)
case test
case safari(URL)
@ -73,7 +74,8 @@ class Navigator {
return ShareActionController.init(viewModel: viewModel, navigator: self)
case .musicStyle(viewModel: let viewModel):
return MusicStyleViewController.init(viewModel: viewModel, navigator: self)
case .searchResults(viewModel: let viewModel):
return SearchResultsController.init(viewModel: viewModel, navigator: self)
case .test:
let test = UIViewController.init()

@ -0,0 +1,499 @@
//
// ScrollSegmentView.swift
// IndieMusic
//
// Created by WenLei on 2024/1/6.
//
import Foundation
public struct SegmentStyle{
///
public var showCover = false
/// 线
public var showLine = false
///
public var scaleTitle = false
///
public var scrollTitle = true
///
public var average = true
/// 2
public var scrollLineHeight: CGFloat = 2
///
public var scrollLineColor = UIColor.brown
///
public var coverBackgroundColor = UIColor.lightGray
///
public var coverCornerRadius: CGFloat = 14.0
/// cover 28
public var coverHeight: CGFloat?
/// 15
public var titleMargin: CGFloat = 15
/// 14.0
public var titleFont = UIFont.systemFont(ofSize: 14.0)
///
public var titleSelectFont = UIFont.systemFont(ofSize: 14.0)
/// 1.3
public var titleBigScale: CGFloat = 1.1
///
let titleOriginalScale: CGFloat = 1.0
///
var backgroundColor: UIColor = UIColor.white
///
var normalborderColor: UIColor = UIColor.gray
///
var selectedborderColor: UIColor = UIColor.clear
///
public var lineSpace: CGFloat = 5
/// 使RGB!! RGBcrash
public var normalTitleColor = UIColor(red: 51.0/255.0, green: 53.0/255.0, blue: 75/255.0, alpha: 1.0)
/// 使RGB!! RGBcrash
public var selectedTitleColor = UIColor(red: 255.0/255.0, green: 0.0/255.0, blue: 121/255.0, alpha: 1.0)
public init() {
}
}
open class ScrollSegmentView: UIView {
var segmentStyle: SegmentStyle
///
open var titleBtnOnClick:((_ label: UILabel, _ index: Int)->Void)?
///
fileprivate var titleWidthArry: [CGFloat] = []
///
fileprivate var titles: [String]
///
fileprivate var labelsArray: [UILabel] = []
/// self.bounds.size.width
fileprivate var currentWidth: CGFloat = 0
///
fileprivate var currentIndex = 0
///
fileprivate var oldIndex = 0
///
fileprivate var labelWithMax: CGFloat = 0
/// xx
fileprivate var xGap = 5
///
fileprivate var wGap: Int {
return 2 * xGap
}
///
fileprivate var lineSpace: CGFloat = 12
///
lazy var scrollView: UIScrollView = {
let scrollV = UIScrollView()
scrollV.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
scrollV.showsHorizontalScrollIndicator = false
scrollV.bounces = true
scrollV.isPagingEnabled = false
scrollV.scrollsToTop = false
return scrollV
}()
///
fileprivate lazy var scrollLine: UIView? = {[unowned self] in
let line = UIView()
line.layer.cornerRadius = 3
return self.segmentStyle.showLine ? line : nil
}()
///
fileprivate lazy var coverView: UIView? = {[unowned self] in
let cover = UIView()
cover.layer.cornerRadius = CGFloat(self.segmentStyle.coverCornerRadius)
cover.layer.masksToBounds = true
return self.segmentStyle.showCover ? cover : nil
}()
/// rgb,
fileprivate lazy var rgbDelta: (deltaR: CGFloat, deltaG: CGFloat, deltaB: CGFloat) = {[unowned self] in
let normalColorRgb = self.normalColorRgb
let selectedTitleColorRgb = self.selectedTitleColorRgb
let deltaR = normalColorRgb.r - selectedTitleColorRgb.r
let deltaG = normalColorRgb.g - selectedTitleColorRgb.g
let deltaB = normalColorRgb.b - selectedTitleColorRgb.b
return (deltaR: deltaR, deltaG: deltaG, deltaB: deltaB)
}()
/// rgb,
fileprivate lazy var normalColorRgb: (r: CGFloat, g: CGFloat, b: CGFloat) = {
if let normalRgb = self.getColorRGB(self.segmentStyle.normalTitleColor) {
return normalRgb
} else {
fatalError("设置普通状态的文字颜色时 请使用RGB空间的颜色值")
}
}()
fileprivate lazy var selectedTitleColorRgb: (r: CGFloat, g: CGFloat, b: CGFloat) = {
if let selectedRgb = self.getColorRGB(self.segmentStyle.selectedTitleColor) {
return selectedRgb
} else {
fatalError("设置选中状态的文字颜色时 请使用RGB空间的颜色值")
}
}()
//FIXME: RGBcrash
fileprivate func getColorRGB(_ color: UIColor) -> (r: CGFloat, g: CGFloat, b: CGFloat)? {
// print(UIColor.getRed(color))
let numOfComponents = color.cgColor.numberOfComponents
if numOfComponents == 4 {
let componemts = color.cgColor.components
// print("\(componemts[0]) --- \(componemts[1]) ---- \(componemts[2]) --- \(componemts[3])")
return (r: componemts?[0], g: componemts?[1], b: componemts?[2]) as! (r: CGFloat, g: CGFloat, b: CGFloat)
}
return nil
}
open var backgroundImage: UIImage? = nil {
didSet {
// imageView
if let image = backgroundImage {
backgroundImageView.image = image
insertSubview(backgroundImageView, at: 0)
}
}
}
fileprivate lazy var backgroundImageView: UIImageView = {[unowned self] in
let imageView = UIImageView(frame: self.bounds)
return imageView
}()
//MARK:-
public init(frame: CGRect, segmentStyle: SegmentStyle, titles: [String]){
self.segmentStyle = segmentStyle
self.titles = titles
super.init(frame: frame)
addSubview(scrollView)
// Titles
setupTitles()
// Frame
setupUI()
}
@objc func titleLabelOnClick(_ tapGes: UITapGestureRecognizer){
guard let currentLabel = tapGes.view as? CustomLabel else { return }
currentIndex = currentLabel.tag
print(currentLabel.tag)
adjustUIWhenBtnOnClickWithAnimate(false)
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//MARK: - public helper
extension ScrollSegmentView {
///
public func selectedIndex(_ selectedIndex: Int, animated: Bool) {
assert(!(selectedIndex < 0 || selectedIndex >= titles.count), "设置的下标不合法!!")
if selectedIndex < 0 || selectedIndex >= titles.count {
return
}
//
currentIndex = selectedIndex
// print("\(oldIndex) ------- \(currentIndex)")
//
adjustUIWhenBtnOnClickWithAnimate(animated)
}
//
public func reloadTitlesWithNewTitles(_ titles: [String]) {
// scrollView
scrollView.subviews.forEach { (subview) in
subview.removeFromSuperview()
}
// label
titleWidthArry.removeAll()
labelsArray.removeAll()
// UI
self.titles = titles
setupTitles()
setupUI()
// default selecte the first tag
selectedIndex(0, animated: true)
}
}
//MARK:-
extension ScrollSegmentView{
// Titles
fileprivate func setupTitles() {
for (index, title) in titles.enumerated(){
let label = CustomLabel(frame: CGRect.zero)
label.tag = index
label.text = title
label.font = segmentStyle.titleFont
label.layer.borderColor = segmentStyle.normalborderColor.cgColor
label.layer.borderWidth = 1
label.layer.cornerRadius = CGFloat(self.segmentStyle.coverCornerRadius)
label.layer.masksToBounds = true
if index == currentIndex {
label.font = segmentStyle.titleSelectFont
label.layer.borderColor = segmentStyle.selectedborderColor.cgColor
}
label.textColor = segmentStyle.normalTitleColor
label.textAlignment = .center
label.isUserInteractionEnabled = true
//
let tapGes = UITapGestureRecognizer(target: self, action: #selector(self.titleLabelOnClick(_:)))
label.addGestureRecognizer(tapGes)
//
let size = (title as NSString).boundingRect(with: CGSize(width: CGFloat(MAXFLOAT), height: 0.0), options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: label.font], context: nil)
//
titleWidthArry.append(size.width)
// label
labelsArray.append(label)
// label
scrollView.addSubview(label)
}
}
// Frame
fileprivate func setupUI() {
scrollView.backgroundColor = segmentStyle.backgroundColor
// Label
currentWidth = bounds.size.width
setUpLabelsPosition()
//
setupScrollLineAndCover()
if segmentStyle.scrollTitle{
if let lastLabel = labelsArray.last {
scrollView.contentSize = CGSize(width: lastLabel.frame.maxX + segmentStyle.titleMargin, height: 0)
}
}
}
/// label
fileprivate func setUpLabelsPosition() {
var titleX: CGFloat = 0.0
let titleY: CGFloat = 0.0
var titleW: CGFloat = 0.0
let titleH = bounds.size.height - segmentStyle.scrollLineHeight
if !segmentStyle.scrollTitle{
// if segmentStyle.average {
// titleW = currentWidth/CGFloat(titles.count)
// } else {
// titleW = currentWidth/CGFloat(titles.count)
// }
for(index, label) in labelsArray.enumerated(){
// titleX = titleW * CGFloat(index)
// titleX = segmentStyle.titleMargin
let currWidth = currentWidth - 2 * segmentStyle.titleMargin
titleW = currWidth/CGFloat(labelsArray.count)
titleX = segmentStyle.titleMargin
if index != 0 {
let lastLabel = labelsArray[index - 1]
titleX = lastLabel.frame.maxX + segmentStyle.titleMargin
}
label.frame = CGRect(x: titleX, y: titleY, width: titleW, height: titleH)
// label.frame = CGRect(x: titleX, y: titleY, width: titleW, height: titleH)
// // 线
// let lineView = UIView.init(frame: CGRect.init(x: titleX, y: titleY, width: 4, height: 10))
// lineView.backgroundColor = UIColor.red
// scrollView.addSubview(lineView)
}
}else{
//
for (index, labelWith) in titleWidthArry.enumerated(){
labelWithMax += labelWith + 2 * segmentStyle.titleMargin
}
print("COntrol Width \(labelWithMax) \(currentWidth)")
//
if labelWithMax <= currentWidth{
for(index, label) in labelsArray.enumerated(){
let currWidth = currentWidth - 2 * segmentStyle.titleMargin
titleW = currWidth/CGFloat(labelsArray.count)
titleX = segmentStyle.titleMargin
if index != 0{
let lastLabel = labelsArray[index - 1]
titleX = lastLabel.frame.maxX + segmentStyle.titleMargin
}
label.frame = CGRect(x: titleX, y: titleY, width: titleW, height: titleH)
// 线
if index != 0 {
let lineView = UIView.init(frame: CGRect.init(x: titleX, y: titleY, width: 1, height: 30))
lineView.center.y = label.center.y
lineView.backgroundColor = UIColor(red: 0.32, green: 0.53, blue: 0.70, alpha: 1.00)
scrollView.addSubview(lineView)
}
}
}
//
else{
for(index, label) in labelsArray.enumerated(){
titleW = titleWidthArry[index]
titleX = segmentStyle.titleMargin
if index != 0{
let lastLabel = labelsArray[index - 1]
titleX = lastLabel.frame.maxX + segmentStyle.titleMargin * 2
}
label.frame = CGRect(x: titleX, y: titleY, width: titleW, height: titleH)
}
}
}
if let firstLabel = labelsArray[0] as? CustomLabel {
// , labeltransform
if segmentStyle.scaleTitle {
firstLabel.currentTransformSx = segmentStyle.titleBigScale
}
//
firstLabel.textColor = segmentStyle.selectedTitleColor
}
}
///
fileprivate func setupScrollLineAndCover(){
if let line = scrollLine {
line.backgroundColor = segmentStyle.scrollLineColor
scrollView.addSubview(line)
scrollView.insertSubview(line, at: 0)
}
if let cover = coverView {
cover.backgroundColor = segmentStyle.coverBackgroundColor
scrollView.insertSubview(cover, at: 0)
}
let coverX = labelsArray[0].frame.origin.x
let coverW = labelsArray[0].frame.size.width
let coverH: CGFloat = segmentStyle.coverHeight ?? bounds.size.height
let coverY = (bounds.size.height - coverH) / 2
//
if segmentStyle.scrollTitle {
// x-xGap width+wGap
coverView?.frame = CGRect(x: coverX - CGFloat(xGap), y: coverY, width: coverW + CGFloat(wGap), height: coverH)
} else {
coverView?.frame = CGRect(x: coverX, y: coverY, width: coverW, height: coverH)
}
//
scrollLine?.frame = CGRect(x: coverX, y: bounds.size.height - segmentStyle.scrollLineHeight - segmentStyle.lineSpace, width: 50, height: segmentStyle.scrollLineHeight)
scrollLine?.center = CGPoint.init(x: labelsArray[0].center.x, y: labelsArray[0].frame.maxY - segmentStyle.lineSpace)
}
/// UI
func adjustUIWhenBtnOnClickWithAnimate(_ animated: Bool){
guard currentIndex != oldIndex else {
return
}
let oldLabel = labelsArray[oldIndex] as! CustomLabel
let currentLabel = labelsArray[currentIndex] as! CustomLabel
//
adjustTitleOffSetToCurrentIndex(currentIndex)
//
UIView.animate(withDuration: animated ? 0.3 : 0) {
[unowned self] in
//
oldLabel.textColor = self.segmentStyle.normalTitleColor
oldLabel.layer.borderColor = segmentStyle.normalborderColor.cgColor
oldLabel.layer.borderWidth = 1
currentLabel.layer.borderColor = segmentStyle.selectedborderColor.cgColor
currentLabel.layer.borderWidth = 0
currentLabel.textColor = self.segmentStyle.selectedTitleColor
//
if self.segmentStyle.scaleTitle {
oldLabel.currentTransformSx = self.segmentStyle.titleOriginalScale
currentLabel.currentTransformSx = self.segmentStyle.titleBigScale
} else {
oldLabel.font = self.segmentStyle.titleFont
currentLabel.font = self.segmentStyle.titleSelectFont
}
//
self.scrollLine?.frame.origin.x = currentLabel.frame.origin.x
// , bounds width transform 使frame
self.scrollLine?.frame.size.width = 50
self.scrollLine?.center = CGPoint.init(x: currentLabel.center.x, y: currentLabel.frame.maxY - segmentStyle.lineSpace)
//
if self.segmentStyle.scrollTitle {
self.coverView?.frame.origin.x = currentLabel.frame.origin.x - CGFloat(self.xGap)
self.coverView?.frame.size.width = currentLabel.frame.size.width + CGFloat(self.wGap)
} else {
self.coverView?.frame.origin.x = currentLabel.frame.origin.x
self.coverView?.frame.size.width = currentLabel.frame.size.width
}
}
oldIndex = currentIndex
titleBtnOnClick?(currentLabel, currentIndex)
}
///
public func adjustTitleOffSetToCurrentIndex(_ currentIndex: Int){
let currentLabel = labelsArray[currentIndex]
for index in labelsArray.enumerated(){
if index.offset != currentIndex{
index.element.textColor = self.segmentStyle.normalTitleColor
}
}
/// scrollView
var offSetX = currentLabel.center.x - currentWidth/2
if offSetX < 0 {
offSetX = 0
}
/// scrollView
var maxOffSetX = scrollView.contentSize.width - currentWidth
//
if maxOffSetX < 0 {
maxOffSetX = 0
}
// offSetX
if offSetX > maxOffSetX {
offSetX = maxOffSetX
}
// scrollView
scrollView.setContentOffset(CGPoint(x:offSetX, y: 0), animated: true)
}
}
open class CustomLabel: UILabel {
/// label
open var currentTransformSx:CGFloat = 1.0 {
didSet {
transform = CGAffineTransform(scaleX: currentTransformSx, y: currentTransformSx)
}
}
}

@ -20,6 +20,7 @@ class SearchResultsController: ViewController {
let searchNoDataView: SearchNoDataView = {
let searchNoDataView = SearchNoDataView.init()
searchNoDataView.isHidden = true
return searchNoDataView
}()
@ -44,6 +45,8 @@ class SearchResultsController: ViewController {
override func makeUI() {
super.makeUI()
view.backgroundColor = .white
view.addSubview(searchTopBar)
view.addSubview(searchNoDataView)
view.addSubview(searchResultsView)
@ -64,7 +67,7 @@ class SearchResultsController: ViewController {
searchTopBar.snp.makeConstraints { make in
make.left.equalTo(view)
make.right.equalTo(view)
make.top.equalTo(view).offset(BaseDimensions.statusBarHeight + 15)
make.top.equalTo(view).offset(15)
make.height.equalTo(40)
}
@ -90,13 +93,17 @@ class SearchResultsController: ViewController {
class SearchTopBar: UIView {
let searchControl: SearchControl = {
let searchControl = SearchControl.init()
searchControl.layer.cornerRadius = 20
searchControl.layer.borderColor = UIColor.primaryText().cgColor
searchControl.layer.borderWidth = 1
return searchControl
}()
let cancelButton: UIButton = {
let cancelButton = UIButton.init()
cancelButton.titleLabel?.font = UIFont.systemFont(ofSize: 17, weight: .medium)
cancelButton.setTitleColor(.primaryText(), for: .normal)
cancelButton.setTitle("取消", for: .normal)
return cancelButton
@ -114,6 +121,8 @@ class SearchTopBar: UIView {
}
func makeUI() {
backgroundColor = .white
addSubview(searchControl)
addSubview(cancelButton)
}
@ -124,11 +133,14 @@ class SearchTopBar: UIView {
cancelButton.snp.makeConstraints { make in
make.right.equalTo(self).offset(-18)
make.centerY.equalTo(self)
make.width.equalTo(50)
}
searchControl.snp.makeConstraints { make in
make.left.equalTo(self).offset(18)
make.centerY.equalTo(self)
// make.centerY.equalTo(self)
make.top.equalTo(self)
make.bottom.equalTo(self)
make.right.equalTo(cancelButton.snp.left).offset(-12)
}
@ -172,13 +184,31 @@ class SearchNoDataView: UIView {
class SearchResultsView: UIView {
lazy var segmentControl: SegmentControl = {
let segmentControl = SegmentControl.init()
segmentControl.items = ["单曲", "期刊"]
segmentControl.font = UIFont.systemFont(ofSize: 15)
segmentControl.selectedFont = UIFont.systemFont(ofSize: 15)
lazy var segmentControl: ScrollSegmentView = {
var style = SegmentStyle()
style.showLine = true
style.normalTitleColor = UIColor.tertiaryText()
style.selectedTitleColor = UIColor.white
style.backgroundColor = UIColor.white
style.titleSelectFont = UIFont.systemFont(ofSize: 14, weight: .medium)
style.titleFont = UIFont.systemFont(ofSize: 14)
style.scrollLineHeight = 0
style.scrollLineColor = .clear
style.coverBackgroundColor = .init(hex: 0x0d0d0d)
style.normalborderColor = UIColor.tertiaryText()
style.scrollTitle = false
style.showCover = true
// style.scrollTitle = true
// style.lineSpace = 12
let segmentControl = ScrollSegmentView.init(frame: CGRect.init(x: 0, y: 0, width: 200, height: 32), segmentStyle: style, titles: ["单曲", "期刊"])
// segmentControl.scrollView.backgroundColor = .red
return segmentControl
}()
@ -190,8 +220,17 @@ class SearchResultsView: UIView {
}()
let collectionView: UICollectionView = {
let collectionView = UICollectionView.init()
collectionView.isHidden = true
let layout = UICollectionViewFlowLayout()
layout.minimumInteritemSpacing = 15
layout.minimumLineSpacing = 24
layout.sectionInset = UIEdgeInsets.init(top: 0, left: 18, bottom: 0, right: 18)
layout.itemSize = CGSize(width: (BaseDimensions.screenWidth - 18 * 2 - 15) / 2, height: 147)
let collectionView = UICollectionView.init(frame: CGRect.zero, collectionViewLayout: layout)
collectionView.register(MusicStyleCellView.self, forCellWithReuseIdentifier: "MusicStyleCellView")
return collectionView
}()
@ -235,6 +274,8 @@ class SearchResultsView: UIView {
segmentControl.snp.makeConstraints { make in
make.left.equalTo(self).offset(18)
make.top.equalTo(self).offset(0)
make.height.equalTo(32)
make.width.equalTo(200)
}
tableView.snp.makeConstraints { make in

@ -0,0 +1,52 @@
//
// SearchResultsViewModel.swift
// IndieMusic
//
// Created by WenLei on 2024/1/6.
//
import Foundation
import RxSwift
import RxCocoa
class SearchResultsViewModel: ViewModel, ViewModelType {
struct Input {
let viewWillAppear: ControlEvent<Bool>
let selection: Driver<IndexPath>
}
struct Output {
let items: BehaviorRelay<[SearchSection]>
let selection: Driver<IndexPath>
let itemSelected: PublishSubject<Search>
}
let itemSelected = PublishSubject<Search>()
let items = BehaviorRelay<[SearchSection]>.init(value: [])
func transform(input: Input) -> Output {
let search = Search.init(title: "硬核", subTitle: "Hardcore", backgroundImage: "")
let searchSection = SearchSection.init(items: [search, search, search, search, search])
items.accept([searchSection])
input.selection.drive { indexPath in
guard let sectionItem = self.items.value.first?.items[indexPath.row] else { return }
self.itemSelected.onNext(sectionItem)
}.disposed(by: rx.disposeBag)
return Output(items: items,
selection: input.selection,
itemSelected: itemSelected)
}
}

@ -71,8 +71,12 @@ class SearchViewController: ViewController, UIScrollViewDelegate {
output.itemSelected.subscribe { sectionItem in
let musicStyleViewModel = MusicStyleViewModel.init(provider: viewModel.provider)
self.navigator.show(segue: .musicStyle(viewModel: musicStyleViewModel), sender: self)
// let musicStyleViewModel = MusicStyleViewModel.init(provider: viewModel.provider)
// self.navigator.show(segue: .musicStyle(viewModel: musicStyleViewModel), sender: self)
let searchResultsViewModel = SearchResultsViewModel.init(provider: viewModel.provider)
self.navigator.show(segue: .searchResults(viewModel: searchResultsViewModel), sender: self)
}.disposed(by: rx.disposeBag)
}
@ -231,7 +235,7 @@ class SearchHeaderView: UICollectionReusableView {
}
}
class SearchControl: UIControl {
class SearchControl: UIView {
let iconView: UIImageView = {
let iconView = UIImageView.init()
iconView.image = UIImage.init(named: "search_bar_icon")

Loading…
Cancel
Save