pujiaxin33 / JXSegmentedView

A powerful and easy to use segmented view (segmentedcontrol, pagingview, pagerview, pagecontrol, categoryview) (腾讯新闻、今日头条、QQ音乐、网易云音乐、京东、爱奇艺、腾讯视频、淘宝、天猫、简书、微博等所有主流APP分类切换滚动视图)
MIT License
2.66k stars 369 forks source link

-[JXSegmentedView.JXSegmentedView reuseIdentifier]: unrecognized selector sent to instance 0x126720460 #234

Closed zhuxiaod closed 3 months ago

zhuxiaod commented 11 months ago

你好,你的框架给了我很多优势在开发中。最近我遇到一个很难解决的问题,在我测试的众多版本下,我使用都是正常的,但是有一个客户反馈进入页面后崩溃,我一只无法复现这个问题。

设备版本:13.6 (17G68) 机型:iPad Pro 9.7-inch CPU架构:arm64-v8a

image image

@objcMembers class HomeCourseViewController: UIViewController {

//数据源
private var viewModel: HomeCourseViewModel!

lazy var pagingView: JXPagingView = JXPagingView(delegate: self)

lazy var userHeaderView: HomeCourseHeaderView = HomeCourseHeaderView()

let dataSource: JXSegmentedCourseDataSource = JXSegmentedCourseDataSource()

lazy var tab_emptView = UIView(frame: CGRect(x: 0, y: 0, width: cScreenWidth, height: cScreenHeight))

lazy var segmentedView: JXSegmentedView = JXSegmentedView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: CGFloat(headerInSectionHeight)))

var webVC = CourseWebDetailViewController()

var courseCommentVC: CourseCommentViewController? = nil

var courseListDetailVC: CourseListDetailViewController? = nil

var headerInSectionHeight: Int = Int(50.auto())

var isNeedHeader = false

var isNeedFooter = false

var schoolListModel = SchoolListModel()

var shareView: SchoolShareView?

var bottomView = HomeCourseBottomView()

var timerStr = ""

var indexTime = 0

var coursePayType: CoursePayType = .normal

var titles:[String] = [L10n.Sw.CourseListDetailVC.courseIntroduction,L10n.Sw.CourseListDetailVC.chapters]

//倒计时View
let countDownLab = UILabel().then {
    $0.textAlignment = .center
    $0.backgroundColor = UIColor(hexString: "#FCE155")
}

lazy var navView = UIView()

let navHStack = HStack()

let backImgView = UIImageView(image: UIImage(named: "nav_back"))

let navTitleLab = UILabel(text: "课程详情", font: 18.systemFont())

let courseShareImgView = UIImageView(image: UIImage(named: "black_share_icon"))

let courseShareImgBtn = UIButton()

let backBtn = UIButton()

var courseNavShareBtn = UIButton()

//sellCourseScheduleId courseScheduleId
init(model: SchoolListModel,vcType: Int = 0) {

    viewModel = HomeCourseViewModel()

    //设置数据状态
    viewModel.coursePayType = CoursePayType(rawValue: vcType) ?? .normal

    //如果是积分添加积分 ID
    if viewModel.coursePayType == .integralCourse {

        viewModel.integralId = model.integralId
    }

    schoolListModel = model

    self.coursePayType = CoursePayType(rawValue: vcType) ?? .normal

    super.init(nibName: nil, bundle: nil)

}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

deinit {

    ZXDTimer.cancelTask(timerStr)
}

override func viewDidLoad() {
    super.viewDidLoad()

    fd_prefersNavigationBarHidden = true

    setupBottomView()

    addNoty()

    setupContentView()

    setupHeaderView()

    addNavView()

    loadAnimated()

}

}

// MARK: - UI extension HomeCourseViewController: SchoolBottomViewDelegate {

