| | |
| | | self.player = try? AVAudioPlayer(contentsOf: fileURL!) |
| | | self.player?.delegate = self |
| | | self.player?.play() |
| | | DispatchQueue.main.async { |
| | | self.delegate?.playing() |
| | | } |
| | | }else{ |
| | | //文件不存在:执行下载 |
| | | let downloadTask = URLSession.shared.downloadTask(with: URL(string: u)!) { tempLocalUrl, response, error in |
| | |
| | | self.player = try? AVAudioPlayer(contentsOf: finalCacheUrl) |
| | | self.player?.delegate = self |
| | | self.player?.play() |
| | | DispatchQueue.main.async { |
| | | self.delegate?.playing() |
| | | } |
| | | } catch { |
| | | print("视频缓存失败:catch") |
| | | } |
| | |
| | | |
| | | extension VoicePlayer:AVAudioPlayerDelegate{ |
| | | func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { |
| | | DispatchQueue.main.async { |
| | | VoicePlayer.share().playComplete?() |
| | | delegate?.playComplete() |
| | | self.delegate?.playComplete() |
| | | } |
| | | } |
| | | |
| | | func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: (any Error)?) { |
| | |
| | | |
| | | |
| | | func restore(){ |
| | | isAnsterDone = false |
| | | isAnsterModel.removeAll() |
| | | isAnsterComplete = false |
| | | viewModel.answerType.accept(.none) |
| | |
| | | private func getNextAnswer(){ |
| | | isListen = false |
| | | if isAnsterModel.count == 4{ |
| | | print("答题答满了");return |
| | | if !isAnsterDone{ |
| | | let v = rootViewModel.answerCount.value |
| | | rootViewModel.answerCount.accept(v + 1) |
| | | } |
| | | isAnsterDone = true |
| | | |
| | | DispatchQueue.main.asyncAfter(deadline: .now()+3){[weak self] in |
| | | guard let weakSelf = self else { return } |
| | | NotificationCenter.default.post(name: NextLession_Noti, object: nil) |
| | | weakSelf.viewModel.answerType.accept(.none) |
| | | weakSelf.viewModel.selectIndex.accept(nil) |
| | | weakSelf.rootViewModel.answerItems[weakSelf.page] = weakSelf.listenNewModel.subjectList[weakSelf.page] |
| | | weakSelf.isListen = false |
| | | } |
| | | return |
| | | } |
| | | |
| | | randomElement = listenNewModel.subjectList[page].randomElement() |
| | |
| | | } |
| | | |
| | | extension HomeListenFight_lesson_1_VC:VoicePlayerDelegate{ |
| | | func playing() {} |
| | | func playing() { |
| | | isListen = false |
| | | } |
| | | |
| | | func playComplete() { |
| | | isListen = true |
| | | self.menuView?.resetView() |
| | | if isAnsterModel.count == 4{ |
| | | |
| | | if !isAnsterDone{ |
| | | let v = rootViewModel.answerCount.value |
| | | rootViewModel.answerCount.accept(v + 1) |
| | | } |
| | | isAnsterDone = true |
| | | |
| | | DispatchQueue.main.asyncAfter(deadline: .now()+3){[weak self] in |
| | | guard let weakSelf = self else { return } |
| | | NotificationCenter.default.post(name: NextLession_Noti, object: nil) |
| | | weakSelf.viewModel.answerType.accept(.none) |
| | | weakSelf.viewModel.selectIndex.accept(nil) |
| | | weakSelf.rootViewModel.answerItems[weakSelf.page] = weakSelf.listenNewModel.subjectList[weakSelf.page] |
| | | weakSelf.isListen = false |
| | | } |
| | | } |
| | | |
| | | if isAnsterComplete{ |
| | | getNextAnswer() |
| | |
| | | |
| | | /// 当前页数 |
| | | var currentPage = BehaviorRelay<Int>(value: 0) |
| | | var subPage = BehaviorRelay<Int>(value: 1) //小题目角标 |
| | | var maxPage = BehaviorRelay<Int>(value: 5) |
| | | var listenType = BehaviorRelay<ListenType>(value:.lesson1) |
| | | var times:Int = 0 |
| | |
| | | },onError: { _ in |
| | | weakSelf.showGameLevel() |
| | | }).disposed(by: weakSelf.disposeBag) |
| | | } cancelClouse: {[weak self] in |
| | | self?.navigationController?.popViewController(animated: true) |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | private func setPages(){ |
| | | switch viewModel.listenType.value{ |
| | | case .lesson1,.lesson2,.lesson3,.lesson5: |
| | | case .lesson1,.lesson2,.lesson5: |
| | | label_pageNum.text = "已完成:\(viewModel.answerCount.value)/\((data as! ListenNewModel).subjectList.flatMap({$0}).count)" |
| | | case .lesson3: |
| | | label_pageNum.text = "已完成:\(viewModel.currentPage.value + 1)/\((data as! ListenNewModel).subjectList.count)" |
| | | case .lesson4: |
| | | //两题为一组:需要/2 |
| | | label_pageNum.text = "已完成:\(viewModel.answerCount.value)/\((data as! ListenNewModel).subjectList.flatMap({$0}).count / 2)" |
| | |
| | | default:break |
| | | } |
| | | |
| | | //正确率 |
| | | let accracy = Int(Double(viewModel.correctNum) / Double(viewModel.correctNum + viewModel.errorNum) * 100) |
| | | |
| | | //有答题过程 |
| | | //完成进度 |
| | | var isComplete = false |
| | | switch viewModel.listenType.value { |
| | | case .lesson1:isComplete = studyScheduleModel?.listen == 100 |
| | | case .lesson2:isComplete = studyScheduleModel?.look == 100 |
| | | case .lesson3:isComplete = studyScheduleModel?.induction == 100 |
| | | case .lesson4:isComplete = studyScheduleModel?.answer == 100 |
| | | case .lesson5:isComplete = studyScheduleModel?.pair == 100 |
| | | default:isComplete = false |
| | | } |
| | | |
| | | Services.completeLearing(type: viewModel.listenType.value.rawValue, studyTime: viewModel.times, studyIds: ids, isComplete: isComplete).subscribe(onNext: {data in |
| | | Services.completeLearing(type: viewModel.listenType.value.rawValue, studyTime: viewModel.times, studyIds: ids, quarter: viewModel.quarter.value!, week: viewModel.week.value!, day: viewModel.day.value!, accracy: accracy).subscribe(onNext: {data in |
| | | NotificationCenter.default.post(name: Refresh_ListenSchedule_Noti, object: nil) |
| | | }).disposed(by: disposeBag) |
| | | |
| | |
| | | |
| | | @objc func beforeAction(){ |
| | | listenFightLine = .before |
| | | var beforePage = max(0, viewModel.currentPage.value - 1) |
| | | let beforePage = max(0, viewModel.currentPage.value - 1) |
| | | switch viewModel.listenType.value { |
| | | case .lesson1,.lesson2: |
| | | let temp = (beforePage * 4) + 1 |
| | | viewModel.answerCount.accept(max(1,temp)) |
| | | default:break |
| | | } |
| | | |
| | | |
| | | pageVC.scroll(toPage: beforePage, animation: true) |
| | | viewModel.currentPage.accept(beforePage) |
| | | |
| | |
| | | |
| | | handleView.chooseClouse {[weak self] btn in |
| | | guard let weakSelf = self else { return } |
| | | if weakSelf.playedIndex.count != 3{ |
| | | handleView.btn_choose.isSelected = false |
| | | alertError(msg: "请听完");return |
| | | } |
| | | handleView.view_choose.alpha = 1 |
| | | var lessionType:Fight_lessonType = .none |
| | | if handleView.vioceSoundUrl == weakSelf.listenNewModel.subjectList[weakSelf.page][row].correct{ |
| | |
| | | } |
| | | |
| | | extension HomeListenFight_lesson_2_VC:VoicePlayerDelegate{ |
| | | func playing() {} |
| | | func playing() { |
| | | print("正在播放") |
| | | //正在播放中,其他播放按钮先禁止 |
| | | for sub in stackView.arrangedSubviews as! [StudyHandleView]{ |
| | | sub.btn_pay.isEnabled = false |
| | | sub.btn_choose.isEnabled = false |
| | | } |
| | | |
| | | } |
| | | |
| | | func playComplete() { |
| | | //对已经播放过的View,进行刷新 |
| | | for sub in stackView.arrangedSubviews as! [StudyHandleView]{ |
| | | sub.btn_pay.isEnabled = true |
| | | sub.btn_choose.isEnabled = true |
| | | if playedIndex.contains(sub.tag){ |
| | | sub.resetView() |
| | | sub.view_choose.alpha = playedIndex.contains(sub.tag) ? 1:0 |
| | |
| | | private var voicePlayer = VoicePlayer.share() |
| | | private var playIndex = Set<IndexPath>() //顺序播放 |
| | | private var isPlayingIndex:IndexPath? //正在播放中 |
| | | private var islisten:Bool = false |
| | | |
| | | required init(page:Int,listenNewModel:ListenNewModel){ |
| | | super.init(nibName: nil, bundle: nil) |
| | |
| | | super.viewDidLoad() |
| | | navigationItem.titleView = UIView() |
| | | playIndex.insert(IndexPath(row: 0, section: 0)) |
| | | // setAnswerStackView() |
| | | } |
| | | |
| | | func restore(){ |
| | |
| | | |
| | | } |
| | | |
| | | private func setAnswerStackView(){ |
| | | private func setAnswerStackView(force:Bool = false){ |
| | | |
| | | stackView.removeArrangedSubviews() |
| | | |
| | | for v in stackView.arrangedSubviews{ |
| | | v.removeFromSuperview() |
| | | } |
| | | |
| | | |
| | | if isPlayingIndex == IndexPath(row: 2, section: 0) || isPlayingIndex == IndexPath(row: 1, section: 1) || isPlayingIndex == IndexPath(row: 2, section: 1) || !force{ |
| | | var tempImageArray = [String]() |
| | | |
| | | tempImageArray.append(listenNewModel.subjectList[page][2].img) |
| | |
| | | tempAnswerViews.shuffle() |
| | | stackView.addArrangedSubviews(tempAnswerViews) |
| | | } |
| | | } |
| | | |
| | | @objc private func chooseAnswerAction(btn:UIButton){ |
| | | |
| | | if !islisten{ |
| | | alertError(msg: "请先听题");return |
| | | } |
| | | |
| | | if isPlayingIndex != nil { |
| | | alertError(msg: "请先听题");return |
| | | } |
| | | |
| | | if rootViewModel.correctNum == 0 && !playIndex.contains(IndexPath(row: 2, section: 0)){ |
| | | if answterCount == 0 && !playIndex.contains(IndexPath(row: 2, section: 0)){ |
| | | alertError(msg: "请先听题");return |
| | | } |
| | | |
| | | if rootViewModel.correctNum == 1 && !playIndex.contains(IndexPath(row: 1, section: 1)){ |
| | | if answterCount == 1 && !playIndex.contains(IndexPath(row: 1, section: 1)){ |
| | | alertError(msg: "请先听题");return |
| | | } |
| | | |
| | | if rootViewModel.correctNum == 2 && !playIndex.contains(IndexPath(row: 2, section: 1)){ |
| | | if answterCount == 2 && !playIndex.contains(IndexPath(row: 2, section: 1)){ |
| | | alertError(msg: "请先听题");return |
| | | } |
| | | |
| | |
| | | subV?.btn_fullscreen.alpha = 0 |
| | | }completion: { _ in |
| | | DispatchQueue.main.asyncAfter(deadline: .now()+1.5) { |
| | | self.setAnswerStackView() |
| | | self.setAnswerStackView(force: true) |
| | | } |
| | | } |
| | | default:break |
| | |
| | | weakSelf.isPlayingIndex = index |
| | | |
| | | weakSelf.voicePlayer.playerEnd() |
| | | |
| | | if indexPath.section == 1{ |
| | | weakSelf.voicePlayer.playerAt(url: weakSelf.listenNewModel.subjectList[weakSelf.page][indexPath.row + 3].correct) |
| | | }else{ |
| | | weakSelf.voicePlayer.playerAt(url: weakSelf.listenNewModel.subjectList[weakSelf.page][indexPath.row].correct) |
| | | } |
| | | |
| | | weakSelf.viewModel.selectIndex.accept(index) |
| | | //点击答案,就显示 |
| | | if (index.section == 0 && index.row == 2) || (index.section == 1 && index.row > 0){ |
| | | weakSelf.viewModel.selectIndex.accept(index) |
| | | weakSelf.setAnswerStackView() |
| | | } |
| | | |
| | | collectionView.reloadItems(at: [index]) |
| | | } |
| | |
| | | extension HomeListenFight_lesson_3_VC:VoicePlayerDelegate{ |
| | | func playComplete() { |
| | | isPlayingIndex = nil |
| | | |
| | | islisten = true |
| | | var nextRow = (viewModel.selectIndex.value?.row ?? 0) + 1 |
| | | var section = (viewModel.selectIndex.value?.section ?? 0) + 0 |
| | | |
| | |
| | | } |
| | | |
| | | func playing() { |
| | | |
| | | islisten = false |
| | | } |
| | | } |
| | |
| | | @IBOutlet weak var tackView_level: UIStackView! |
| | | |
| | | private var clouseLevel:((Int)->Void)! |
| | | private var cancelClouse:(()->Void)! |
| | | private var level:Int = 0 |
| | | |
| | | override func awakeFromNib() { |
| | |
| | | layoutIfNeeded() |
| | | } |
| | | |
| | | static func show(clouse:@escaping (Int)->Void){ |
| | | static func show(clouse:@escaping (Int)->Void,cancelClouse:@escaping()->Void){ |
| | | |
| | | var needLoad:Bool = true |
| | | for v in sceneDelegate?.window?.subviews ?? []{ |
| | |
| | | |
| | | let levelView = ChooseLevelView.jq_loadNibView() |
| | | levelView.clouseLevel = clouse |
| | | levelView.cancelClouse = cancelClouse |
| | | sceneDelegate?.window?.addSubview(levelView) |
| | | levelView.frame = sceneDelegate?.window?.frame ?? .zero |
| | | |
| | |
| | | self.alpha = 0 |
| | | } completion: { _ in |
| | | self.removeFromSuperview() |
| | | self.cancelClouse() |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /// 完成学习 |
| | | class func completeLearing(type:Int,studyTime:Int,studyIds:String,isComplete:Bool)->Observable<BaseResponse<SimpleModel>>{ |
| | | class func completeLearing(type:Int,studyTime:Int,studyIds:String,quarter:Int,week:Int,day:Int,accracy:Int)->Observable<BaseResponse<SimpleModel>>{ |
| | | let params = ParamsAppender.build(url: All_Url) |
| | | params.interface(url: "/study/base/study/completeLearning") |
| | | .append(key: "type", value: type) |
| | | .append(key: "studyTime", value: studyTime) |
| | | .append(key: "studyIds", value: studyIds) |
| | | .append(key: "isComplete", value: isComplete) |
| | | .append(key: "week", value: week) |
| | | .append(key: "day", value: day) |
| | | .append(key: "quarter", value: quarter) |
| | | .append(key: "accuracy", value: accracy) |
| | | return NetworkRequest.request(params: params, method: .post,encoding: JSONEncoding.default, progress: true) |
| | | } |
| | | |