搜索页面开发
This commit is contained in:
parent
a2c6c0cc16
commit
06122c3142
@ -18,6 +18,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
SPLoginManager.manager.requestVisitorLogin(completer: nil)
|
||||
|
||||
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,11 @@ extension UIColor {
|
||||
static func themeColor() -> UIColor {
|
||||
return color000000()
|
||||
}
|
||||
//
|
||||
// static func placeholderColor() -> UIColor {
|
||||
// return color868C92()
|
||||
// }
|
||||
|
||||
|
||||
static func placeholderColor() -> UIColor {
|
||||
return .colorFFFFFF(alpha: 0.22)
|
||||
}
|
||||
}
|
||||
|
||||
extension UIColor {
|
||||
|
@ -43,7 +43,7 @@ class SPVideoAPI: NSObject {
|
||||
}
|
||||
|
||||
///收藏短剧
|
||||
static func requestCollectShort(isCollect: Bool, shortPlayId: String, success: (() -> Void)?) {
|
||||
static func requestCollectShort(isCollect: Bool, shortPlayId: String, videoId: String, success: (() -> Void)?) {
|
||||
let path: String
|
||||
if isCollect {
|
||||
path = "/collect"
|
||||
@ -54,7 +54,8 @@ class SPVideoAPI: NSObject {
|
||||
var param = SPNetworkParameters(path: path)
|
||||
param.isLoding = true
|
||||
param.parameters = [
|
||||
"short_play_id" : shortPlayId
|
||||
"short_play_id" : shortPlayId,
|
||||
"video_id" : videoId
|
||||
]
|
||||
|
||||
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<String>) in
|
||||
|
142
ShortPlay/Base/View/SPTextField.swift
Normal file
142
ShortPlay/Base/View/SPTextField.swift
Normal file
@ -0,0 +1,142 @@
|
||||
//
|
||||
// SPTextField.swift
|
||||
// ShortPlay
|
||||
//
|
||||
// Created by 曾觉新 on 2025/4/17.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SPTextField: UITextField {
|
||||
|
||||
///0 不限制字数
|
||||
var maxNumber = 0
|
||||
|
||||
var currentNumber = 0
|
||||
|
||||
///是否为手机格式
|
||||
var isPhone: Bool = false
|
||||
|
||||
var textDidChange: ((_ text: String) -> Void)?
|
||||
|
||||
var sp_placeholder: String? {
|
||||
set {
|
||||
_createAttributedPlaceholder()
|
||||
let newStr = NSMutableAttributedString(string: newValue ?? "")
|
||||
newStr.font = self.sp_placeholderFont
|
||||
newStr.color = self.sp_placeholderColor
|
||||
_attributedPlaceholder = newStr
|
||||
self.attributedPlaceholder = _attributedPlaceholder
|
||||
}
|
||||
get {
|
||||
return _attributedPlaceholder?.string
|
||||
}
|
||||
}
|
||||
|
||||
var sp_placeholderFont: UIFont? {
|
||||
|
||||
set {
|
||||
_createAttributedPlaceholder()
|
||||
_attributedPlaceholder?.font = newValue
|
||||
self.attributedPlaceholder = _attributedPlaceholder
|
||||
}
|
||||
get {
|
||||
if let font = _attributedPlaceholder?.font {
|
||||
return font
|
||||
} else {
|
||||
return self.font
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var sp_placeholderColor: UIColor? {
|
||||
set {
|
||||
_createAttributedPlaceholder()
|
||||
_attributedPlaceholder?.color = newValue
|
||||
self.attributedPlaceholder = _attributedPlaceholder
|
||||
}
|
||||
get {
|
||||
if let color = _attributedPlaceholder?.color {
|
||||
return color
|
||||
} else {
|
||||
return .placeholderColor()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var _attributedPlaceholder: NSMutableAttributedString?
|
||||
|
||||
|
||||
private func _createAttributedPlaceholder() {
|
||||
if self._attributedPlaceholder == nil {
|
||||
_attributedPlaceholder = NSMutableAttributedString(string: "")
|
||||
_attributedPlaceholder?.font = self.font
|
||||
_attributedPlaceholder?.color = .placeholderColor()
|
||||
self.attributedPlaceholder = _attributedPlaceholder
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(textDidChangeNotification(sender:)), name: UITextField.textDidChangeNotification, object: nil)
|
||||
|
||||
// var iq = self.iq
|
||||
// iq.enableMode = .enabled
|
||||
|
||||
self.textColor = .colorFFFFFF(alpha: 0.9)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SPTextField {
|
||||
|
||||
@objc func textDidChangeNotification(sender: Notification){
|
||||
|
||||
guard let object = sender.object else { return }
|
||||
if !(object is UITextField) {return}
|
||||
if (object as! UITextField) != self {return}
|
||||
|
||||
|
||||
let selectedRange: UITextRange? = self.markedTextRange
|
||||
|
||||
|
||||
if selectedRange == nil {
|
||||
|
||||
if !self.isPhone {
|
||||
if maxNumber > 0 {
|
||||
if self.text?.count ?? 0 > self.maxNumber {
|
||||
var string = self.text
|
||||
string?.removeLast(self.text!.count - self.maxNumber)
|
||||
self.text = string
|
||||
}
|
||||
}
|
||||
if let textDidChange = textDidChange {
|
||||
textDidChange(self.text ?? "")
|
||||
}
|
||||
} else {
|
||||
// var newString = self.text?.replacingOccurrences(of: " ", with: "") ?? ""
|
||||
//
|
||||
// if newString.count > self.maxNumber {
|
||||
// newString.removeLast(newString.count - self.maxNumber)
|
||||
// }
|
||||
//
|
||||
// self.text = newString.formatToPhone()
|
||||
// if let textDidChange = textDidChange {
|
||||
// textDidChange(newString)
|
||||
// }
|
||||
}
|
||||
|
||||
self.currentNumber = self.text?.count ?? 0
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,12 @@ class SPHomePageController: SPViewController {
|
||||
return arr
|
||||
}()
|
||||
|
||||
private lazy var searchButton: SPHomeSearchButton = {
|
||||
let button = SPHomeSearchButton()
|
||||
button.addTarget(self, action: #selector(handleSearchButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var pageView: JYPageController = {
|
||||
let customIndicatorImage = UIImage(named: "page_indicator_icon_01")
|
||||
let customIndicator = UIImageView(image: customIndicatorImage)
|
||||
@ -68,14 +74,31 @@ extension SPHomePageController {
|
||||
private func sp_setupUI() {
|
||||
addChild(pageView)
|
||||
view.addSubview(pageView.view)
|
||||
view.addSubview(searchButton)
|
||||
|
||||
pageView.view.snp.makeConstraints { make in
|
||||
// make.edges.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(kSPStatusbarHeight + 66)
|
||||
make.left.right.bottom.equalToSuperview()
|
||||
}
|
||||
|
||||
searchButton.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(15)
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(kSPStatusbarHeight + 10)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SPHomePageController {
|
||||
|
||||
@objc private func handleSearchButton() {
|
||||
let vc = SPSearchViewController()
|
||||
self.navigationController?.pushViewController(vc, animated: true)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//MARK: -------------- JYPageControllerDelegate & JYPageControllerDataSource --------------
|
||||
extension SPHomePageController: JYPageControllerDelegate, JYPageControllerDataSource {
|
||||
|
72
ShortPlay/Class/Home/Controller/SPSearchViewController.swift
Normal file
72
ShortPlay/Class/Home/Controller/SPSearchViewController.swift
Normal file
@ -0,0 +1,72 @@
|
||||
//
|
||||
// SPSearchViewController.swift
|
||||
// ShortPlay
|
||||
//
|
||||
// Created by 曾觉新 on 2025/4/17.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SPSearchViewController: SPViewController {
|
||||
|
||||
private lazy var backButton: UIButton = {
|
||||
let button = UIButton(type: .custom)
|
||||
button.setImage(UIImage(named: "arrow_left_icon_01"), for: .normal)
|
||||
button.addTarget(self, action: #selector(handleBack), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var searchInputView: SPSearchInputView = {
|
||||
let view = SPSearchInputView()
|
||||
view.textField.delegate = self
|
||||
return view
|
||||
}()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
_setupUI()
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
self.navigationController?.setNavigationBarHidden(true, animated: true)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension SPSearchViewController {
|
||||
|
||||
private func _setupUI() {
|
||||
view.addSubview(backButton)
|
||||
view.addSubview(searchInputView)
|
||||
|
||||
backButton.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(5)
|
||||
make.centerY.equalTo(searchInputView)
|
||||
make.width.height.equalTo(37)
|
||||
}
|
||||
|
||||
searchInputView.snp.makeConstraints { make in
|
||||
make.right.equalToSuperview().offset(-15)
|
||||
make.top.equalToSuperview().offset(kSPStatusbarHeight + 10)
|
||||
make.left.equalTo(backButton.snp.right).offset(5)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//MARK: -------------- UITextFieldDelegate --------------
|
||||
extension SPSearchViewController: UITextFieldDelegate {
|
||||
|
||||
func textFieldDidBeginEditing(_ textField: UITextField) {
|
||||
spLog(message: "开始编辑")
|
||||
}
|
||||
|
||||
func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {
|
||||
spLog(message: "结束编辑")
|
||||
}
|
||||
|
||||
}
|
50
ShortPlay/Class/Home/View/SPHomeSearchButton.swift
Normal file
50
ShortPlay/Class/Home/View/SPHomeSearchButton.swift
Normal file
@ -0,0 +1,50 @@
|
||||
//
|
||||
// SPHomeSearchButton.swift
|
||||
// ShortPlay
|
||||
//
|
||||
// Created by 曾觉新 on 2025/4/17.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SPHomeSearchButton: UIControl {
|
||||
|
||||
|
||||
override var intrinsicContentSize: CGSize {
|
||||
return CGSize(width: kSPScreenWidth, height: 38)
|
||||
}
|
||||
|
||||
private lazy var iconImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: UIImage(named: "search_icon_01"))
|
||||
return imageView
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
layer.cornerRadius = 19
|
||||
layer.masksToBounds = true
|
||||
|
||||
backgroundColor = .colorFFFFFF(alpha: 0.1)
|
||||
|
||||
_setupUI()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SPHomeSearchButton {
|
||||
|
||||
private func _setupUI() {
|
||||
addSubview(iconImageView)
|
||||
|
||||
iconImageView.snp.makeConstraints { make in
|
||||
make.centerY.equalToSuperview()
|
||||
make.left.equalToSuperview().offset(15)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
14
ShortPlay/Class/Home/View/SPSearchHomeView.swift
Normal file
14
ShortPlay/Class/Home/View/SPSearchHomeView.swift
Normal file
@ -0,0 +1,14 @@
|
||||
//
|
||||
// SPSearchHomeView.swift
|
||||
// ShortPlay
|
||||
//
|
||||
// Created by 曾觉新 on 2025/4/17.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SPSearchHomeView: UIView {
|
||||
|
||||
|
||||
|
||||
}
|
70
ShortPlay/Class/Home/View/SPSearchInputView.swift
Normal file
70
ShortPlay/Class/Home/View/SPSearchInputView.swift
Normal file
@ -0,0 +1,70 @@
|
||||
//
|
||||
// SPSearchInputView.swift
|
||||
// ShortPlay
|
||||
//
|
||||
// Created by 曾觉新 on 2025/4/17.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SPSearchInputView: UIView {
|
||||
|
||||
override var intrinsicContentSize: CGSize {
|
||||
return CGSize(width: kSPScreenWidth, height: 38)
|
||||
}
|
||||
|
||||
var placeholder: String? {
|
||||
didSet {
|
||||
textField.sp_placeholder = placeholder
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: UI属性
|
||||
private lazy var iconImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: UIImage(named: "search_icon_02"))
|
||||
imageView.setContentHuggingPriority(.required, for: .horizontal)
|
||||
imageView.setContentCompressionResistancePriority(.required, for: .horizontal)
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private(set) lazy var textField: SPTextField = {
|
||||
let textField = SPTextField()
|
||||
textField.font = .fontRegular(ofSize: 12)
|
||||
return textField
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
layer.cornerRadius = 19
|
||||
layer.masksToBounds = true
|
||||
backgroundColor = .colorFFFFFF(alpha: 0.1)
|
||||
|
||||
_setupUI()
|
||||
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SPSearchInputView {
|
||||
|
||||
private func _setupUI() {
|
||||
addSubview(iconImageView)
|
||||
addSubview(textField)
|
||||
|
||||
iconImageView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(15)
|
||||
make.centerY.equalToSuperview()
|
||||
}
|
||||
|
||||
textField.snp.makeConstraints { make in
|
||||
make.top.bottom.equalToSuperview()
|
||||
make.left.equalTo(iconImageView.snp.right).offset(7)
|
||||
make.right.equalToSuperview().offset(-15)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -203,10 +203,11 @@ extension SPPlayerControlView {
|
||||
|
||||
@objc private func handleCollectButton() {
|
||||
guard let shortPlayId = self.videoInfo?.short_play_id else { return }
|
||||
guard let videoId = self.videoInfo?.short_play_video_id else { return }
|
||||
|
||||
let isCollect = !(self.shortModel?.is_collect ?? false)
|
||||
|
||||
SPVideoAPI.requestCollectShort(isCollect: isCollect, shortPlayId: shortPlayId) {
|
||||
SPVideoAPI.requestCollectShort(isCollect: isCollect, shortPlayId: shortPlayId, videoId: videoId) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,8 +37,6 @@ extension SPLoginManager {
|
||||
return
|
||||
}
|
||||
isRefreshingToken = true
|
||||
// var loding = true
|
||||
|
||||
let param = SPNetworkParameters(path: "/customer/register")
|
||||
SPNetwork.request(parameters: param) { [weak self] (response: SPNetworkResponse<SPTokenModel>) in
|
||||
guard let self = self else { return }
|
||||
@ -46,12 +44,58 @@ extension SPLoginManager {
|
||||
self.setLoginToken(token: token)
|
||||
}
|
||||
self.isRefreshingToken = false
|
||||
// loding = false
|
||||
completer?()
|
||||
}
|
||||
|
||||
// while loding {
|
||||
// RunLoop.current.run(mode: .default, before: Date.distantFuture)
|
||||
}
|
||||
|
||||
func performDependentRequestsWithOperations() {
|
||||
let queue = OperationQueue()
|
||||
|
||||
// 1. 创建初始请求操作
|
||||
let initialOperation = BlockOperation {
|
||||
let semaphore = DispatchSemaphore(value: 0)
|
||||
|
||||
// initialRequest { result in
|
||||
// defer { semaphore.signal() }
|
||||
//
|
||||
// if result.isSuccess {
|
||||
// print("初始请求成功")
|
||||
// }
|
||||
// }
|
||||
|
||||
semaphore.wait()
|
||||
}
|
||||
|
||||
// 2. 创建依赖操作
|
||||
let request1Operation = BlockOperation {
|
||||
let semaphore = DispatchSemaphore(value: 0)
|
||||
|
||||
// request1 {
|
||||
// print("请求1完成")
|
||||
// semaphore.signal()
|
||||
// }
|
||||
|
||||
semaphore.wait()
|
||||
}
|
||||
|
||||
let request2Operation = BlockOperation {
|
||||
let semaphore = DispatchSemaphore(value: 0)
|
||||
|
||||
// request2 {
|
||||
// print("请求2完成")
|
||||
// semaphore.signal()
|
||||
// }
|
||||
|
||||
semaphore.wait()
|
||||
}
|
||||
|
||||
// 3. 设置依赖关系
|
||||
request1Operation.addDependency(initialOperation)
|
||||
request2Operation.addDependency(initialOperation)
|
||||
|
||||
// 4. 添加操作到队列
|
||||
queue.addOperations([initialOperation, request1Operation, request2Operation], waitUntilFinished: false)
|
||||
}
|
||||
|
||||
}
|
||||
|
22
ShortPlay/Source/Assets.xcassets/icon/search_icon_01.imageset/Contents.json
vendored
Normal file
22
ShortPlay/Source/Assets.xcassets/icon/search_icon_01.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "搜索图标@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "搜索图标@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
ShortPlay/Source/Assets.xcassets/icon/search_icon_01.imageset/搜索图标@2x.png
vendored
Normal file
BIN
ShortPlay/Source/Assets.xcassets/icon/search_icon_01.imageset/搜索图标@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
ShortPlay/Source/Assets.xcassets/icon/search_icon_01.imageset/搜索图标@3x.png
vendored
Normal file
BIN
ShortPlay/Source/Assets.xcassets/icon/search_icon_01.imageset/搜索图标@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
22
ShortPlay/Source/Assets.xcassets/icon/search_icon_02.imageset/Contents.json
vendored
Normal file
22
ShortPlay/Source/Assets.xcassets/icon/search_icon_02.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "搜索图标@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "搜索图标@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
ShortPlay/Source/Assets.xcassets/icon/search_icon_02.imageset/搜索图标@2x.png
vendored
Normal file
BIN
ShortPlay/Source/Assets.xcassets/icon/search_icon_02.imageset/搜索图标@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1000 B |
BIN
ShortPlay/Source/Assets.xcassets/icon/search_icon_02.imageset/搜索图标@3x.png
vendored
Normal file
BIN
ShortPlay/Source/Assets.xcassets/icon/search_icon_02.imageset/搜索图标@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
Loading…
x
Reference in New Issue
Block a user