DolphinEnglishLearnStudent.xcodeproj/project.pbxproj | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
DolphinEnglishLearnStudent/Assets.xcassets/Bg/bg_card.imageset/Contents.json | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
DolphinEnglishLearnStudent/Assets.xcassets/Bg/bg_card.imageset/bg_card.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
DolphinEnglishLearnStudent/Assets.xcassets/Bg/bg_card.imageset/bg_card@2x.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_CCell.swift | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_CCell.xib | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_Pocket_CCell.swift | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_1_VC.swift | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_2_VC.swift | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
DolphinEnglishLearnStudent.xcodeproj/project.pbxproj
@@ -51,6 +51,7 @@ 130278992BFD9FBF00DDCE81 /* Home_1_TCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130278932BFD9FBF00DDCE81 /* Home_1_TCell.swift */; }; 1302789A2BFD9FBF00DDCE81 /* AddressManageTCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130278942BFD9FBF00DDCE81 /* AddressManageTCell.swift */; }; 1302789B2BFD9FBF00DDCE81 /* GoodsItemTCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130278952BFD9FBF00DDCE81 /* GoodsItemTCell.swift */; }; 130A2C812C07075B008463B2 /* ListenFight_Game_Pocket_CCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130A2C7F2C07075B008463B2 /* ListenFight_Game_Pocket_CCell.swift */; }; 1316A22E2C05CE5900BE6CAA /* GameBeginTipView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1316A22D2C05CE5900BE6CAA /* GameBeginTipView.swift */; }; 1316A2302C05CE6100BE6CAA /* GameBeginTipView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1316A22F2C05CE6100BE6CAA /* GameBeginTipView.xib */; }; 133386382C007E91002EE788 /* HomeListenFight_lesson_2_VC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133386372C007E91002EE788 /* HomeListenFight_lesson_2_VC.swift */; }; @@ -145,6 +146,7 @@ 130278932BFD9FBF00DDCE81 /* Home_1_TCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Home_1_TCell.swift; sourceTree = "<group>"; }; 130278942BFD9FBF00DDCE81 /* AddressManageTCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressManageTCell.swift; sourceTree = "<group>"; }; 130278952BFD9FBF00DDCE81 /* GoodsItemTCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GoodsItemTCell.swift; sourceTree = "<group>"; }; 130A2C7F2C07075B008463B2 /* ListenFight_Game_Pocket_CCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListenFight_Game_Pocket_CCell.swift; sourceTree = "<group>"; }; 1316A22D2C05CE5900BE6CAA /* GameBeginTipView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameBeginTipView.swift; sourceTree = "<group>"; }; 1316A22F2C05CE6100BE6CAA /* GameBeginTipView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GameBeginTipView.xib; sourceTree = "<group>"; }; 133386372C007E91002EE788 /* HomeListenFight_lesson_2_VC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeListenFight_lesson_2_VC.swift; sourceTree = "<group>"; }; @@ -398,6 +400,7 @@ 13CDF44B2C056A6900E8D4FD /* ListenFight_lesson_4_CCell.xib */, 13397D942C05EA9D003440F9 /* ListenFight_Game_CCell.swift */, 13397D952C05EA9D003440F9 /* ListenFight_Game_CCell.xib */, 130A2C7F2C07075B008463B2 /* ListenFight_Game_Pocket_CCell.swift */, ); path = CCell; sourceTree = "<group>"; @@ -691,6 +694,7 @@ 130278422BFD978900DDCE81 /* Enums.swift in Sources */, 13EEB8912BFED3F3002996FC /* AwardListView.swift in Sources */, 130278412BFD978900DDCE81 /* Config.swift in Sources */, 130A2C812C07075B008463B2 /* ListenFight_Game_Pocket_CCell.swift in Sources */, 1302784A2BFD979200DDCE81 /* BaseVC.swift in Sources */, 13A830F52C041B4400BB2F23 /* ListenFight_lesson_3_CCell.swift in Sources */, 137CB4292BFF505800D32862 /* HomeListenFightVC.swift in Sources */, DolphinEnglishLearnStudent/Assets.xcassets/Bg/bg_card.imageset/Contents.json
New file @@ -0,0 +1,22 @@ { "images" : [ { "filename" : "bg_card.png", "idiom" : "universal", "scale" : "1x" }, { "filename" : "bg_card@2x.png", "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "author" : "xcode", "version" : 1 } } DolphinEnglishLearnStudent/Assets.xcassets/Bg/bg_card.imageset/bg_card.png
DolphinEnglishLearnStudent/Assets.xcassets/Bg/bg_card.imageset/bg_card@2x.png
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_CCell.swift
@@ -9,9 +9,39 @@ class ListenFight_Game_CCell: UICollectionViewCell { @IBOutlet weak var view_container: UIView! @IBOutlet weak var view_top: UIView! @IBOutlet weak var img_state: UIImageView! override func awakeFromNib() { super.awakeFromNib() // Initialization code img_state.alpha = 0 } func setState(state:Fight_lessonType){ switch state { case .success: img_state.image = UIImage(named: "icon_success") UIView.animate(withDuration: 0.6, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.4, options: .layoutSubviews) { self.img_state.alpha = 1 self.img_state.transform = .init(scaleX: 1, y: 1) } case .fail: img_state.image = UIImage(named: "icon_fail") UIView.animate(withDuration: 0.6, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.4, options: .layoutSubviews) { self.img_state.alpha = 1 self.img_state.transform = .init(scaleX: 1, y: 1) } case .none: img_state.alpha = 0 img_state.transform = .init(scaleX: 0.1, y: 0.1) } } override func layoutSubviews() { super.layoutSubviews() view_top.jq_addCorners(corner: [.topLeft,.topRight], radius: 8) jq_cornerRadius = 8 } } DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_CCell.xib
@@ -4,21 +4,83 @@ <dependencies> <deployment identifier="iOS"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22684"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="System colors in document resources" minToolsVersion="11.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <objects> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="_ListenFight_Game_CCell" id="gTV-IL-0wX" customClass="ListenFight_Game_CCell" customModule="DolphinEnglishLearnStudent" customModuleProvider="target"> <rect key="frame" x="0.0" y="0.0" width="50" height="50"/> <rect key="frame" x="0.0" y="0.0" width="165" height="210"/> <autoresizingMask key="autoresizingMask"/> <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center"> <rect key="frame" x="0.0" y="0.0" width="50" height="50"/> <rect key="frame" x="0.0" y="0.0" width="165" height="210"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <subviews> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YTs-C9-W1k"> <rect key="frame" x="5" y="5" width="155" height="200"/> <subviews> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Mmn-Bf-5Vy"> <rect key="frame" x="0.0" y="0.0" width="155" height="40"/> <color key="backgroundColor" red="0.83137254901960778" green="0.82352941176470584" blue="0.80392156862745101" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <constraints> <constraint firstAttribute="height" constant="40" id="E9b-fE-KSJ"/> </constraints> </view> <viewLayoutGuide key="safeArea" id="ZTg-uK-7eu"/> <point key="canvasLocation" x="61" y="20"/> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="qVZ-4r-nXX"> <rect key="frame" x="0.0" y="40" width="155" height="160"/> </imageView> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NUh-6J-pQi"> <rect key="frame" x="121" y="166" width="34" height="34"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <state key="normal" image="icon_fullScreen"/> </button> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_success" translatesAutoresizingMaskIntoConstraints="NO" id="dMD-2P-QwE"> <rect key="frame" x="49.5" y="74" width="56" height="56"/> <constraints> <constraint firstAttribute="height" constant="56" id="StM-MP-u9g"/> <constraint firstAttribute="width" constant="56" id="Y6Z-pZ-azs"/> </constraints> </imageView> </subviews> <color key="backgroundColor" systemColor="systemBackgroundColor"/> <constraints> <constraint firstItem="Mmn-Bf-5Vy" firstAttribute="top" secondItem="YTs-C9-W1k" secondAttribute="top" id="1Sn-gn-FxE"/> <constraint firstItem="dMD-2P-QwE" firstAttribute="centerX" secondItem="qVZ-4r-nXX" secondAttribute="centerX" id="4uB-mE-grS"/> <constraint firstAttribute="trailing" secondItem="Mmn-Bf-5Vy" secondAttribute="trailing" id="5Nt-bJ-JBK"/> <constraint firstAttribute="trailing" secondItem="NUh-6J-pQi" secondAttribute="trailing" id="LIg-1l-i3u"/> <constraint firstAttribute="trailing" secondItem="qVZ-4r-nXX" secondAttribute="trailing" id="PZ7-rB-ouR"/> <constraint firstItem="Mmn-Bf-5Vy" firstAttribute="leading" secondItem="YTs-C9-W1k" secondAttribute="leading" id="bJw-qs-aXN"/> <constraint firstItem="qVZ-4r-nXX" firstAttribute="top" secondItem="Mmn-Bf-5Vy" secondAttribute="bottom" id="grT-zb-2jJ"/> <constraint firstItem="qVZ-4r-nXX" firstAttribute="leading" secondItem="YTs-C9-W1k" secondAttribute="leading" id="sxq-IC-gv7"/> <constraint firstAttribute="bottom" secondItem="qVZ-4r-nXX" secondAttribute="bottom" id="vUB-b9-xLp"/> <constraint firstAttribute="bottom" secondItem="NUh-6J-pQi" secondAttribute="bottom" id="vgf-mV-ruR"/> <constraint firstItem="dMD-2P-QwE" firstAttribute="top" secondItem="Mmn-Bf-5Vy" secondAttribute="bottom" constant="34" id="yju-Cd-yGg"/> </constraints> </view> </subviews> </view> <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <constraints> <constraint firstItem="YTs-C9-W1k" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" constant="5" id="7F2-TZ-ITp"/> <constraint firstAttribute="bottom" secondItem="YTs-C9-W1k" secondAttribute="bottom" constant="5" id="NS4-Iw-Buc"/> <constraint firstItem="YTs-C9-W1k" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" constant="5" id="bKs-J5-I38"/> <constraint firstAttribute="trailing" secondItem="YTs-C9-W1k" secondAttribute="trailing" constant="5" id="bdG-vi-hhI"/> </constraints> <size key="customSize" width="165" height="210"/> <connections> <outlet property="img_state" destination="dMD-2P-QwE" id="asa-h2-2Ut"/> <outlet property="view_container" destination="YTs-C9-W1k" id="SRu-Wj-Ued"/> <outlet property="view_top" destination="Mmn-Bf-5Vy" id="Pdc-oD-g5f"/> </connections> <point key="canvasLocation" x="101.34146341463415" y="60.50847457627119"/> </collectionViewCell> </objects> <resources> <image name="icon_fullScreen" width="34" height="34"/> <image name="icon_success" width="80" height="81"/> <systemColor name="systemBackgroundColor"> <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> </systemColor> </resources> </document> DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_Pocket_CCell.swift
New file @@ -0,0 +1,62 @@ // // ListenFight_Game_Pocket_CCell.swift // DolphinEnglishLearnStudent // // Created by 无故事王国 on 2024/5/29. // import UIKit class ListenFight_Game_Pocket_CCell: UICollectionViewCell { private lazy var mask_img:UIImageView = { let image = UIImageView(image: UIImage(named: "bg_card")) return image }() private lazy var answer_img:UIImageView = { let image = UIImageView() image.jq_cornerRadius = 10 image.backgroundColor = .red return image }() override init(frame: CGRect) { super.init(frame: frame) addSubview(answer_img) answer_img.snp.makeConstraints { make in make.edges.equalToSuperview() } addSubview(mask_img) mask_img.snp.makeConstraints { make in make.edges.equalToSuperview() } let mask_tap = UITapGestureRecognizer(target: self, action: #selector(toFromAction)) mask_img.addGestureRecognizer(mask_tap) mask_img.isUserInteractionEnabled = true let answer_tap = UITapGestureRecognizer(target: self, action: #selector(toBackAction)) answer_img.addGestureRecognizer(answer_tap) answer_img.isUserInteractionEnabled = true } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @objc func toFromAction(){ UIView.transition(from: mask_img, to: answer_img, duration: 0.6, options: [.transitionFlipFromLeft,.showHideTransitionViews]) { _ in } } @objc func toBackAction(){ UIView.transition(from: answer_img, to: mask_img, duration: 0.6,options: [.transitionFlipFromRight,.showHideTransitionViews]){ _ in } } } DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_1_VC.swift
@@ -11,6 +11,31 @@ private var viewModel = FightAnswerViewModel() private lazy var label_class:UILabel = { let label = UILabel() label.textColor = .white label.text = "1" label.textAlignment = .center label.font = UIFont.init(name: "Impact", size: 21) return label }() private lazy var label_hint:UILabel = { let label = UILabel() label.textColor = UIColor(hexStr: "#EE1111") label.text = "请在10s内选择答案!" label.textAlignment = .center label.font = .systemFont(ofSize: 14, weight: .medium) return label }() private lazy var view_studyHandleView:StudyHandleView = { let studyHandleView = StudyHandleView.jq_loadNibView() studyHandleView.view_choose.isHidden = true return studyHandleView }() private lazy var collectionView:UICollectionView = { let flowLayout = UICollectionViewFlowLayout() let w = (JQ_ScreenW - 35 * 2 - 12) / 4.0 @@ -24,12 +49,15 @@ return collection }() private var timer:Timer? private var times:Int = 10 override func viewDidLoad() { super.viewDidLoad() ChooseLevelView.show { level in GameBeginTipView.show { self.startTimer() } } } @@ -37,9 +65,44 @@ override func setUI() { super.setUI() let view_class_title = UIView() view_class_title.jq_cornerRadius = 16 view_class_title.backgroundColor = UIColor(hexStr: "#FBCF0F") view.addSubview(view_class_title) view_class_title.snp.makeConstraints { make in make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(40) make.left.equalToSuperview().offset(40) make.height.equalTo(32) make.width.greaterThanOrEqualTo(32) } view_class_title.addSubview(label_class) label_class.snp.makeConstraints { make in make.left.equalTo(11) make.right.equalTo(-12) make.centerY.equalToSuperview() } view.addSubview(view_studyHandleView) view_studyHandleView.snp.makeConstraints { make in make.left.equalTo(view_class_title.snp.right).offset(12) make.centerY.equalTo(view_class_title) make.width.equalTo(159) make.height.equalTo(52) } view.addSubview(label_hint) label_hint.snp.makeConstraints { make in make.left.equalTo(view_studyHandleView.snp.right).offset(23) make.centerY.equalTo(view_class_title) make.height.equalTo(20) } collectionView.delegate = self collectionView.dataSource = self collectionView.showsVerticalScrollIndicator = false collectionView.jq_addShadows(shadowColor: UIColor.black.withAlphaComponent(0.1), corner: 8, radius: 10, offset: CGSize(width: 0, height: 2), opacity: 1) collectionView.backgroundColor = .clear view.addSubview(collectionView) collectionView.snp.makeConstraints { make in @@ -47,21 +110,98 @@ make.left.right.equalToSuperview() make.bottom.equalToSuperview() } view.layoutIfNeeded() } private func startTimer(){ if timer == nil{ timer = Timer(timeInterval: 1.0, target: self, selector: #selector(runloopTime), userInfo: nil, repeats: true) } timer?.fire() RunLoop.current.add(timer!, forMode: .default) } @objc private func runloopTime(){ times -= 1 label_hint.text = "请在\(times)s内选择答案!" if times == 0{ timer?.fireDate = .distantFuture DispatchQueue.main.asyncAfter(deadline: .now()+3) { self.times = 10 self.timer?.fireDate = .distantPast } } } private func nextQuesAction(){ } private func answerQuestion(){ view.layoutIfNeeded() var answerType:Fight_lessonType = .none answerType = .success switch answerType { case .success: viewModel.answerType.accept(.success) collectionView.reloadData() if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_Game_CCell", for: viewModel.selectIndex.value!) as? ListenFight_Game_CCell{ let newRect = cell.contentView.convert(cell.bounds, from: self.collectionView) let x = abs(newRect.origin.x) + self.collectionView.contentInset.left + 5 let y = abs(newRect.origin.y) + 99 + 5 let layout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout let copyView = view_studyHandleView.copyView() copyView.view_choose.isHidden = true view.addSubview(copyView) UIView.animate(withDuration: 0.5) { copyView.frame = CGRect(x: x, y: y, width: layout.itemSize.width - 10, height: 40) } completion: { _ in DispatchQueue.main.asyncAfter(deadline: .now()+0.5) { self.viewModel.answerType.accept(.none) self.collectionView.reloadData() self.times = 11 self.nextQuesAction() } } } case .fail: viewModel.answerType.accept(.fail) collectionView.reloadData() DispatchQueue.main.asyncAfter(wallDeadline: .now()+2.5) { self.viewModel.answerType.accept(.none) self.collectionView.reloadData() self.times = 11 self.nextQuesAction() } case .none: break } } } extension HomeListenGame_1_VC:UICollectionViewDelegate{ func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { viewModel.selectIndex.accept(indexPath) answerQuestion() } } extension HomeListenGame_1_VC:UICollectionViewDataSource{ func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_Game_CCell", for: indexPath) as! ListenFight_Game_CCell cell.backgroundColor = .jq_randomColor cell.contentView.backgroundColor = .jq_randomColor if viewModel.selectIndex.value == indexPath{ cell.setState(state: viewModel.answerType.value) }else{ cell.setState(state: .none) } return cell } DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_2_VC.swift
@@ -9,11 +9,178 @@ class HomeListenGame_2_VC: BaseVC { private var viewModel = FightAnswerViewModel() private lazy var label_time:UILabel = { let label = UILabel() label.textColor = UIColor(hexStr: "#EE1111") label.text = "0s" label.font = UIFont.init(name: "Impact", size: 36) return label }() private lazy var collectionView:UICollectionView = { let flowLayout = UICollectionViewFlowLayout() let w = (JQ_ScreenW - 40 * 2 - 30) / 4.0 flowLayout.itemSize = CGSize(width: w, height: w * 0.675) flowLayout.minimumInteritemSpacing = 10 flowLayout.minimumLineSpacing = 20 flowLayout.scrollDirection = .vertical let collection = UICollectionView(frame: .zero, collectionViewLayout: flowLayout) collection.contentInset = UIEdgeInsets(top: 101, left: 40, bottom: 0, right: 40) collection.register(ListenFight_Game_Pocket_CCell.self, forCellWithReuseIdentifier: "_ListenFight_Game_Pocket_CCell") return collection }() private var timer:Timer? private var times:Int = 600 override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. startTimer() } override func setUI() { super.setUI() let label_surplusTitle = UILabel() label_surplusTitle.textColor = UIColor.black label_surplusTitle.text = "答题剩余时间:" label_surplusTitle.font = .systemFont(ofSize: 14, weight: .medium) view.addSubview(label_surplusTitle) label_surplusTitle.snp.makeConstraints { make in make.left.equalTo(40) make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(46) make.height.equalTo(20) } view.addSubview(label_time) label_time.snp.makeConstraints { make in make.left.equalTo(label_surplusTitle.snp.right).offset(0) make.centerY.equalTo(label_surplusTitle) make.height.equalTo(44) } collectionView.delegate = self collectionView.dataSource = self collectionView.showsVerticalScrollIndicator = false collectionView.jq_addShadows(shadowColor: UIColor.black.withAlphaComponent(0.1), corner: 8, radius: 10, offset: CGSize(width: 0, height: 2), opacity: 1) collectionView.backgroundColor = .clear view.addSubview(collectionView) collectionView.snp.makeConstraints { make in make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top) make.left.right.equalToSuperview() make.bottom.equalToSuperview() } view.layoutIfNeeded() } private func startTimer(){ if timer == nil{ timer = Timer(timeInterval: 1.0, target: self, selector: #selector(runloopTime), userInfo: nil, repeats: true) } timer?.fire() RunLoop.current.add(timer!, forMode: .default) } @objc private func runloopTime(){ times -= 1 label_time.text = "\(times)s" if times == 0{ timer?.fireDate = .distantFuture DispatchQueue.main.asyncAfter(deadline: .now()+3) { self.times = 10 self.timer?.fireDate = .distantPast } } } private func nextQuesAction(){ } private func answerQuestion(){ view.layoutIfNeeded() var answerType:Fight_lessonType = .none answerType = .success switch answerType { case .success: viewModel.answerType.accept(.success) collectionView.reloadData() case .fail: viewModel.answerType.accept(.fail) collectionView.reloadData() DispatchQueue.main.asyncAfter(wallDeadline: .now()+2.5) { self.viewModel.answerType.accept(.none) self.collectionView.reloadData() } case .none: break } } } extension HomeListenGame_2_VC:UICollectionViewDelegate{ func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { viewModel.selectIndex.accept(indexPath) _ = self.collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_Game_Pocket_CCell", for: indexPath) as! ListenFight_Game_Pocket_CCell } } extension HomeListenGame_2_VC:UICollectionViewDataSource{ func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_Game_Pocket_CCell", for: indexPath) as! ListenFight_Game_Pocket_CCell return cell } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 12 } } extension HomeListenGame_2_VC: UICollectionViewDelegateFlowLayout { // 实现以下方法以支持转场动画 func collectionView(_ collectionView: UICollectionView, transitionLayoutForOldLayout fromLayout: UICollectionViewLayout, newLayout toLayout: UICollectionViewLayout) -> UICollectionViewTransitionLayout { return UICollectionViewTransitionLayout(currentLayout: fromLayout, nextLayout: toLayout) } // 实现以下方法以返回自定义的转场动画控制器 func collectionView(_ collectionView: UICollectionView, transitionAnimationControllerForOldCell: UICollectionViewCell, newCell: UICollectionViewCell) -> UIViewControllerAnimatedTransitioning? { return FlipAnimationController() } // FlipAnimationController实现转场动画的具体细节 class FlipAnimationController: NSObject, UIViewControllerAnimatedTransitioning { func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return 0.3 } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { guard let fromView = transitionContext.view(forKey: UITransitionContextViewKey.from) else { return } guard let toView = transitionContext.view(forKey: UITransitionContextViewKey.to) else { return } let containerView = transitionContext.containerView // 初始化动画参数 toView.frame = transitionContext.finalFrame(for: transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!) containerView.addSubview(toView) // 翻牌动画 UIView.transition(from: fromView, to: toView, duration: transitionDuration(using: transitionContext), options: [.transitionFlipFromLeft]) { completed in transitionContext.completeTransition(completed) } } } }