func setupContentView() {

    dataSource.normalImageInfos = ["", L10n.ImageLocalizable.freeWatch, ""]
    dataSource.titleImageTypeArray = [.onlyTitle,.rightImage,.onlyTitle]
    dataSource.titles = titles
    dataSource.titleNormalColor = UIColor.appLabBlack()
    dataSource.titleSelectedColor = UIColor.appMain()
    dataSource.titleNormalFont = UIFont.boldSystemFont(ofSize: 15.fontAuto())
    dataSource.imageSizeArray = [
        CGSize(width: 0, height: 0),
        CGSize(width: 28.auto(), height: 14.auto()),
        CGSize(width: 0, height: 0)
    ]
    dataSource.isItemSpacingAverageEnabled = false
    segmentedView.dataSource = dataSource
    segmentedView.contentEdgeInsetLeft = 16.auto()
    segmentedView.backgroundColor = UIColor.white
    segmentedView.delegate = self
    segmentedView.isContentScrollViewClickTransitionAnimationEnabled = false
    segmentedView.dataSource = dataSource

    let lineView = JXSegmentedIndicatorLineView()
    lineView.indicatorColor = UIColor.appMain()
    lineView.indicatorWidth = 14.auto()
    segmentedView.indicators = [lineView]

    pagingView.mainTableView.gestureDelegate = self

    view.addSubview(pagingView)

    view.addSubview(countDownLab)

    countDownLab.snp.makeConstraints {
        $0.height.equalTo(0)
        $0.right.left.equalTo(view)
        $0.bottom.equalTo(bottomView.snp.top)
    }

    pagingView.snp.makeConstraints {
        $0.top.equalTo(view)
        $0.right.left.equalTo(view)
        $0.bottom.equalTo(countDownLab.snp.top)
    }

    segmentedView.listContainer = pagingView.listContainerView
    //扣边返回处理,下面的代码要加上
    pagingView.listContainerView.scrollView.panGestureRecognizer.require(toFail: self.navigationController!.interactivePopGestureRecognizer!)
    pagingView.mainTableView.panGestureRecognizer.require(toFail: self.navigationController!.interactivePopGestureRecognizer!)

}

}

// MARK: - navigationView extension HomeCourseViewController {

func addNavView() {

    navView.alpha = 0
    navView.backgroundColor = UIColor.appWhite()
    view.addSubview(navView)

    navView.snp.makeConstraints {
        $0.top.left.right.equalTo(view)
        $0.height.equalTo(cSafeAreaTopInset+cNavigationBarHeight)
    }

    view.addSubview(navHStack)
    view.addSubview(backImgView)
    view.addSubview(courseShareImgView)

    navHStack.snp.makeConstraints {
        $0.top.equalTo(view).offset(cSafeAreaTopInset)
        $0.height.equalTo(cNavigationBarHeight)
        $0.left.equalTo(view)
        $0.right.equalTo(view)
    }

    navTitleLab.textAlignment = .center
    navTitleLab.alpha = 0

    navHStack.qd_removeArrangedSubviews()

    navHStack.addArrangedSubviews([
        backBtn, navTitleLab, courseShareImgBtn
    ]) {
        backBtn.sizeConstraint = CGSize(width: 60.auto(), height: 44.auto())
        courseShareImgBtn.sizeConstraint = CGSize(width: 60.auto(), height: 44.auto())
    }

    backImgView.snp.makeConstraints {
        $0.centerY.equalTo(backBtn)
        $0.left.equalTo(backBtn).offset(16.auto())
        $0.size.equalTo(CGSize(width: 18.auto(), height: 18.auto()))
    }

    courseShareImgView.snp.makeConstraints {
        $0.centerY.equalTo(courseShareImgBtn)
        $0.right.equalTo(courseShareImgBtn).offset(-16.auto())
        $0.size.equalTo(CGSize(width: 18.auto(), height: 18.auto()))
    }

    pagingView.pinSectionHeaderVerticalOffset = Int(cSafeAreaTopInset+cNavigationBarHeight)

    backBtn.addTarget(self, action: #selector(backLastVC), for: .touchUpInside)
    courseShareImgBtn.addTarget(self, action: #selector(shareNormal), for: .touchUpInside)
}

func pagingView(_ pagingView: JXPagingView, mainTableViewDidScroll scrollView: UIScrollView) {
    let thresholdDistance: CGFloat = 100
    var percent = scrollView.contentOffset.y/thresholdDistance
    percent = max(0, min(1, percent))
    navView.alpha = percent
    navTitleLab.alpha = percent
}

}

// MARK: - bottomView逻辑 extension HomeCourseViewController {

func setupBottomView() {

    view.addSubview(bottomView)

    bottomView.snp.makeConstraints {
        $0.right.left.equalTo(view)
        $0.height.equalTo(52.auto())
        $0.bottom.equalTo(view).offset(-cSafeAreaBottomInset)
    }

}

}

