滑动返回优化
This commit is contained in:
parent
067bba0814
commit
6ecceff7a9
@ -51,11 +51,13 @@ struct NRNovelAPI {
|
||||
|
||||
///上报阅读记录
|
||||
static func requestUploadRecord(_ id: String, chapterId: String) {
|
||||
var param = NRNetwork.Parameters(path: "/novel/watchProgressReport")
|
||||
// var param = NRNetwork.Parameters(path: "/novel/watchProgressReport")
|
||||
var param = NRNetwork.Parameters(path: "/createHistory")
|
||||
param.isToast = false
|
||||
param.parameters = [
|
||||
"short_play_id" : id,
|
||||
"short_play_video_id" : chapterId
|
||||
// "short_play_video_id" : chapterId
|
||||
"video_id" : chapterId
|
||||
]
|
||||
|
||||
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<String>) in
|
||||
|
||||
@ -34,10 +34,22 @@ class NRProgressView: UIView {
|
||||
///滑动进度
|
||||
private var panProgress: CGFloat = 0
|
||||
|
||||
var progressColor: UIColor = .black.withAlphaComponent(0.25)
|
||||
var currentProgress: UIColor = .F_9710_D
|
||||
var progressColor: UIColor = .black.withAlphaComponent(0.25) {
|
||||
didSet {
|
||||
setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
var currentProgress: UIColor = .F_9710_D {
|
||||
didSet {
|
||||
setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
var lineWidth: CGFloat = 4
|
||||
var lineWidth: CGFloat = 4 {
|
||||
didSet {
|
||||
setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
///加载中状态
|
||||
var isLoading = false {
|
||||
@ -53,7 +65,11 @@ class NRProgressView: UIView {
|
||||
}
|
||||
}
|
||||
|
||||
var thumbImage: UIImage?
|
||||
var thumbImage: UIImage? {
|
||||
didSet {
|
||||
setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
var insets: UIEdgeInsets = .init(top: 0, left: 15, bottom: 0, right: 15) {
|
||||
didSet {
|
||||
|
||||
@ -7,7 +7,21 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
protocol NRScrollViewDelegate: AnyObject {
|
||||
func nr_gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool?
|
||||
}
|
||||
|
||||
|
||||
extension NRScrollViewDelegate {
|
||||
func nr_gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool? {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
class NRScrollView: UIScrollView {
|
||||
|
||||
weak var nr_delegate: NRScrollViewDelegate?
|
||||
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
@ -17,5 +31,25 @@ class NRScrollView: UIScrollView {
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
}
|
||||
|
||||
|
||||
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||
if let result = self.nr_delegate?.nr_gestureRecognizerShouldBegin(gestureRecognizer) {
|
||||
return result
|
||||
}
|
||||
let result = super.gestureRecognizerShouldBegin(gestureRecognizer)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
class NRPagerScrollView: NRScrollView {
|
||||
|
||||
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||
let result = super.gestureRecognizerShouldBegin(gestureRecognizer)
|
||||
guard let panGestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer else { return result }
|
||||
let translation = panGestureRecognizer.translation(in: self)
|
||||
if translation.x > 0, self.contentOffset.x == 0 {
|
||||
return false
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,7 +55,18 @@ class NRTableView: UITableView, UIGestureRecognizerDelegate {
|
||||
}
|
||||
|
||||
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||
return shouldRecognizeSimultaneously
|
||||
guard shouldRecognizeSimultaneously else { return false }
|
||||
guard gestureRecognizer.isKind(of: UIPanGestureRecognizer.self) && otherGestureRecognizer.isKind(of: UIPanGestureRecognizer.self) else { return false }
|
||||
|
||||
var superview = otherGestureRecognizer.view
|
||||
|
||||
while superview != nil {
|
||||
if superview == self {
|
||||
return true
|
||||
}
|
||||
superview = superview?.superview
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -101,6 +101,7 @@ extension NRNovelGenresCell {
|
||||
|
||||
categoryView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview()
|
||||
make.right.lessThanOrEqualToSuperview()
|
||||
make.bottom.equalToSuperview()
|
||||
}
|
||||
|
||||
|
||||
@ -12,12 +12,14 @@ class NRHomeCategoryTagView: UIView {
|
||||
|
||||
|
||||
override var intrinsicContentSize: CGSize {
|
||||
return .init(width: 10, height: 20)
|
||||
let textWidth = self.categoryLabel.sizeThatFits(.init(width: UIScreen.width - 50, height: 20)).width
|
||||
return .init(width: textWidth + 16, height: 20)
|
||||
}
|
||||
|
||||
var text: String? {
|
||||
set {
|
||||
categoryLabel.text = newValue
|
||||
self.invalidateIntrinsicContentSize()
|
||||
}
|
||||
get {
|
||||
return categoryLabel.text
|
||||
|
||||
@ -100,6 +100,7 @@ extension NRHomeNovelListCell {
|
||||
categooryView.snp.makeConstraints { make in
|
||||
make.bottom.equalToSuperview()
|
||||
make.left.equalToSuperview()
|
||||
make.right.lessThanOrEqualToSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -114,6 +114,7 @@ extension NRHomeNovelListTextCell {
|
||||
|
||||
categoryLabel.snp.makeConstraints { make in
|
||||
make.left.equalTo(nameLabel)
|
||||
make.right.lessThanOrEqualToSuperview().offset(-8)
|
||||
make.bottom.equalTo(coverImageView).offset(-7)
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,6 +138,7 @@ extension NRHomeNovelMustReadTodayCell {
|
||||
|
||||
categoryView.snp.makeConstraints { make in
|
||||
make.left.equalTo(coverImageView.snp.right).offset(12)
|
||||
make.right.lessThanOrEqualToSuperview().offset(-12)
|
||||
make.top.equalTo(coverImageView)
|
||||
make.height.equalTo(20)
|
||||
}
|
||||
|
||||
@ -114,6 +114,7 @@ extension NRHomeNovelNextViewCell {
|
||||
|
||||
categoryView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview()
|
||||
make.right.lessThanOrEqualToSuperview()
|
||||
// make.top.equalTo(titleLabel.snp.bottom).offset(4)
|
||||
make.bottom.equalToSuperview()
|
||||
make.height.equalTo(20)
|
||||
|
||||
@ -122,6 +122,7 @@ extension NRNovelHistoryCell {
|
||||
|
||||
categoryView.snp.makeConstraints { make in
|
||||
make.left.equalTo(titleLabel)
|
||||
make.right.lessThanOrEqualToSuperview().offset(60)
|
||||
make.bottom.equalToSuperview().offset(-7.5)
|
||||
}
|
||||
|
||||
|
||||
@ -47,6 +47,7 @@ class NRDetailRechargeView: NRPanModalContentView {
|
||||
didSet {
|
||||
coinsView.shortPlayId = worksId
|
||||
vipView.shortPlayId = worksId
|
||||
self.requestRestore()
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,6 +55,7 @@ class NRDetailRechargeView: NRPanModalContentView {
|
||||
didSet {
|
||||
coinsView.videoId = chapterId
|
||||
vipView.videoId = chapterId
|
||||
self.requestRestore()
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,6 +94,10 @@ class NRDetailRechargeView: NRPanModalContentView {
|
||||
private lazy var closeButton: UIButton = {
|
||||
let button = UIButton(type: .custom, primaryAction: UIAction(handler: { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
NRStatAPI.nr_requestEventStat(orderCode: nil, shortPlayId: self.worksId, videoId: self.chapterId, eventKey: .payTemplateDialog, errorMsg: nil, otherParamenters: [
|
||||
"event_name" : "pay cancel"
|
||||
])
|
||||
|
||||
Task {
|
||||
await self.dismiss(animated: true)
|
||||
}
|
||||
@ -226,3 +232,23 @@ extension NRDetailRechargeView {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension NRDetailRechargeView {
|
||||
|
||||
@objc private func requestRestore() {
|
||||
guard let shortPlayId = self.worksId, let videoId = self.chapterId else { return }
|
||||
|
||||
NRIapManager.manager.restore(isLoding: false, shortPlayId: shortPlayId, videoId: videoId) { [weak self] isFinish, buyType in
|
||||
if isFinish {
|
||||
Task {
|
||||
await NRLoginManager.manager.updateUserInfo()
|
||||
}
|
||||
self?.buyFinishHandle?()
|
||||
Task {
|
||||
await self?.dismiss(animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -19,8 +19,20 @@ extension NRNovelDetailHeaderView {
|
||||
|
||||
stackView.nr_removeAllArrangedSubview()
|
||||
|
||||
model?.category?.forEach {
|
||||
if let view = self.createCategoryView($0) {
|
||||
var categoryTotalWidth: CGFloat = 0
|
||||
let categoryArr = model?.category ?? []
|
||||
for text in categoryArr {
|
||||
if let view = self.createCategoryView(text) {
|
||||
nrPrint(message: view.intrinsicContentSize)
|
||||
let viewWidth = view.intrinsicContentSize.width
|
||||
if categoryTotalWidth == 0 {
|
||||
categoryTotalWidth += viewWidth
|
||||
} else {
|
||||
categoryTotalWidth += (viewWidth + self.stackView.spacing)
|
||||
}
|
||||
if categoryTotalWidth > UIScreen.width - 32 {
|
||||
break
|
||||
}
|
||||
self.stackView.addArrangedSubview(view)
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +42,8 @@ class NRNovelDetailHeaderView: UIView {
|
||||
heatsDataView.num = CGFloat(model?.heats ?? 0)
|
||||
wordDataView.num = CGFloat(model?.words ?? 0)
|
||||
rateDataView.num = model?.rate ?? 0
|
||||
|
||||
contentsMoreButton.setNeedsUpdateConfiguration()
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,9 +146,9 @@ class NRNovelDetailHeaderView: UIView {
|
||||
}
|
||||
}))
|
||||
button.isHidden = true
|
||||
button.setImage(UIImage(named: "arrow_bown_icon_01"), for: .normal)
|
||||
button.setImage(UIImage(named: "arrow_right_icon_01"), for: .selected)
|
||||
button.setImage(UIImage(named: "arrow_right_icon_01"), for: [.selected, .highlighted])
|
||||
button.setImage(UIImage(named: "arrow_right_icon_01"), for: .normal)
|
||||
button.setImage(UIImage(named: "arrow_bown_icon_01"), for: .selected)
|
||||
button.setImage(UIImage(named: "arrow_bown_icon_01"), for: [.selected, .highlighted])
|
||||
return button
|
||||
}()
|
||||
|
||||
@ -187,10 +189,6 @@ class NRNovelDetailHeaderView: UIView {
|
||||
configuration.image = UIImage(named: "arrow_right_icon_04")
|
||||
configuration.imagePadding = 0
|
||||
configuration.imagePlacement = .trailing
|
||||
configuration.attributedTitle = AttributedString("Completed".localized, attributes: AttributeContainer([
|
||||
.font : UIFont.font(ofSize: 12, weight: .regular),
|
||||
.foregroundColor : UIColor.black.withAlphaComponent(0.5)
|
||||
]))
|
||||
|
||||
let button = UIButton(configuration: configuration, primaryAction: UIAction(handler: { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
@ -198,6 +196,17 @@ class NRNovelDetailHeaderView: UIView {
|
||||
vc.novelModel = self.model
|
||||
self.viewController?.navigationController?.pushViewController(vc, animated: true)
|
||||
}))
|
||||
|
||||
button.configurationUpdateHandler = { [weak self] button in
|
||||
guard let self = self else { return }
|
||||
button.configuration?.attributedTitle = AttributedString("Completed".localized, attributes: AttributeContainer([
|
||||
// button.configuration?.attributedTitle = AttributedString(self.model?.process ?? "", attributes: AttributeContainer([
|
||||
.font : UIFont.font(ofSize: 12, weight: .regular),
|
||||
.foregroundColor : UIColor.black.withAlphaComponent(0.5)
|
||||
]))
|
||||
|
||||
}
|
||||
|
||||
return button
|
||||
}()
|
||||
|
||||
|
||||
@ -265,10 +265,12 @@ class NRNovelReadBottomView: UIView {
|
||||
prevButton.setTitleColor(.white, for: .normal)
|
||||
nextButton.setTitleColor(.white, for: .normal)
|
||||
contentView.backgroundColor = ._36353_A
|
||||
progressView.progressColor = .white.withAlphaComponent(0.25)
|
||||
} else {
|
||||
prevButton.setTitleColor(.black, for: .normal)
|
||||
nextButton.setTitleColor(.black, for: .normal)
|
||||
contentView.backgroundColor = .white
|
||||
progressView.progressColor = .black.withAlphaComponent(0.25)
|
||||
}
|
||||
catalogButton.setNeedsUpdateConfiguration()
|
||||
nightButton.setNeedsUpdateConfiguration()
|
||||
|
||||
@ -18,7 +18,7 @@ class NRNovelReadGradeView: NRPanModalContentView {
|
||||
nameLabel.text = model?.name
|
||||
|
||||
starView.grade = (model?.rate ?? 0) / 2
|
||||
starView.text = NSNumber(value: model?.rate ?? 0).toString(maximumFractionDigits: 1)
|
||||
starView.text = NSNumber(value: model?.rate ?? 0).toString(maximumFractionDigits: 1, minimumFractionDigits: 1)
|
||||
|
||||
if let text = model?.category?.first, text.count > 0 {
|
||||
categoryView.isHidden = false
|
||||
|
||||
@ -25,8 +25,8 @@ class NRNovelReadStarGradeView: UIView {
|
||||
gradeView.updateOnTouch = true
|
||||
gradeView.fillMode = .full
|
||||
} else {
|
||||
label.text = "My Rate:##".localizedReplace(text: NSNumber(value: self_rate).toString())
|
||||
gradeView.grade = self_rate
|
||||
label.text = "My Rate:##".localizedReplace(text: NSNumber(value: self_rate).toString(maximumFractionDigits: 1, minimumFractionDigits: 1))
|
||||
gradeView.grade = self_rate / 2
|
||||
gradeView.updateOnTouch = false
|
||||
gradeView.fillMode = .precise
|
||||
}
|
||||
@ -84,7 +84,7 @@ class NRNovelReadStarGradeView: UIView {
|
||||
guard let id = self.model?.id else { return }
|
||||
Task {
|
||||
guard await NRNovelAPI.requestRateScore(id, stars: CGFloat(grade)) else { return}
|
||||
self.model?.self_rate = grade
|
||||
self.model?.self_rate = grade * 2
|
||||
gradeView.isHidden = true
|
||||
label.isHidden = true
|
||||
finishView.isHidden = false
|
||||
|
||||
@ -44,8 +44,6 @@ class NRNovelReadView: UIView {
|
||||
// 正常使用
|
||||
backgroundColor = UIColor.clear
|
||||
|
||||
// 可以修改为随机颜色便于调试范围
|
||||
// backgroundColor = DZM_COLOR_ARC
|
||||
}
|
||||
|
||||
/// 绘制
|
||||
|
||||
@ -17,14 +17,13 @@ class NRNovelDetailCatalogViewController: NRViewController {
|
||||
|
||||
totalChaptersLabel.text = "## Chapters".localizedReplace(text: "\(novelModel?.episode_total ?? 0)")
|
||||
|
||||
Task {
|
||||
await requestDataArr()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lazy var dataArr: [NRReadChapterCatalogModel] = []
|
||||
|
||||
var isViewDidAppear = false
|
||||
|
||||
|
||||
private lazy var lineView: UIView = {
|
||||
let view = UIView()
|
||||
@ -70,6 +69,10 @@ class NRNovelDetailCatalogViewController: NRViewController {
|
||||
configNavigationBack("arrow_left_icon_05")
|
||||
|
||||
nr_setupUI()
|
||||
|
||||
Task {
|
||||
await requestDataArr()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -79,7 +82,17 @@ class NRNovelDetailCatalogViewController: NRViewController {
|
||||
self.nr_setNavigationStyle(titleColor: UINavigationBar.titleBlackColor)
|
||||
}
|
||||
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
if isViewDidAppear {
|
||||
Task {
|
||||
await requestDataArr()
|
||||
}
|
||||
} else {
|
||||
isViewDidAppear = true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -203,11 +203,10 @@ extension NRNovelReaderViewController {
|
||||
}
|
||||
|
||||
let indexPath = self.indexPathToReadRecord()
|
||||
let section = indexPath.section
|
||||
|
||||
self.viewModel.currentPageIndexPath = indexPath
|
||||
|
||||
let currentCatalogModel = self.viewModel.chapterCatalogList[section]
|
||||
let currentCatalogModel = self.viewModel.chapterCatalogList[indexPath.section]
|
||||
|
||||
//获取章节数据
|
||||
await self.viewModel.requestChapterData(currentCatalogModel)
|
||||
@ -225,8 +224,6 @@ extension NRNovelReaderViewController {
|
||||
//读取历史记录
|
||||
let recordModel = self.viewModel.getReadRecord()
|
||||
|
||||
var tempCatalogModel: NRReadChapterCatalogModel?
|
||||
|
||||
//匹配历史记录的索引
|
||||
var section = 0
|
||||
var row = 0
|
||||
@ -234,7 +231,6 @@ extension NRNovelReaderViewController {
|
||||
for (index, model) in self.viewModel.chapterCatalogList.enumerated() {
|
||||
if model.id == catalogModel.id {
|
||||
section = index
|
||||
tempCatalogModel = model
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -243,6 +239,8 @@ extension NRNovelReaderViewController {
|
||||
}
|
||||
self.targetCatalogModel = nil
|
||||
} else {
|
||||
var tempCatalogModel: NRReadChapterCatalogModel?
|
||||
|
||||
if let recordModel = recordModel {
|
||||
for (index, model) in self.viewModel.chapterCatalogList.enumerated() {
|
||||
if model.id == recordModel.short_play_video_id {
|
||||
@ -254,21 +252,23 @@ extension NRNovelReaderViewController {
|
||||
if let page = recordModel.page {
|
||||
row = page
|
||||
}
|
||||
|
||||
//如果当前剧集已上锁,需要找到最近已解锁章节
|
||||
if tempCatalogModel?.is_lock == true {
|
||||
var tempIndex = 0
|
||||
for (index, model) in self.viewModel.chapterCatalogList.enumerated() {
|
||||
if model.is_lock == true {
|
||||
break
|
||||
}
|
||||
tempIndex = index
|
||||
}
|
||||
section = tempIndex
|
||||
row = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//如果当前剧集已上锁,需要找到最近已解锁章节
|
||||
if tempCatalogModel?.is_lock == true {
|
||||
var tempIndex = 0
|
||||
for (index, model) in self.viewModel.chapterCatalogList.enumerated() {
|
||||
if model.is_lock == true {
|
||||
break
|
||||
}
|
||||
tempIndex = index
|
||||
}
|
||||
section = tempIndex
|
||||
row = 0
|
||||
}
|
||||
|
||||
|
||||
return IndexPath(row: row, section: section)
|
||||
}
|
||||
|
||||
@ -167,7 +167,7 @@ extension NRNovelReadViewModel {
|
||||
let lastTime = uploadRecordDate?.timeIntervalSince1970 ?? 0
|
||||
let nowTime = Date().timeIntervalSince1970
|
||||
|
||||
if lastTime == 0 || nowTime - lastTime > 5 {//间隔5秒才能上传一次记录
|
||||
if lastTime == 0 || nowTime - lastTime > 1 {//间隔5秒才能上传一次记录
|
||||
uploadRecordDate = Date()
|
||||
NRNovelAPI.requestUploadRecord(novelId, chapterId: catalogModel.id ?? "")
|
||||
}
|
||||
|
||||
@ -186,6 +186,9 @@ extension NRNovelReadViewModel {
|
||||
private func _openRechargeView(_ payModel: NRPayDateModel, _ catalogModel: NRReadChapterCatalogModel) {
|
||||
guard self.popView == nil else { return }
|
||||
|
||||
NRStatAPI.nr_requestEventStat(orderCode: nil, shortPlayId: self.novelId, videoId: catalogModel.id, eventKey: .payTemplateDialog, errorMsg: nil, otherParamenters: [
|
||||
"event_name" : "pay open"
|
||||
])
|
||||
|
||||
let view = NRDetailRechargeView()
|
||||
view.payModel = payModel
|
||||
|
||||
@ -115,4 +115,8 @@ extension NROrderRecordsPageViewController: JXSegmentedListContainerViewDataSour
|
||||
return self.titles.count
|
||||
}
|
||||
|
||||
func scrollViewClass(in listContainerView: JXSegmentedListContainerView) -> AnyClass {
|
||||
return NRPagerScrollView.self
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -75,8 +75,8 @@ class NRNovelReadSetManager: NSObject {
|
||||
return UIFont.font(ofSize: self.readSet.fontSize + 10, weight: .semibold)
|
||||
}
|
||||
|
||||
var miniFontSize: CGFloat = 12
|
||||
var maxFontSize: CGFloat = 24
|
||||
let miniFontSize: CGFloat = 12
|
||||
let maxFontSize: CGFloat = 24
|
||||
|
||||
var isNight: Bool {
|
||||
return readSet.isNight
|
||||
|
||||
@ -33,7 +33,7 @@ extension CGCoins {
|
||||
let lastTime = uploadRecordDate?.timeIntervalSince1970 ?? 0
|
||||
let nowTime = Date().timeIntervalSince1970
|
||||
|
||||
if lastTime == 0 || nowTime - lastTime > 5 {
|
||||
if lastTime == 0 || nowTime - lastTime > 1 {
|
||||
uploadRecordDate = Date()
|
||||
XMust.requestUploadRecord(novelId, chapterId: catalogModel.id ?? "")
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user