Music_Player3/relax.offline.mp3.music/MP/MPPositive/ViewControllers/Search(搜索页)/MPPositive_SearchResultShowViewController.swift
2024-08-09 17:48:28 +08:00

287 lines
11 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// MPPositive_SearchResultShowViewController.swift
// MusicPlayer
//
// Created by Mr.Zhou on 2024/5/12.
//
import UIKit
///
class MPPositive_SearchResultShowViewController: MPPositive_BaseViewController, UIViewControllerTransitioningDelegate {
//MARK: - View
//textField
private lazy var searchTextField:UITextField = {
let textField = UITextField()
textField.delegate = self
textField.font = .systemFont(ofSize: 14*width, weight: .regular)
textField.textColor = .white
//
let attributedText = NSAttributedString(string: "Search songs,artists,playlists", attributes: [.font:UIFont.systemFont(ofSize: 14*width, weight: .regular), .foregroundColor:UIColor(hex: "#666666")])
textField.attributedPlaceholder = attributedText
return textField
}()
//
private lazy var deleteBtn:UIButton = {
let btn:UIButton = .init()
btn.setBackgroundImage(UIImage(named: "Search_Delete'logo"), for: .normal)
btn.addTarget(self, action: #selector(deleteTextClick(_ :)), for: .touchUpInside)
return btn
}()
//cancel
private lazy var cancelBtn:UIButton = {
let btn:UIButton = .init()
btn.setTitle("Cancel", for: .normal)
btn.setTitleColor(.init(hex: "#FFFFFF", alpha: 0.85), for: .normal)
btn.titleLabel?.font = .systemFont(ofSize: 14*width, weight: .regular)
btn.addTarget(self, action: #selector(backPopClick(_ :)), for: .touchUpInside)
return btn
}()
//
private var debounceTimer: Timer?
//
private var suggestionList:MPPositive_SearchSuggestionItemListModel!{
didSet{
DispatchQueue.main.async {
[weak self] in
guard let self = self else {return}
if suggestionList != nil {
//
suggestionView.isHidden = false
suggestionView.suggestions = suggestionList.attributedTexts
MP_AnalyticsManager.shared.search_sug_showAction()
}else {
suggestionView.isHidden = true
suggestionView.suggestions = nil
}
}
}
}
private var isShowAd = true
//
private var searchText:String?
///View
private lazy var historyView:MPPositive_SearchHistoryView = .init(frame: .zero)
///View
private lazy var suggestionView:MPPositive_SearchSuggestionsView = .init(frame: .zero)
///View
private lazy var resultsShowView:MPPositive_SearchResultsShowView = .init(frame: .zero, isShowAd: self.isShowAd)
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
[weak self] in
guard let self = self else {return}
searchTextField.becomeFirstResponder()
}
}
init(_ text:String, isShowAd:Bool = true) {
super.init(nibName: nil, bundle: nil)
self.isShowAd = isShowAd
searchTextField.text = text
searchText = text
resultsShowView.loadModel = .init(text)
MP_AnalyticsManager.shared.search_sug_clickAction(text)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
deinit {
debounceTimer?.invalidate()
debounceTimer = nil
}
override func viewDidLoad() {
super.viewDidLoad()
setTitle("Result")
setPopBtn()
configure()
historyView.selectedTagBlock = {
[weak self] (text) in
guard let self = self else {return}
searchText = text
searchTextField.text = text
resultsShowView.loadModel = .init(text)
MP_AnalyticsManager.shared.search_sug_clickAction(text)
suggestionView.isHidden = true
historyView.isHidden = true
}
suggestionView.selectedTextBlock = {
[weak self] (text) in
guard let self = self else {return}
searchText = text
searchTextField.text = text
resultsShowView.loadModel = .init(text)
MP_AnalyticsManager.shared.search_sug_clickAction(text)
suggestionView.isHidden = true
historyView.isHidden = true
}
resultsShowView.scrollBlock = {
[weak self] in
guard let self = self else {return}
DispatchQueue.main.async {
self.view?.endEditing(true)
}
}
errorBlock = {
[weak self] in
MP_HUD.hideNow()
self?.resultsShowView.isHidden = false
self?.resultsShowView.emptyImageView.isHidden = false
}
}
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
return MPPositive_PresentationController(presentedViewController: presented, presenting: presenting)
}
private func configure() {
//
let searchView = createSearchView()
navView.addSubview(searchView)
searchView.snp.makeConstraints { make in
make.width.equalTo(275*width)
make.height.equalTo(40*width)
make.centerY.equalToSuperview()
make.left.equalToSuperview().offset(18*width)
}
navView.addSubview(cancelBtn)
cancelBtn.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-18*width)
make.centerY.equalToSuperview()
}
//historyView
view.addSubview(historyView)
historyView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.top.equalTo(navView.snp.bottom)
}
historyView.isHidden = false
historyView.reloadHistory()
//suggestionView
view.addSubview(suggestionView)
suggestionView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.top.equalTo(navView.snp.bottom)
}
suggestionView.isHidden = true
//resultsShowView
view.addSubview(resultsShowView)
resultsShowView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.top.equalTo(navView.snp.bottom)
}
resultsShowView.isHidden = true
}
//
private func createSearchView() -> UIView{
let searchView:UIView = UIView()
searchView.backgroundColor = .init(hex: "#000000")
searchView.isUserInteractionEnabled = true
searchView.layer.masksToBounds = true
searchView.layer.cornerRadius = 20*width
//icon
let iconImageView = UIImageView(image: .init(named: "Search_ICON'logo"))
searchView.addSubview(iconImageView)
iconImageView.snp.makeConstraints { make in
make.height.width.equalTo(24*width)
make.left.equalToSuperview().offset(8*width)
make.centerY.equalToSuperview()
}
searchView.addSubview(deleteBtn)
deleteBtn.snp.makeConstraints { make in
make.height.width.equalTo(24*width)
make.right.equalToSuperview().offset(-12*width)
make.centerY.equalToSuperview()
}
//textField
searchView.addSubview(searchTextField)
searchTextField.snp.makeConstraints { make in
make.top.bottom.equalToSuperview()
make.left.equalTo(iconImageView.snp.right).offset(14*width)
make.right.equalTo(deleteBtn.snp.left).offset(-12*width)
}
return searchView
}
//
@objc private func deleteTextClick(_ sender:UIButton) {
//View
searchTextField.text = ""
searchText = ""
suggestionView.suggestions = nil
resultsShowView.loadModel = nil
historyView.isHidden = false
}
//
@objc private func backPopClick(_ sender:UIButton) {
MPPositive_Debouncer.shared.call {
[weak self] in
guard let self = self else {return}
navigationController?.popToRootViewController(animated: false)
}
}
}
//MARK: - UITextFieldDelegate
extension MPPositive_SearchResultShowViewController:UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let text = (textField.text! as NSString).replacingCharacters(in: range, with: string)
guard text.count <= 30 else {
return false
}
//,View
resultsShowView.isHidden = true
historyView.isHidden = true
if text.isEmpty {
self.suggestionList = nil
cancelDebounceTimer()
historyView.isHidden = false
}else {
//
loadSearchSuggestions(text)
}
return true
}
//
private func cancelDebounceTimer() {
debounceTimer?.invalidate()
debounceTimer = nil
}
//
private func loadSearchSuggestions(_ text:String) {
cancelDebounceTimer()
//0.5
debounceTimer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { [weak self] _ in
self?.searchText = text
self?.fetchSearchSuggestions(text)
}
}
//
private func fetchSearchSuggestions(_ text:String) {
MP_NetWorkManager.shared.requestSearchSuggestions(text) { [weak self] (result) in
self?.suggestionList = .init(self?.searchText ?? "", suggestions: result)
}
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
//textField
if let text = textField.text, text.isEmpty != true {
MPPositive_Debouncer.shared.call {
[weak self] in
guard let self = self else {return}
self.searchText = text
//
resultsShowView.loadModel = .init(text)
MP_AnalyticsManager.shared.search_sug_clickAction(text)
suggestionView.isHidden = true
//
view.endEditing(true)
}
return true
}else {
return false
}
}
}