| | |
| | | |
| | | protocol VoicePlayerDelegate{ |
| | | func playComplete() |
| | | func playing() |
| | | } |
| | | |
| | | /// 音频播放器 |
| | |
| | | player = try? AVAudioPlayer(contentsOf: fileURL!) |
| | | player?.delegate = self |
| | | player?.play() |
| | | 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() |
| | | self.delegate?.playing() |
| | | } catch { |
| | | print("视频缓存失败:catch") |
| | | } |
| | |
| | | private var isListen:Bool = false |
| | | private var isAnsterComplete:Bool = false //是否已经回答完成 |
| | | |
| | | private var menuView:VoiceHandleView! |
| | | private var menuView:VoiceHandleView? |
| | | |
| | | private lazy var collectionView:UICollectionView = { |
| | | let flowLayout = UICollectionViewFlowLayout() |
| | |
| | | super.init(nibName: nil, bundle: nil) |
| | | self.page = page |
| | | self.listen1Model = listen1Model |
| | | self.listen1Model.subjectList.shuffle() |
| | | } |
| | | |
| | | required init?(coder: NSCoder) { |
| | |
| | | super.viewDidLoad() |
| | | navigationItem.titleView = UIView() |
| | | collectionView.reloadData() |
| | | print("加载======DidLoad") |
| | | |
| | | // collectionView.isUserInteractionEnabled = false |
| | | //制造随机 |
| | | randomElement = listen1Model.subjectList.randomElement() |
| | | menuView?.playUrl = randomElement?.correct |
| | | menuView?.listenType = .lesson1 |
| | | |
| | | DispatchQueue.main.asyncAfter(deadline: .now()+2) { |
| | | VoicePlayer.share().playerAt(url: self.randomElement?.correct) |
| | | self.menuView?.playing() |
| | | } |
| | | |
| | | } |
| | | |
| | |
| | | VoicePlayer.share().delegate = nil |
| | | } |
| | | |
| | | |
| | | func restore(){ |
| | | isAnsterComplete = false |
| | | viewModel.answerType.accept(.none) |
| | | viewModel.selectIndex.accept(nil) |
| | | menuView?.resetView() |
| | | setUI() |
| | | collectionView.reloadData() |
| | | } |
| | | |
| | | override func setUI() { |
| | | super.setUI() |
| | | |
| | | collectionView.delegate = self |
| | | collectionView.dataSource = self |
| | | collectionView.backgroundColor = UIColor(hexStr: "#C3BFB3") |
| | | view.addSubview(collectionView) |
| | | collectionView.snp.makeConstraints { make in |
| | | make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(101) |
| | | make.left.equalTo(194) |
| | | make.right.equalTo(-194) |
| | | make.bottom.equalToSuperview() |
| | | if !view.subviews.contains(collectionView){ |
| | | collectionView.delegate = self |
| | | collectionView.dataSource = self |
| | | collectionView.backgroundColor = UIColor(hexStr: "#C3BFB3") |
| | | view.addSubview(collectionView) |
| | | collectionView.snp.makeConstraints { make in |
| | | make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(101) |
| | | make.left.equalTo(194) |
| | | make.right.equalTo(-194) |
| | | make.bottom.equalToSuperview() |
| | | } |
| | | } |
| | | |
| | | menuView = VoiceHandleView() |
| | | //制造随机 |
| | | randomElement = listen1Model.subjectList.randomElement() |
| | | menuView.playUrl = randomElement?.correct |
| | | menuView.listenType = .lesson1 |
| | | view.addSubview(menuView) |
| | | menuView.snp.makeConstraints { make in |
| | | make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(24) |
| | | make.centerX.equalToSuperview() |
| | | make.height.equalTo(52) |
| | | make.width.equalTo(159) |
| | | if menuView == nil{ |
| | | menuView = VoiceHandleView() |
| | | view.addSubview(menuView!) |
| | | menuView?.snp.makeConstraints { make in |
| | | make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(24) |
| | | make.centerX.equalToSuperview() |
| | | make.height.equalTo(52) |
| | | make.width.equalTo(159) |
| | | } |
| | | }else{ |
| | | menuView?.snp.remakeConstraints { make in |
| | | make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(24) |
| | | make.centerX.equalToSuperview() |
| | | make.height.equalTo(52) |
| | | make.width.equalTo(159) |
| | | } |
| | | } |
| | | |
| | | collectionView.reloadData() |
| | | } |
| | | |
| | | override func setRx() { |
| | | viewModel.selectIndex.subscribe(onNext: {[weak self] index in |
| | | |
| | | guard let index = index else { return } |
| | | |
| | | //判断选中是否正确逻辑 |
| | | if let cell = self?.collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_1_CCell", for: index) as? ListenFight_lesson_1_CCell{ |
| | | var answer:Fight_lessonType = .none |
| | |
| | | self?.rootViewModel.correctNum += 1 |
| | | } |
| | | self?.isAnsterComplete = true |
| | | VoicePlayer.share().playerAt(url: self?.listen1Model.subjectList[index.row].correct) |
| | | }else{ |
| | | answer = .fail |
| | | if self?.isAnsterComplete == false{ |
| | |
| | | |
| | | //回答正确 |
| | | private func answerSuccess(_ cell:ListenFight_lesson_1_CCell){ |
| | | menuView.snp.removeConstraints() |
| | | menuView?.snp.removeConstraints() |
| | | // collectionView.isUserInteractionEnabled = false |
| | | let v = cell.view_topHandle.convert(cell.bounds, to: self.view) |
| | | UIView.animate(withDuration: 0.3) { |
| | | self.menuView.snp.updateConstraints { make in |
| | | self.menuView?.snp.updateConstraints { make in |
| | | make.top.equalTo(self.view).offset(v.origin.y + UIDevice.jq_safeEdges.top + 101 + 50) |
| | | make.left.equalToSuperview().offset(v.origin.x + 194) |
| | | make.width.equalTo(v.size.width - 10) |
| | |
| | | self.view.layoutIfNeeded() |
| | | }completion: { _ in |
| | | self.collectionView.reloadData() |
| | | DispatchQueue.main.asyncAfter(deadline: .now()+1.2){ |
| | | NotificationCenter.default.post(name: NextLession_Noti, object: nil) |
| | | // self.collectionView.isUserInteractionEnabled = true |
| | | self.viewModel.answerType.accept(.none) |
| | | self.viewModel.selectIndex.accept(nil) |
| | | self.rootViewModel.answerItems[self.page] = self.listen1Model |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | extension HomeListenFight_lesson_1_VC:VoicePlayerDelegate{ |
| | | func playing() {} |
| | | |
| | | func playComplete() { |
| | | isListen = true |
| | | menuView.resetView() |
| | | self.menuView?.resetView() |
| | | if self.isAnsterComplete{ |
| | | DispatchQueue.main.asyncAfter(deadline: .now()+3){ |
| | | NotificationCenter.default.post(name: NextLession_Noti, object: nil) |
| | | self.viewModel.answerType.accept(.none) |
| | | self.viewModel.selectIndex.accept(nil) |
| | | self.rootViewModel.answerItems[self.page] = self.listen1Model |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | }else if progress == 100{ |
| | | view_state.backgroundColor = UIColor(hexString: "#66CFFA") |
| | | label_state.text = "已完成" |
| | | }else{ |
| | | }else if progress > 0 && progress < 100{ |
| | | view_state.backgroundColor = UIColor(hexString: "#FF8A66") |
| | | label_state.text = String(format: "%ld%%", progress) |
| | | }else{ |
| | | view_state.backgroundColor = .black.withAlphaComponent(0.33) |
| | | label_state.text = "未开始" |
| | | } |
| | | |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | enum ListenFightLine{ |
| | | case before |
| | | case next |
| | | case none |
| | | } |
| | | |
| | | class HomeListenFightViewModel{ |
| | | |
| | | /// 当前页数 |
| | |
| | | var times:Int = 0 |
| | | var quarter = BehaviorRelay<Int?>(value: 0) |
| | | var week = BehaviorRelay<Int?>(value: 0) |
| | | var day = BehaviorRelay<Int?>(value: 0) |
| | | |
| | | //游戏专属,游戏等级 |
| | | var gameLevel = BehaviorRelay<Int>(value:0) |
| | |
| | | |
| | | class HomeListenFightVC: BaseVC { |
| | | private var viewModel = HomeListenFightViewModel() |
| | | var studyScheduleModel:StudyScheduleModel? //学习进度(上级传递) |
| | | var listenFightLine:ListenFightLine = .none |
| | | var data:Any? |
| | | |
| | | private lazy var label_pageNum:UILabel = { |
| | |
| | | private var timer:Timer! |
| | | |
| | | |
| | | init(listenType:ListenType,quarter:Int? = nil,week:Int? = nil) { |
| | | init(listenType:ListenType,quarter:Int? = nil,week:Int? = nil,day:Int? = nil) { |
| | | super.init(nibName: nil, bundle: nil) |
| | | self.viewModel.listenType.accept(listenType) |
| | | self.viewModel.week.accept(week) |
| | | self.viewModel.day.accept(day) |
| | | self.viewModel.quarter.accept(quarter) |
| | | |
| | | if listenType == .game1 || listenType == .game2{ |
| | |
| | | } |
| | | |
| | | override func setRx() { |
| | | |
| | | // NotificationCenter.default.rx.notification(Reload_Noti).take(until: self.rx.deallocated).subscribe(onNext: {[weak self] noti in |
| | | // self?.pageVC.reloadData() |
| | | // }).disposed(by: disposeBag) |
| | | |
| | | |
| | | NotificationCenter.default.rx.notification(NextLession_Noti).take(until: self.rx.deallocated).subscribe(onNext: {[weak self] noti in |
| | | guard let weakSelf = self else { return } |
| | | let nextPage = weakSelf.viewModel.currentPage.value + 1 |
| | |
| | | return |
| | | } |
| | | |
| | | self?.listenFightLine = .next |
| | | self?.pageVC.scroll(toPage: nextPage, animation: true) |
| | | self?.viewModel.currentPage.accept(nextPage) |
| | | }).disposed(by: disposeBag) |
| | |
| | | }).disposed(by: disposeBag) |
| | | } |
| | | |
| | | //学习类完成 |
| | | |
| | | /// 学习类完成 |
| | | /// - Parameter ignorePush: 是否忽略跳转(未完成答题 :true) |
| | | private func studyComplete(){ |
| | | var toalIntegral:Int = 0 |
| | | var ids = [Int]() |
| | |
| | | } |
| | | } |
| | | |
| | | Services.completeLearing(type: viewModel.listenType.value.rawValue, studyTime: viewModel.times, studyIds: ids, isComplete: false).subscribe(onNext: {data in |
| | | |
| | | }).disposed(by: disposeBag) |
| | | //有答题过程 |
| | | //完成进度 |
| | | 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 |
| | | NotificationCenter.default.post(name: Refresh_ListenSchedule_Noti, object: nil) |
| | | }).disposed(by: disposeBag) |
| | | |
| | | timer.invalidate() |
| | | |
| | | let vc = HomeStudyCompleteVC(correctNum: viewModel.correctNum, errorNum: viewModel.errorNum, totalCoin: toalIntegral, listenType: viewModel.listenType.value) |
| | | vc.title = viewModel.listenType.value.rawTitle |
| | | push(vc: vc) |
| | | let vc = HomeStudyCompleteVC(correctNum: viewModel.correctNum, errorNum: viewModel.errorNum, totalCoin: toalIntegral, listenType: viewModel.listenType.value) |
| | | vc.title = viewModel.listenType.value.rawTitle |
| | | push(vc: vc) |
| | | } |
| | | |
| | | //游戏类完成 |
| | |
| | | let accuracy = Int(Double(viewModel.correctNum) / Double(viewModel.correctNum + viewModel.errorNum) * 100) |
| | | |
| | | Services.completeGames(gameId: gameId, gameName: name, difficulty: viewModel.gameLevel.value, accuracy: accuracy, useTime: viewModel.times).subscribe(onNext: {data in |
| | | |
| | | NotificationCenter.default.post(name: Refresh_ListenSchedule_Noti, object: nil) |
| | | }).disposed(by: disposeBag) |
| | | |
| | | timer.invalidate() |
| | |
| | | } |
| | | |
| | | private func storyComplete(storyId:Int,integral:Int){ |
| | | Services.completeStory(storyId: storyId, integral: integral).subscribe(onNext: {data in |
| | | timer.invalidate() |
| | | |
| | | Services.completeStory(storyId: storyId, integral: integral).subscribe(onNext: {data in |
| | | NotificationCenter.default.post(name: Refresh_ListenSchedule_Noti, object: nil) |
| | | }).disposed(by: disposeBag) |
| | | |
| | | let vc = HomeStudyCompleteVC(correctNum: viewModel.correctNum, errorNum: viewModel.errorNum, totalCoin: integral, listenType: viewModel.listenType.value) |
| | |
| | | storyComplete(storyId: v.data!.id, integral: v.data!.lookIntegral) |
| | | } |
| | | }else{ |
| | | CommonAlertView.show(content: "未完成全部答题,确认退出吗?") { |
| | | self.navigationController?.popViewController(animated: true) |
| | | CommonAlertView.show(content: "未完成全部答题,确认退出吗?") {[weak self] () in |
| | | guard let weakSelf = self else { return } |
| | | |
| | | var temIds = [String]() |
| | | var topicIds = [String]() |
| | | for v in weakSelf.viewModel.answerItems.values{ |
| | | if let v = v as? Listen1Model{ |
| | | temIds.append("\(v.data?.id ?? 0)") |
| | | for sV in v.subjectList{ |
| | | topicIds.append("\(sV.id)") |
| | | } |
| | | } |
| | | } |
| | | |
| | | switch weakSelf.viewModel.listenType.value{ |
| | | case .lesson1,.lesson2,.lesson3,.lesson4,.lesson5: |
| | | if temIds.count > 0 && topicIds.count > 0{ |
| | | Services.exitLearning(type:weakSelf.viewModel.listenType.value.rawValue,week: weakSelf.viewModel.week.value!, day: weakSelf.viewModel.day.value!, teamIds: temIds, topicIds: topicIds).subscribe(onNext: { data in |
| | | |
| | | }).disposed(by: weakSelf.disposeBag) |
| | | } |
| | | default:break |
| | | } |
| | | weakSelf.navigationController?.popViewController(animated: true) |
| | | } |
| | | } |
| | | } |
| | | |
| | | @objc func nextAction(){ |
| | | // var v = viewModel.currentPage.value |
| | | // v += 1 |
| | | // viewModel.currentPage.accept(v) |
| | | |
| | | listenFightLine = .next |
| | | if viewModel.listenType.value == .story2{ |
| | | let v = data as! Listen1Model |
| | | var dict = Dictionary<String,Any>() |
| | |
| | | } |
| | | |
| | | @objc func beforeAction(){ |
| | | listenFightLine = .before |
| | | let beforePage = max(0, viewModel.currentPage.value - 1) |
| | | pageVC.scroll(toPage: beforePage, animation: true) |
| | | viewModel.currentPage.accept(beforePage) |
| | |
| | | } |
| | | |
| | | func pageViewController(_ pageViewController: FFPageViewController, currentPageChanged currentPage: Int) { |
| | | print("---->\(currentPage)") |
| | | |
| | | if listenFightLine == .before{ |
| | | if let vc = pageViewController.currentController as? HomeListenFight_lesson_1_VC{ |
| | | vc.restore() |
| | | } |
| | | if let vc = pageViewController.currentController as? HomeListenFight_lesson_2_VC{ |
| | | vc.restore() |
| | | } |
| | | if let vc = pageViewController.currentController as? HomeListenFight_lesson_3_VC{ |
| | | vc.restore() |
| | | } |
| | | if let vc = pageViewController.currentController as? HomeListenFight_lesson_4_VC{ |
| | | vc.restore() |
| | | } |
| | | if let vc = pageViewController.currentController as? HomeListenFight_lesson_5_VC{ |
| | | vc.restore() |
| | | } |
| | | } |
| | | } |
| | | |
| | | func pageViewController(_ pageViewConteoller: FFPageViewController, controllerForPage page: Int) -> UIViewController { |
| | | |
| | | print("加载======") |
| | | if viewModel.listenType.value == .lesson1{ |
| | | let vc = HomeListenFight_lesson_1_VC(page: page,listen1Model:data as! Listen1Model) |
| | | vc.rootViewModel = viewModel |
| | |
| | | private var tempViews = [StudyHandleView]() |
| | | |
| | | private var playedIndex = Set<Int>() //已经播放过的view |
| | | private var voicePlayer = VoicePlayer.share() |
| | | |
| | | private lazy var stackView:UIStackView = { |
| | | let stackView = UIStackView() |
| | |
| | | super.init(nibName: nil, bundle: nil) |
| | | self.page = page |
| | | self.listen1Model = listen1Model |
| | | self.listen1Model.subjectList.shuffle() |
| | | } |
| | | |
| | | required init?(coder: NSCoder) { |
| | |
| | | override func viewDidLoad() { |
| | | super.viewDidLoad() |
| | | navigationItem.titleView = UIView() |
| | | } |
| | | |
| | | override func viewDidAppear(_ animated: Bool) { |
| | | super.viewDidAppear(animated) |
| | | VoicePlayer.share().delegate = self |
| | | } |
| | | |
| | | override func viewDidDisappear(_ animated: Bool) { |
| | | super.viewDidDisappear(animated) |
| | | VoicePlayer.share().delegate = nil |
| | | } |
| | | |
| | | func restore(){ |
| | | playedIndex.removeAll() |
| | | tempViews.removeAll() |
| | | |
| | | for subView in view.subviews{ |
| | | if subView is StudyHandleView{ |
| | | subView.removeFromSuperview() |
| | | } |
| | | } |
| | | setUI() |
| | | collectionView.reloadData() |
| | | |
| | | } |
| | | |
| | |
| | | |
| | | viewModel.selectIndex.accept(IndexPath(row: 0, section: 0)) |
| | | |
| | | collectionView.delegate = self |
| | | collectionView.dataSource = self |
| | | collectionView.backgroundColor = UIColor(hexStr: "#C3BFB3") |
| | | view.addSubview(collectionView) |
| | | if !view.subviews.contains(collectionView){ |
| | | collectionView.delegate = self |
| | | collectionView.dataSource = self |
| | | collectionView.backgroundColor = UIColor(hexStr: "#C3BFB3") |
| | | view.addSubview(collectionView) |
| | | } |
| | | |
| | | collectionView.snp.makeConstraints { make in |
| | | make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(101) |
| | | make.left.equalTo(194) |
| | |
| | | make.bottom.equalToSuperview() |
| | | } |
| | | |
| | | view.addSubview(stackView) |
| | | if !view.subviews.contains(stackView){ |
| | | view.addSubview(stackView) |
| | | } |
| | | |
| | | stackView.snp.makeConstraints { make in |
| | | make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(24) |
| | | make.centerX.equalToSuperview() |
| | |
| | | } |
| | | |
| | | addStackView() |
| | | VoicePlayer.share().playEnd {[weak self] in |
| | | //对已经播放过的View,进行刷新 |
| | | for sub in self!.stackView.arrangedSubviews as! [StudyHandleView]{ |
| | | if self!.playedIndex.contains(sub.tag){ |
| | | sub.resetView() |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | |
| | | var lessionType:Fight_lessonType = .none |
| | | if handleView.vioceSoundUrl == weakSelf.listen1Model.subjectList[row].correct{ |
| | | lessionType = .success |
| | | VoicePlayer.share().playerEnd() |
| | | weakSelf.voicePlayer.playerEnd() |
| | | }else{ |
| | | lessionType = .fail |
| | | } |
| | |
| | | self.view.layoutIfNeeded() |
| | | }completion: { complete in |
| | | if complete{ |
| | | self.resetStackView() |
| | | self.voicePlayer.playerAt(url: self.listen1Model.subjectList[self.viewModel.selectIndex.value!.row].correct) |
| | | } |
| | | } |
| | | } |
| | | |
| | | private func resetStackView(){ |
| | | let newRow = viewModel.selectIndex.value!.row+1 |
| | | viewModel.selectIndex.accept(IndexPath(row: newRow, section: 0)) |
| | | |
| | | collectionView.reloadData() |
| | | if newRow == 4{ |
| | | if newRow == listen1Model.subjectList.count{ //防止坐标越界 |
| | | rootViewModel.answerItems[page] = listen1Model |
| | | NotificationCenter.default.post(name: NextLession_Noti, object: nil);return |
| | | } |
| | | |
| | | collectionView.reloadData() |
| | | viewModel.selectIndex.accept(IndexPath(row: newRow, section: 0)) |
| | | addStackView() |
| | | } |
| | | |
| | | override func setRx() { |
| | | // viewModel.selectIndex.subscribe(onNext: {[weak self] index in |
| | | // guard let index = index else { return } |
| | | // //判断选中是否正确逻辑 |
| | | // if self?.collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_1_CCell", for: index) is ListenFight_lesson_1_CCell{ |
| | | // var answerType:Fight_lessonType = .none |
| | | // answerType = .success |
| | | // switch answerType { |
| | | // case .success: |
| | | // self?.viewModel.answerType.accept(.success) |
| | | // self?.rootViewModel.correctNum += 1 |
| | | // case .fail: |
| | | // self?.viewModel.answerType.accept(.fail) |
| | | // self?.rootViewModel.errorNum += 1 |
| | | // default:break |
| | | // } |
| | | // } |
| | | // }).disposed(by: disposeBag) |
| | | } |
| | | override func setRx() {} |
| | | } |
| | | |
| | | extension HomeListenFight_lesson_2_VC:UICollectionViewDelegate{ |
| | |
| | | return min(4,listen1Model.subjectList.count) |
| | | } |
| | | } |
| | | |
| | | extension HomeListenFight_lesson_2_VC:VoicePlayerDelegate{ |
| | | func playing() {} |
| | | |
| | | func playComplete() { |
| | | //对已经播放过的View,进行刷新 |
| | | for sub in stackView.arrangedSubviews as! [StudyHandleView]{ |
| | | if playedIndex.contains(sub.tag){ |
| | | sub.resetView() |
| | | } |
| | | } |
| | | |
| | | print("--->\(page)") |
| | | |
| | | if viewModel.answerType.value == .success{ |
| | | DispatchQueue.main.asyncAfter(deadline: .now()+3) { |
| | | self.resetStackView() |
| | | self.viewModel.answerType.accept(.none) |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | private var page:Int! |
| | | private var answterCount:Int = 0 //回答计数,用于确定角标 |
| | | var rootViewModel:HomeListenFightViewModel! |
| | | private var voicePlayer = VoicePlayer.share() |
| | | |
| | | required init(page:Int,listen1Model:Listen1Model){ |
| | | super.init(nibName: nil, bundle: nil) |
| | | self.page = page |
| | | self.listen1Model = listen1Model |
| | | self.listen1Model.subjectList.shuffle() |
| | | } |
| | | |
| | | required init?(coder: NSCoder) { |
| | | fatalError("init(coder:) has not been implemented") |
| | | } |
| | | |
| | | |
| | | override func viewDidAppear(_ animated: Bool) { |
| | | super.viewDidAppear(animated) |
| | | voicePlayer.delegate = self |
| | | } |
| | | |
| | | override func viewDidDisappear(_ animated: Bool) { |
| | | super.viewDidDisappear(animated) |
| | | voicePlayer.delegate = nil |
| | | } |
| | | |
| | | |
| | | |
| | | override func viewDidLoad() { |
| | | super.viewDidLoad() |
| | |
| | | // viewModel.selectIndex.accept(IndexPath(row: 0, section: 0)) |
| | | |
| | | setAnswerStackView() |
| | | } |
| | | |
| | | VoicePlayer.share().playEnd { [weak self] in |
| | | guard let weakSelf = self else { return } |
| | | // if weakSelf.viewModel.selectIndex.value != nil{ |
| | | // weakSelf.collectionView.reloadItems(at: [weakSelf.viewModel.selectIndex.value!]) |
| | | // weakSelf.viewModel.selectIndex.accept(nil) |
| | | // } |
| | | weakSelf.collectionView.reloadData() |
| | | func restore(){ |
| | | answterCount = 0 |
| | | for subView in view.subviews{ |
| | | if subView is Lesson_3_AnswerView{ |
| | | subView.removeFromSuperview() |
| | | } |
| | | } |
| | | setUI() |
| | | collectionView.reloadData() |
| | | |
| | | } |
| | | |
| | | override func setUI() { |
| | | super.setUI() |
| | | if !view.subviews.contains(collectionView){ |
| | | collectionView.delegate = self |
| | | collectionView.dataSource = self |
| | | collectionView.showsVerticalScrollIndicator = false |
| | | collectionView.backgroundColor = .clear |
| | | view.addSubview(collectionView) |
| | | } |
| | | |
| | | collectionView.delegate = self |
| | | collectionView.dataSource = self |
| | | collectionView.showsVerticalScrollIndicator = false |
| | | collectionView.backgroundColor = .clear |
| | | view.addSubview(collectionView) |
| | | collectionView.snp.makeConstraints { make in |
| | | make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(0) |
| | | make.left.equalTo(97) |
| | | make.right.equalTo(-54) |
| | | make.bottom.equalToSuperview() |
| | | } |
| | | } |
| | | |
| | | private func answerSuccess(_ cell:ListenFight_lesson_1_CCell,index:Int){ |
| | | |
| | | } |
| | | |
| | | private func resetStackView(){ |
| | | |
| | | } |
| | | |
| | | override func setRx() { |
| | |
| | | } |
| | | |
| | | @objc private func chooseAnswerAction(btn:UIButton){ |
| | | |
| | | if viewModel.selectIndex.value == nil{alertError(msg: "请先听题");return} |
| | | |
| | | let index = btn.tag - 10 |
| | |
| | | let copyViewFrame = subV?.convert(subV!.bounds, to: self.view) |
| | | let copyView = subV?.copyView() |
| | | copyView?.frame = copyViewFrame! |
| | | copyView?.img_cover.image = subV?.img_cover.image |
| | | copyView?.img_cover.contentMode = .scaleToFill |
| | | copyView?.img_cover.image = subV?.img_cover.image |
| | | self.view.addSubview(copyView!) |
| | | copyView?.layoutIfNeeded() |
| | | |
| | |
| | | copyView?.frame = newFrame |
| | | } completion: { _ in |
| | | self.answterCount += 1 |
| | | if self.answterCount == 3{ |
| | | self.rootViewModel.answerItems[self.page] = self.listen1Model |
| | | NotificationCenter.default.post(name: NextLession_Noti, object: nil);return |
| | | } |
| | | self.voicePlayer.playerAt(url: self.listen1Model.subjectList[valueIndex].correct) |
| | | |
| | | DispatchQueue.main.asyncAfter(deadline: .now()+1.0) { |
| | | self.setAnswerStackView() |
| | |
| | | func numberOfSections(in collectionView: UICollectionView) -> Int { |
| | | return 2 |
| | | } |
| | | } |
| | | |
| | | extension HomeListenFight_lesson_3_VC:VoicePlayerDelegate{ |
| | | func playComplete() { |
| | | collectionView.reloadData() |
| | | |
| | | if self.answterCount == 3{ |
| | | self.rootViewModel.answerItems[self.page] = self.listen1Model |
| | | NotificationCenter.default.post(name: NextLession_Noti, object: nil) |
| | | VoicePlayer.share().playerEnd() |
| | | return |
| | | } |
| | | } |
| | | |
| | | func playing() { |
| | | |
| | | } |
| | | } |
| | |
| | | return collection |
| | | }() |
| | | |
| | | private var voicePlayer = VoicePlayer.share() |
| | | |
| | | required init(page:Int,listen4Model:Listen4Model){ |
| | | super.init(nibName: nil, bundle: nil) |
| | | self.page = page |
| | | self.listen4Model = listen4Model |
| | | self.listen4Model.data.shuffle() |
| | | } |
| | | |
| | | required init?(coder: NSCoder) { |
| | | fatalError("init(coder:) has not been implemented") |
| | | } |
| | | |
| | | func restore(){ |
| | | |
| | | answerCount = 0 |
| | | answerIndex = nil |
| | | for subView in view.subviews{ |
| | | if subView is Lesson_4_AnswerView{ |
| | | subView.removeFromSuperview() |
| | | } |
| | | } |
| | | |
| | | setUI() |
| | | collectionView.reloadData() |
| | | } |
| | | |
| | | override func viewDidLoad() { |
| | | super.viewDidLoad() |
| | | |
| | | VoicePlayer.share().playEnd { |
| | | print("播放完成") |
| | | } |
| | | } |
| | | |
| | | override func viewDidAppear(_ animated: Bool) { |
| | | super.viewDidAppear(animated) |
| | | voicePlayer.delegate = self |
| | | } |
| | | |
| | | override func viewDidDisappear(_ animated: Bool) { |
| | | super.viewDidDisappear(animated) |
| | | voicePlayer.delegate = nil |
| | | } |
| | | |
| | | |
| | | override func setUI() { |
| | | super.setUI() |
| | | |
| | | collectionView.delegate = self |
| | | collectionView.dataSource = self |
| | | collectionView.showsVerticalScrollIndicator = false |
| | | collectionView.backgroundColor = .clear |
| | | view.addSubview(collectionView) |
| | | if !view.subviews.contains(collectionView){ |
| | | collectionView.delegate = self |
| | | collectionView.dataSource = self |
| | | collectionView.showsVerticalScrollIndicator = false |
| | | collectionView.backgroundColor = .clear |
| | | view.addSubview(collectionView) |
| | | } |
| | | |
| | | collectionView.snp.makeConstraints { make in |
| | | make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(0) |
| | | make.left.equalTo(164) |
| | |
| | | alertError(msg: "请先听题");return |
| | | } |
| | | |
| | | stackView.removeArrangedSubviews() |
| | | for v in stackView.subviews{ |
| | | v.removeFromSuperview() |
| | | } |
| | | |
| | | if !view.subviews.contains(stackView){ |
| | | view.addSubview(stackView) |
| | |
| | | } |
| | | |
| | | |
| | | let answerId = listen4Model.data[viewModel.selectIndex.value!.section].answerSubject |
| | | let answerId = listen4Model.data[viewModel.selectIndex.value!.section].subject |
| | | var tempVoiceArray = [String]() |
| | | for v in listen4Model.data[viewModel.selectIndex.value!.section].subjectList{ |
| | | if v.id == answerId{ |
| | |
| | | |
| | | var answerModel:Listen1SubModel? |
| | | for (index,v) in (listen4Model.data[viewModel.selectIndex.value!.section].subjectList).enumerated(){ |
| | | if v.id == listen4Model.data[viewModel.selectIndex.value!.section].answerSubject{ |
| | | if v.id == listen4Model.data[viewModel.selectIndex.value!.section].subject{ |
| | | answerModel = v |
| | | }else{ |
| | | answerIndex = IndexPath(row: index, section: viewModel.selectIndex.value!.section) |
| | | } |
| | | } |
| | |
| | | answerType = .fail |
| | | rootViewModel.errorNum += 1 |
| | | } |
| | | VoicePlayer.share().playerEnd() |
| | | voicePlayer.playerEnd() |
| | | |
| | | switch answerType { |
| | | case .success: |
| | |
| | | copyView.frame = CGRect(origin: newRect1.origin, size: CGSize(width: 152, height: 52)) |
| | | } completion: { _ in |
| | | self.viewModel.selectIndex.accept(nil) |
| | | self.stackView.removeArrangedSubviews() |
| | | for v in self.stackView.subviews{ |
| | | v.removeFromSuperview() |
| | | } |
| | | self.stackView.layoutIfNeeded() |
| | | |
| | | //回答完成,下一答题 |
| | | if self.answerCount == 2{ |
| | | self.rootViewModel.answerItems[self.page] = self.listen4Model |
| | | VoicePlayer.share().playerEnd() |
| | | NotificationCenter.default.post(name: NextLession_Noti, object: nil);return |
| | | self.voicePlayer.playerEnd() |
| | | NotificationCenter.default.post(name: NextLession_Noti, object: nil) |
| | | self.voicePlayer.playerEnd() |
| | | return |
| | | } |
| | | } |
| | | } |
| | |
| | | func numberOfSections(in collectionView: UICollectionView) -> Int { |
| | | return listen4Model.data.count |
| | | } |
| | | } |
| | | |
| | | extension HomeListenFight_lesson_4_VC:VoicePlayerDelegate{ |
| | | func playComplete() { |
| | | |
| | | } |
| | | |
| | | func playing() { |
| | | |
| | | } |
| | | } |
| | |
| | | private var playVoiceAt:Int? //播放声音的View |
| | | private var playVoiceRealAt:Int? //播放声音的View -被乱序后,真实Index |
| | | var rootViewModel:HomeListenFightViewModel! |
| | | private var voicePlayer = VoicePlayer.share() |
| | | |
| | | private lazy var collectionView:UICollectionView = { |
| | | let flowLayout = UICollectionViewFlowLayout() |
| | |
| | | super.init(nibName: nil, bundle: nil) |
| | | self.page = page |
| | | self.listen1Model = listen1Model |
| | | self.listen1Model.subjectList.shuffle() |
| | | } |
| | | |
| | | required init?(coder: NSCoder) { |
| | |
| | | super.viewDidLoad() |
| | | |
| | | collectionView.reloadData() |
| | | } |
| | | |
| | | |
| | | override func viewDidAppear(_ animated: Bool) { |
| | | super.viewDidAppear(animated) |
| | | voicePlayer.delegate = self |
| | | } |
| | | |
| | | override func viewDidDisappear(_ animated: Bool) { |
| | | super.viewDidDisappear(animated) |
| | | voicePlayer.delegate = nil |
| | | } |
| | | |
| | | override func setUI() { |
| | |
| | | } |
| | | |
| | | override func setRx() { |
| | | // viewModel.selectIndex.subscribe(onNext: {indexPath in |
| | | // if let index = indexPath{ |
| | | // |
| | | // } |
| | | // }).disposed(by: disposeBag) |
| | | |
| | | } |
| | | |
| | | func restore(){ |
| | | viewModel.answerType.accept(.none) |
| | | answterCount = 0 |
| | | playVoiceAt = nil |
| | | playVoiceRealAt = nil |
| | | |
| | | for subV in view.subviews{ |
| | | if subV is VoiceHandleView{ |
| | | subV.removeFromSuperview() |
| | | } |
| | | } |
| | | setUI() |
| | | collectionView.reloadData() |
| | | } |
| | | |
| | | private func setAnswerStackView(){ |
| | |
| | | } |
| | | } |
| | | |
| | | var tempArray = [StudyHandleView]() |
| | | var tempArray = [VoiceHandleView]() |
| | | for (i,value) in listen1Model.subjectList.enumerated(){ |
| | | let answerView = StudyHandleView.jq_loadNibView() |
| | | let answerView = VoiceHandleView() |
| | | answerView.listenType = .lesson5 |
| | | answerView.view_choose.isHidden = true |
| | | answerView.tag = 1000+i |
| | | answerView.playAt {[weak self] index in |
| | | print("--->\(index)--\(answerView.frame.origin.x / 248)") |
| | |
| | | self?.playVoiceAt = index - 1000 |
| | | self?.showHintText(true) |
| | | } |
| | | answerView.vioceSoundUrl = value.correct |
| | | answerView.playUrl = value.correct |
| | | answerView.snp.makeConstraints { make in |
| | | make.width.equalTo(159) |
| | | make.height.equalTo(52) |
| | |
| | | answerType = .fail |
| | | } |
| | | |
| | | let tempSubV = stackView.arrangedSubviews[self.playVoiceRealAt!] as! StudyHandleView |
| | | let tempSubV = stackView.arrangedSubviews[self.playVoiceRealAt!] as! VoiceHandleView |
| | | |
| | | switch answerType { |
| | | case .success: |
| | | answterCount += 1 |
| | | rootViewModel.correctNum += 1 |
| | | viewModel.answerType.accept(.success) |
| | | DispatchQueue.main.asyncAfter(deadline: .now()+0.4) { |
| | | let copyView = tempSubV.copyView() |
| | | copyView.view_choose.isHidden = true |
| | | tempSubV.alpha = 0 |
| | | let newRect = tempSubV.convert(tempSubV.bounds, to: self.view) |
| | | copyView.frame = CGRect(origin: newRect.origin, size: CGSize(width: 159, height: 52)) |
| | | self.view.addSubview(copyView) |
| | | |
| | | let copyView = tempSubV.copyView() |
| | | copyView.listenType = .lesson5 |
| | | copyView.playUrl = selectAnswer.correct |
| | | let newRect = tempSubV.convert(tempSubV.bounds, to: self.view) |
| | | copyView.frame = CGRect(origin: newRect.origin, size: CGSize(width: 159, height: 52)) |
| | | self.view.addSubview(copyView) |
| | | tempSubV.alpha = 0 |
| | | |
| | | DispatchQueue.main.asyncAfter(deadline: .now()+0.4) { |
| | | |
| | | //获取Cell的顶部试图 |
| | | let flowLayout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout |
| | |
| | | copyView.frame = CGRect(origin: newRect1.origin, size: CGSize(width: flowLayout.itemSize.width - 10 , height: 40)) |
| | | |
| | | }completion: { _ in |
| | | copyView.playingAction() |
| | | self.playVoiceRealAt = nil |
| | | self.playVoiceAt = nil |
| | | |
| | | if self.answterCount == 4{ |
| | | self.rootViewModel.answerItems[self.page] = self.listen1Model |
| | | VoicePlayer.share().playerEnd() |
| | | NotificationCenter.default.post(name: NextLession_Noti, object: nil) |
| | | } |
| | | self.collectionView.reloadData() |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | } |
| | | |
| | | extension HomeListenFight_lesson_5_VC:VoicePlayerDelegate{ |
| | | func playComplete() { |
| | | for subV in stackView.arrangedSubviews as! [VoiceHandleView]{ |
| | | subV.resetView() |
| | | } |
| | | |
| | | DispatchQueue.main.asyncAfter(deadline: .now()+0.4) { |
| | | if self.answterCount >= 4{ |
| | | self.rootViewModel.answerItems[self.page] = self.listen1Model |
| | | self.voicePlayer.playerEnd() |
| | | NotificationCenter.default.post(name: NextLession_Noti, object: nil) |
| | | } |
| | | } |
| | | } |
| | | |
| | | func playing() { |
| | | |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | import UIKit |
| | | |
| | | let Refresh_ListenSchedule_Noti = Notification.Name.init("Refresh_ListenSchedule") |
| | | |
| | | class HomeListenSubVC: BaseVC { |
| | | |
| | | private var page:Int! |
| | |
| | | override func viewDidLoad() { |
| | | super.viewDidLoad() |
| | | navigationItem.titleView = UIView() |
| | | Services.studySchedule(week: week, day: page + 1).subscribe(onNext: {data in |
| | | self.studyScheduleModel = data.data |
| | | self.tableView.reloadData() |
| | | }).disposed(by: disposeBag) |
| | | getData() |
| | | } |
| | | |
| | | override func setUI() { |
| | |
| | | make.edges.equalToSuperview() |
| | | } |
| | | } |
| | | |
| | | override func setRx() { |
| | | NotificationCenter.default.rx.notification(Refresh_ListenSchedule_Noti).take(until: self.rx.deallocated).subscribe(onNext: {_ in |
| | | self.getData() |
| | | }).disposed(by: disposeBag) |
| | | } |
| | | |
| | | private func getData(){ |
| | | Services.studySchedule(week: week, day: page + 1).subscribe(onNext: {data in |
| | | self.studyScheduleModel = data.data |
| | | self.tableView.reloadData() |
| | | }).disposed(by: disposeBag) |
| | | } |
| | | } |
| | | |
| | | extension HomeListenSubVC:UITableViewDelegate{ |
| | |
| | | if page <= 4{ |
| | | if indexPath.row == 0{ |
| | | //听音选图 |
| | | Services.listenSelectPicture(day:day, quarter: quarter, week: week).subscribe(onNext: {result in |
| | | Services.listenSelectPicture(day:day, quarter: quarter, week: week).subscribe(onNext: {[weak self] result in |
| | | guard let weakSelf = self else { return } |
| | | if let data = result.data{ |
| | | let fightVC = HomeListenFightVC(listenType: .lesson1) |
| | | let fightVC = HomeListenFightVC(listenType: .lesson1,quarter:weakSelf.quarter,week: weakSelf.week,day:day) |
| | | fightVC.title = ListenType.lesson1.rawTitle |
| | | fightVC.data = data |
| | | fightVC.studyScheduleModel = self?.studyScheduleModel |
| | | JQ_currentViewController().jq_push(vc:fightVC) |
| | | } |
| | | }).disposed(by: disposeBag) |
| | |
| | | |
| | | if indexPath.row == 1{ |
| | | //看图选音 |
| | | Services.pictureSelectVoice(day: day, quarter: quarter, week: week).subscribe(onNext: {result in |
| | | Services.pictureSelectVoice(day: day, quarter: quarter, week: week).subscribe(onNext: {[weak self] result in |
| | | guard let weakSelf = self else { return } |
| | | if let data = result.data{ |
| | | let fightVC = HomeListenFightVC(listenType: .lesson2) |
| | | let fightVC = HomeListenFightVC(listenType: .lesson2,quarter:weakSelf.quarter,week: weakSelf.week,day:day) |
| | | fightVC.title = ListenType.lesson2.rawTitle |
| | | fightVC.data = data |
| | | fightVC.studyScheduleModel = self?.studyScheduleModel |
| | | JQ_currentViewController().jq_push(vc:fightVC) |
| | | } |
| | | }).disposed(by: disposeBag) |
| | |
| | | |
| | | if indexPath.row == 2{ |
| | | //归纳排除 |
| | | Services.induceExclude(day: day, quarter: quarter, week: week).subscribe(onNext: {result in |
| | | Services.induceExclude(day: day, quarter: quarter, week: week).subscribe(onNext: {[weak self] result in |
| | | guard let weakSelf = self else { return } |
| | | if let data = result.data{ |
| | | let fightVC = HomeListenFightVC(listenType: .lesson3) |
| | | let fightVC = HomeListenFightVC(listenType: .lesson3,quarter:weakSelf.quarter,week: weakSelf.week,day:day) |
| | | fightVC.title = ListenType.lesson3.rawTitle |
| | | fightVC.data = data |
| | | fightVC.studyScheduleModel = self?.studyScheduleModel |
| | | JQ_currentViewController().jq_push(vc: fightVC) |
| | | } |
| | | }).disposed(by: disposeBag) |
| | |
| | | |
| | | if indexPath.row == 3{ |
| | | //有问有答 |
| | | Services.questionsAndAnswers(day: day, quarter: quarter, week: week).subscribe(onNext: {result in |
| | | Services.questionsAndAnswers(day: day, quarter: quarter, week: week).subscribe(onNext: {[weak self] result in |
| | | guard let weakSelf = self else { return } |
| | | if let data = result.data{ |
| | | let fightVC = HomeListenFightVC(listenType: .lesson4) |
| | | let fightVC = HomeListenFightVC(listenType: .lesson4,quarter:weakSelf.quarter,week: weakSelf.week,day:day) |
| | | fightVC.title = ListenType.lesson4.rawTitle |
| | | fightVC.data = data |
| | | fightVC.studyScheduleModel = self?.studyScheduleModel |
| | | JQ_currentViewController().jq_push(vc: fightVC) |
| | | } |
| | | }).disposed(by: disposeBag) |
| | |
| | | |
| | | if indexPath.row == 4{ |
| | | //音图相配 |
| | | Services.pictureMateVoice(day: day, quarter: quarter, week: week).subscribe(onNext: {result in |
| | | Services.pictureMateVoice(day: day, quarter: quarter, week: week).subscribe(onNext: {[weak self] result in |
| | | guard let weakSelf = self else { return } |
| | | if let data = result.data{ |
| | | let fightVC = HomeListenFightVC(listenType: .lesson5) |
| | | let fightVC = HomeListenFightVC(listenType: .lesson5,quarter:weakSelf.quarter,week: weakSelf.week,day:day) |
| | | fightVC.title = ListenType.lesson5.rawTitle |
| | | fightVC.data = data |
| | | fightVC.studyScheduleModel = self?.studyScheduleModel |
| | | JQ_currentViewController().jq_push(vc: fightVC) |
| | | } |
| | | }).disposed(by: disposeBag) |
| | |
| | | //自主游戏 |
| | | if page == 5{ |
| | | if indexPath.row == 0{ |
| | | let fightVC = HomeListenFightVC(listenType: .game1,quarter: quarter,week: week) |
| | | let fightVC = HomeListenFightVC(listenType: .game1,quarter: quarter,week: week,day: day) |
| | | fightVC.title = ListenType.game1.rawTitle |
| | | JQ_currentViewController().jq_push(vc:fightVC) |
| | | } |
| | | if indexPath.row == 1{ |
| | | Services.gameMemory(quarter: quarter, week: week).subscribe(onNext: {result in |
| | | Services.gameMemory(quarter: quarter, week: week).subscribe(onNext: {[weak self]result in |
| | | guard let weakSelf = self else { return } |
| | | if let data = result.data{ |
| | | let fightVC = HomeListenFightVC(listenType: .game2) |
| | | let fightVC = HomeListenFightVC(listenType: .game2,quarter: weakSelf.quarter,week: weakSelf.week,day: day) |
| | | fightVC.title = ListenType.game2.rawTitle |
| | | fightVC.data = data |
| | | JQ_currentViewController().jq_push(vc: fightVC) |
| | |
| | | //听故事 |
| | | if page == 6{ |
| | | if indexPath.row == 0{ |
| | | Services.lookpictureDbu(quarter: quarter, week: week).subscribe(onNext: {result in |
| | | Services.lookpictureDbu(quarter: quarter, week: week).subscribe(onNext: {[weak self]result in |
| | | guard let weakSelf = self else { return } |
| | | if let data = result.data{ |
| | | let fightVC = HomeListenFightVC(listenType: .story1) |
| | | let fightVC = HomeListenFightVC(listenType: .story1,quarter: weakSelf.quarter,week: weakSelf.week,day: day) |
| | | fightVC.title = ListenType.story1.rawTitle |
| | | fightVC.data = data |
| | | JQ_currentViewController().jq_push(vc: fightVC) |
| | |
| | | }).disposed(by: disposeBag) |
| | | } |
| | | if indexPath.row == 1{ |
| | | Services.frameworkMemory(quarter: quarter, week: week).subscribe(onNext: {result in |
| | | Services.frameworkMemory(quarter: quarter, week: week).subscribe(onNext: {[weak self]result in |
| | | guard let weakSelf = self else { return } |
| | | if let data = result.data{ |
| | | let fightVC = HomeListenFightVC(listenType: .story2) |
| | | let fightVC = HomeListenFightVC(listenType: .story2,quarter: weakSelf.quarter,week: weakSelf.week,day: day) |
| | | fightVC.title = ListenType.story2.rawTitle |
| | | fightVC.data = data |
| | | JQ_currentViewController().jq_push(vc: fightVC) |
| | |
| | | |
| | | if page == 5{ |
| | | cell.view_bg2.isHidden = true |
| | | cell.view_state.isHidden = true |
| | | switch indexPath.row { |
| | | case 0: |
| | | cell.label_title.text = "自主游戏1-超级听力" |
| | |
| | | |
| | | if page == 6{ |
| | | cell.view_bg2.isHidden = true |
| | | cell.view_state.isHidden = true |
| | | switch indexPath.row { |
| | | case 0: |
| | | cell.label_title.text = "自主故事1-看图配音" |
| | |
| | | class HomeListenVC: BaseVC { |
| | | |
| | | //限制后面的点击:天数(1开始) |
| | | private var limitDay = 7 |
| | | private var limitDay = 1 |
| | | private var quarter:Int! |
| | | private var week:Int! |
| | | |
| | |
| | | |
| | | override func viewDidLoad() { |
| | | super.viewDidLoad() |
| | | |
| | | Services.studySchedule(week: week, day: 1).subscribe(onNext: {data in |
| | | self.limitDay = data.data?.day ?? 0 |
| | | |
| | | #if DEBUG |
| | | self.limitDay = 5 |
| | | #endif |
| | | |
| | | if self.limitDay == 5{ |
| | | self.limitDay = Int.max |
| | | } |
| | | |
| | | for (index,titleL) in (self.menu.subviews.last?.subviews[1].subviews ?? []).filter({$0 is UIButton}).enumerated(){ |
| | | if let btn = titleL as? UIButton{ |
| | | btn.setTitleColor(index < (self.limitDay - 1) ? .black:.black.withAlphaComponent(0.33), for: .normal) |
| | | self.menu.setEnabled(index < (self.limitDay - 1), forItemAt: UInt(index)) |
| | | } |
| | | } |
| | | self.pageVC.reloadData() |
| | | }).disposed(by: disposeBag) |
| | | } |
| | | |
| | | override func setUI() { |
| | |
| | | make.bottom.equalTo(self.view.safeAreaLayoutGuide.snp.bottom) |
| | | } |
| | | |
| | | for (index,titleL) in (menu.subviews.last?.subviews[1].subviews ?? []).filter({$0 is UIButton}).enumerated(){ |
| | | if index >= limitDay{ |
| | | for (index,titleL) in (self.menu.subviews.last?.subviews[1].subviews ?? []).filter({$0 is UIButton}).enumerated(){ |
| | | if index >= (self.limitDay - 1){ |
| | | if let btn = titleL as? UIButton{ |
| | | btn.setTitleColor(.black.withAlphaComponent(0.33), for: .normal) |
| | | menu.setEnabled(false, forItemAt: UInt(index)) |
| | | self.menu.setEnabled(false, forItemAt: UInt(index)) |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | } |
| | | |
| | | |
| | | @IBAction func backAction(_ sender: UIButton) { |
| | | self.navigationController?.popToRootViewController(animated: true) |
| | | } |
| | | |
| | | @IBAction func lookOrderAction(_ sender: UIButton) { |
| | | self.navigationController?.popViewController(animated: true, { |
| | | let vc = ExchangeRecordHistoryVC() |
| | | vc.title = "兑换记录" |
| | | JQ_currentNavigationController().pushViewController(vc) |
| | | }) |
| | | } |
| | | |
| | | } |
| | |
| | | <real key="value" value="1"/> |
| | | </userDefinedRuntimeAttribute> |
| | | </userDefinedRuntimeAttributes> |
| | | <connections> |
| | | <action selector="backAction:" destination="-1" eventType="touchUpInside" id="vZ0-kK-S8J"/> |
| | | </connections> |
| | | </button> |
| | | <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="gZA-Zs-XKS"> |
| | | <rect key="frame" x="218" y="0.0" width="124" height="39.5"/> |
| | |
| | | <real key="value" value="4"/> |
| | | </userDefinedRuntimeAttribute> |
| | | </userDefinedRuntimeAttributes> |
| | | <connections> |
| | | <action selector="lookOrderAction:" destination="-1" eventType="touchUpInside" id="ij2-2V-R5z"/> |
| | | </connections> |
| | | </button> |
| | | </subviews> |
| | | </stackView> |
| | |
| | | @IBOutlet weak var label_footNeedCoin: UILabel! |
| | | |
| | | private var viewModel = MarketContentViewModel() |
| | | private var recipientId:Int? // 地址ID |
| | | |
| | | required init(viewModel:MarketContentViewModel) { |
| | | super.init(nibName: nil, bundle: nil) |
| | |
| | | |
| | | Services.addressList().subscribe(onNext: {[weak self]result in |
| | | self?.viewModel.address.accept(result.data ?? []) |
| | | |
| | | if result.data?.count == 0{ |
| | | self?.label_address.text = "新建收货地址" |
| | | self?.label_address_info.isHidden = true |
| | | return |
| | | } |
| | | |
| | | if let first = result.data?.filter({$0.isDefault == 1}).first{ |
| | | self?.label_address.text = first.address |
| | | self?.label_address_info.text = first.recipient + "|" + first.recipientPhone |
| | | self?.recipientId = first.id |
| | | }else{ |
| | | self?.label_address.text = "新建收货地址" |
| | | self?.label_address.text = "选择收货地址" |
| | | self?.label_address_info.isHidden = true |
| | | } |
| | | }).disposed(by: disposeBag) |
| | |
| | | } |
| | | |
| | | @IBAction func addressAction(_ sender: Any) { |
| | | if viewModel.address.value.filter({$0.isDefault == 1}).count > 0{ |
| | | let vc = AddressManageVC(type: .choose) |
| | | vc.title = "地址管理" |
| | | push(vc: vc) |
| | | }else{ |
| | | |
| | | if viewModel.address.value.count == 0{ |
| | | let vc = AddressManageVC(type: .handle) |
| | | vc.title = "地址管理" |
| | | push(vc: vc) |
| | | return |
| | | } |
| | | |
| | | let vc = AddressManageVC(type: .choose) |
| | | vc.title = "地址管理" |
| | | vc.chooseAddress {[weak self] m in |
| | | self?.label_address.text = m.address |
| | | self?.label_address_info.text = m.recipient + "|" + m.recipientPhone |
| | | self?.recipientId = m.id |
| | | self?.label_address_info.isHidden = false |
| | | } |
| | | push(vc: vc) |
| | | } |
| | | |
| | | @IBAction func addNumAction(_ sender: UIButton) { |
| | |
| | | |
| | | @IBAction func exchangeAction(_ sender: UIButton) { |
| | | |
| | | guard viewModel.address.value.filter({$0.isDefault == 1}).count != 0 else{ |
| | | CommonAlertView.show(content: "请先设置收货地址") { |
| | | let vc = AddressManageVC(type: .handle) |
| | | guard recipientId != nil else{ |
| | | CommonAlertView.show(content: "请先选择收货地址") { |
| | | let vc = AddressManageVC(type: .choose) |
| | | vc.title = "地址管理" |
| | | vc.chooseAddress {[weak self] m in |
| | | self?.label_address.text = m.address |
| | | self?.label_address_info.text = m.recipient + "|" + m.recipientPhone |
| | | self?.recipientId = m.id |
| | | self?.label_address_info.isHidden = false |
| | | } |
| | | self.push(vc: vc) |
| | | } |
| | | return |
| | |
| | | let goodsId = self.viewModel.detailModel.value!.good!.id |
| | | let num = self.viewModel.number.value |
| | | let orderNumber = self.viewModel.detailModel.value?.orderNumber ?? "" |
| | | let recipientId = self.viewModel.detailModel.value?.recipient?.id ?? 0 |
| | | let recipientId = self.recipientId |
| | | |
| | | Services.goodsExchangeStudy(goodsId: goodsId, number: num, orderNumber: orderNumber, recipientId: recipientId, remark: self.textView_remark.text!).subscribe(onNext: {_ in |
| | | Services.goodsExchangeStudy(goodsId: goodsId, number: num, orderNumber: orderNumber, recipientId: recipientId!, remark: self.textView_remark.text!).subscribe(onNext: {_ in |
| | | let vc = ExchangeResultVC(resultType: .success) |
| | | vc.title = "商品详情" |
| | | self.push(vc: vc) |
| | |
| | | // |
| | | |
| | | import UIKit |
| | | import RxSwift |
| | | |
| | | class GoodsItemTCell: UITableViewCell { |
| | | |
| | |
| | | @IBOutlet weak var btn_state: UIButton! |
| | | @IBOutlet weak var label_coin: UILabel! |
| | | @IBOutlet weak var img_cover: UIImageView! |
| | | |
| | | @IBOutlet weak var view_container: UIView! |
| | | |
| | | private var exchangeRecordModel:ExchangeRecordModel? |
| | | private var disposeBag = DisposeBag() |
| | | |
| | | override func awakeFromNib() { |
| | | super.awakeFromNib() |
| | | selectionStyle = .none |
| | |
| | | } |
| | | |
| | | func setModel(_ model:ExchangeRecordModel){ |
| | | exchangeRecordModel = model |
| | | label_goodsNum.text = "商品数量:\(model.count)" |
| | | label_coin.text = "\(model.integral)积分" |
| | | label_goodsName.text = model.goodsName |
| | |
| | | @IBAction func handleAction(_ sender: UIButton) { |
| | | let vc = AddressManageVC(type: .choose) |
| | | vc.title = "修改地址" |
| | | vc.chooseAddress { m in |
| | | CommonAlertView.show(content: "确认修改地址?") {[weak self] () in |
| | | guard let weakSelf = self else { return } |
| | | if weakSelf.exchangeRecordModel?.consigneeAddress == m.address && weakSelf.exchangeRecordModel?.consigneeName == m.recipient && weakSelf.exchangeRecordModel?.consigneePhone == m.recipientPhone{ |
| | | alertError(msg: "修改地址信息与原地址信息相同");return |
| | | } |
| | | |
| | | Services.updateOrderAddress(orderId: weakSelf.exchangeRecordModel!.goodsId, recipientId: m.id).subscribe(onNext: {data in |
| | | alertSuccess(msg: "修改成功") |
| | | |
| | | }).disposed(by: weakSelf.disposeBag) |
| | | } |
| | | } |
| | | JQ_currentViewController().jq_push(vc: vc) |
| | | } |
| | | |
| | |
| | | var emuple = [String]() |
| | | if date.hour > 0{emuple.append("\(date.hour)小时")} |
| | | if date.minute > 0{emuple.append("\(date.minute)分钟")} |
| | | if date.second > 0{emuple.append("\(date.second)秒")} |
| | | label_3.text = emuple.joined(separator: "") |
| | | label_4.text = "\(studyGamesRecordModel.accuracy)%" |
| | | } |
| | |
| | | private var tableView:UITableView! |
| | | private var addressManageType:AddressManageType! |
| | | private var viewModel = AddressManageViewModel() |
| | | private var clouse:((AddressModel)->Void)? |
| | | |
| | | required init(type:AddressManageType) { |
| | | super.init(nibName: nil, bundle: nil) |
| | |
| | | viewModel.configure(tableView) |
| | | viewModel.beginRefresh() |
| | | } |
| | | |
| | | |
| | | override func setUI() { |
| | | super.setUI() |
| | |
| | | vc.title = "地址管理" |
| | | JQ_currentViewController().jq_push(vc: vc) |
| | | } |
| | | |
| | | func chooseAddress(_ clouse:@escaping(AddressModel)->Void){ |
| | | self.clouse = clouse |
| | | } |
| | | } |
| | | |
| | | extension AddressManageVC:UITableViewDelegate{ |
| | | |
| | | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { |
| | | if addressManageType == .choose{ |
| | | let model = viewModel.dataSource.value[indexPath.row] |
| | | clouse?(model) |
| | | self.navigationController?.popViewController() |
| | | } |
| | | } |
| | | } |
| | | |
| | | extension AddressManageVC:UITableViewDataSource{ |
| | |
| | | import UIKit |
| | | import RxSwift |
| | | |
| | | let Refresh_MarketExchange_Noti = Notification.Name.init("Refresh_MarketExchange_Noti") |
| | | |
| | | class ExchangeRecordViewModel:RefreshModel<ExchangeRecordModel>{ |
| | | override func api() -> (Observable<BaseResponse<[ExchangeRecordModel]>>)? { |
| | | return Services.exchangeRecord() |
| | |
| | | make.bottom.equalTo(self.view.safeAreaLayoutGuide.snp.bottom).offset(-5) |
| | | } |
| | | } |
| | | |
| | | override func setRx() { |
| | | NotificationCenter.default.rx.notification(Refresh_MarketExchange_Noti).take(until: self.rx.deallocated).subscribe(onNext: {_ in |
| | | self.viewModel.beginRefresh() |
| | | }).disposed(by: disposeBag) |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | func copyView()->StudyHandleView{ |
| | | let copyV = StudyHandleView.jq_loadNibView() |
| | | copyV.bounds = self.bounds |
| | | copyV.tag = self.tag |
| | | copyV.vioceSoundUrl = self.vioceSoundUrl |
| | | return copyV |
| | | } |
| | | |
| | |
| | | |
| | | var playUrl:String? |
| | | var listenType:ListenType? |
| | | private var playAtClouse:((Int)->Void)? |
| | | |
| | | override init(frame: CGRect) { |
| | | super.init(frame: frame) |
| | |
| | | fatalError("init(coder:) has not been implemented") |
| | | } |
| | | |
| | | func copyView()->VoiceHandleView{ |
| | | let copyView = VoiceHandleView() |
| | | copyView.listenType = self.listenType |
| | | copyView.playUrl = self.playUrl |
| | | copyView.frame = self.frame |
| | | return copyView |
| | | } |
| | | |
| | | func resetView(){ |
| | | img_hint.isHidden = false |
| | | btn_play.isHidden = false |
| | | img_hint_playing.isHidden = true |
| | | } |
| | | |
| | | func playing(){ |
| | | img_hint.isHidden = true |
| | | btn_play.isHidden = true |
| | | img_hint_playing.isHidden = false |
| | | } |
| | | |
| | | func playAt(_ clouse:@escaping(Int)->Void){ |
| | | self.playAtClouse = clouse |
| | | } |
| | | |
| | | @objc func playingAction(){ |
| | | if let url = playUrl{ |
| | | playAtClouse?(self.tag) |
| | | VoicePlayer.share().playerAt(url: url) |
| | | img_hint.isHidden = true |
| | | btn_play.isHidden = true |
| | | img_hint_playing.isHidden = false |
| | | playing() |
| | | } |
| | | } |
| | | |
| | |
| | | return NetworkRequest.request(params: params, method: .post,encoding: JSONEncoding.default, progress: true) |
| | | } |
| | | |
| | | class func exitLearning(type:Int,week:Int,day:Int,teamIds:[String],topicIds:[String])->Observable<BaseResponse<SimpleModel>>{ |
| | | let params = ParamsAppender.build(url: All_Url) |
| | | params.interface(url: "/study/base/study/exitLearning") |
| | | .append(key: "week", value: week) |
| | | .append(key: "day", value: day) |
| | | .append(key: "teamIds", value: teamIds.joined(separator: ",")) |
| | | .append(key: "topicIds", value: topicIds.joined(separator: ",")) |
| | | .append(key: "type", value: type) |
| | | return NetworkRequest.request(params: params, method: .post,encoding: JSONEncoding.default, progress: true) |
| | | } |
| | | |
| | | class func updateOrderAddress(orderId:Int,recipientId:Int)->Observable<BaseResponse<SimpleModel>>{ |
| | | let params = ParamsAppender.build(url: All_Url) |
| | | params.interface(url: "/goods/base/goods/updateOrderAddress") |
| | | .append(key: "orderId", value: orderId) |
| | | .append(key: "recipientId", value: recipientId) |
| | | return NetworkRequest.request(params: params, method: .get, progress: true) |
| | | } |
| | | } |
| | | |
| | | extension Services{ |