// MARK: - SubVC逻辑 extension HomeCourseViewController: JXPagingViewDelegate,JXPagingMainTableViewGestureDelegate,JXSegmentedViewDelegate {

func pagingView(_ pagingView: JXPagingView, initListAtIndex index: Int) -> JXPagingViewListViewDelegate {

    //课程介绍
    if index == 0 {
        return webVC
    }else if index == 1 {
        if courseListDetailVC == nil {
            courseListDetailVC = CourseListDetailViewController(
                sellCourseScheduleId: schoolListModel.sellCourseScheduleId,
                courseScheduleId: schoolListModel.courseScheduleId,
                isTryAndSee: viewModel.isTryAndSee,
                isLive: viewModel.classType == .live ? true : false,
                isBuy: viewModel.courseModel?.haveDatebook == 1 ? true : false)
        }
        return courseListDetailVC!
    }else{
        if courseCommentVC == nil {
            courseCommentVC = CourseCommentViewController(sellCourseScheduleId: schoolListModel.sellCourseScheduleId,
                                                          courseScheduleId: schoolListModel.courseScheduleId)
        }
        return courseCommentVC!
    }

}

func tableHeaderViewHeight(in pagingView: JXPagingView) -> Int {
    userHeaderView.viewHeight()
}

func tableHeaderView(in pagingView: JXPagingView) -> UIView {
    userHeaderView
}

func heightForPinSectionHeader(in pagingView: JXPagingView) -> Int {
    headerInSectionHeight
}

func viewForPinSectionHeader(in pagingView: JXPagingView) -> UIView {
    segmentedView
}

func numberOfLists(in pagingView: JXPagingView) -> Int {
    titles.count
}

func preferredPagingView() -> JXPagingView {

    return JXPagingView(delegate: self)
}

func mainTableViewGestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    //禁止segmentedView左右滑动的时候,上下和左右都可以滚动
    if otherGestureRecognizer == segmentedView.collectionView.panGestureRecognizer {
        return false
    }
    return gestureRecognizer.isKind(of: UIPanGestureRecognizer.self) && otherGestureRecognizer.isKind(of: UIPanGestureRecognizer.self)
}

func segmentedView(_ segmentedView: JXSegmentedView, didSelectedItemAt index: Int) {
    self.navigationController?.interactivePopGestureRecognizer?.isEnabled = (index == 0)
}

}

extension HomeCourseViewController {

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    self.navigationController?.interactivePopGestureRecognizer?.isEnabled = (segmentedView.selectedIndex == 0)

    reloadNewData(isBuy: false)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
}

}

// MARK: - 数据处理 extension HomeCourseViewController {

func setupModel() {

    //状态刷新
    courseListDetailVC?.setupInfo(
        sellCourseScheduleId: schoolListModel.sellCourseScheduleId,
        courseScheduleId: schoolListModel.courseScheduleId,
        isTryAndSee: viewModel.isTryAndSee,
        isLive: viewModel.classType == .live ? true : false,
        isBuy: viewModel.courseModel?.haveDatebook == 1 ? true : false)

    courseListDetailVC?.loadData()

    segmentedView.dataSource = dataSource

    segmentedView.reloadData()

    pagingView.reloadData()

    pagingView.listContainerView.reloadData()

    guard let courseModel = self.viewModel.courseModel else {
        return
    }

    bottomView.setup(model: courseModel)

}

//刷新titles
func reloadTitleView() {

    //是否显示评价
    titles = [L10n.Sw.CourseListDetailVC.courseIntroduction,L10n.Sw.CourseListDetailVC.chapters,L10n.Sw.HomeCourseListCell.evaluation]

    dataSource.titles = titles

    segmentedView.reloadData()

    pagingView.reloadData()

}

} 这个是我的代码,我删除了一下业务逻辑。

pujiaxin33 commented 3 months ago

可能和这个bug是一个原因,已经修复了。https://github.com/pujiaxin33/JXSegmentedView/issues/218