1.缺省页 UI

This commit is contained in:
HiBit 2025-11-26 16:55:40 +08:00
parent 967534d926
commit 86b603c64f
27 changed files with 266 additions and 34 deletions

View File

@ -31,5 +31,5 @@ target 'SynthReel' do
pod 'MJRefresh'
pod 'collection-view-layouts/TagsLayout'
pod 'HWPanModal'
pod 'LYEmptyView'
end

View File

@ -123,6 +123,8 @@
370D2F2F2ED5AB2500571E77 /* SRViralHitController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F2E2ED5AB2500571E77 /* SRViralHitController.swift */; };
3754ACBD2ED5B6B6009EBCAD /* UINavigationBar+SRAdd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3754ACBC2ED5B6B6009EBCAD /* UINavigationBar+SRAdd.swift */; };
3754ACBF2ED5B839009EBCAD /* SRNavgationTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3754ACBE2ED5B839009EBCAD /* SRNavgationTitleView.swift */; };
3754ACC12ED69105009EBCAD /* SRTopChartsHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3754ACC02ED69105009EBCAD /* SRTopChartsHeaderView.swift */; };
3754ACC42ED6EDA6009EBCAD /* SREmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3754ACC32ED6EDA6009EBCAD /* SREmpty.swift */; };
3779D0612ECF1CB8006B1698 /* SRShortHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3779D0602ECF1CB8006B1698 /* SRShortHeaderView.swift */; };
47BB39E2DD30787FA591F8EB /* Pods_SynthReel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9255BF4D4B1CFDDB5CFFB43 /* Pods_SynthReel.framework */; };
/* End PBXBuildFile section */
@ -245,6 +247,8 @@
370D2F2E2ED5AB2500571E77 /* SRViralHitController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRViralHitController.swift; sourceTree = "<group>"; };
3754ACBC2ED5B6B6009EBCAD /* UINavigationBar+SRAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationBar+SRAdd.swift"; sourceTree = "<group>"; };
3754ACBE2ED5B839009EBCAD /* SRNavgationTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRNavgationTitleView.swift; sourceTree = "<group>"; };
3754ACC02ED69105009EBCAD /* SRTopChartsHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRTopChartsHeaderView.swift; sourceTree = "<group>"; };
3754ACC32ED6EDA6009EBCAD /* SREmpty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SREmpty.swift; sourceTree = "<group>"; };
3779D0602ECF1CB8006B1698 /* SRShortHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRShortHeaderView.swift; sourceTree = "<group>"; };
59DC746604B26E9FF802D317 /* Pods-SynthReel.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SynthReel.debug.xcconfig"; path = "Target Support Files/Pods-SynthReel/Pods-SynthReel.debug.xcconfig"; sourceTree = "<group>"; };
AA88214030574193B51DE563 /* Pods-SynthReel.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SynthReel.release.xcconfig"; path = "Target Support Files/Pods-SynthReel/Pods-SynthReel.release.xcconfig"; sourceTree = "<group>"; };
@ -389,6 +393,7 @@
03B1A9452ECC5679006C353F /* SRSearchResultCell.swift */,
370D2F2A2ED597F700571E77 /* SRTopChartsCell.swift */,
370D2F2C2ED5AA9700571E77 /* SRViralHitCell.swift */,
3754ACC02ED69105009EBCAD /* SRTopChartsHeaderView.swift */,
);
path = V;
sourceTree = "<group>";
@ -544,6 +549,7 @@
03E9A7D42EC4764A000D1067 /* Libs */ = {
isa = PBXGroup;
children = (
3754ACC22ED6ED92009EBCAD /* Empty */,
03B1A83C2EC5C90F006C353F /* Tool */,
03B1A8372EC5C8BF006C353F /* SRHud */,
03E9A7ED2EC4A855000D1067 /* SRAccount */,
@ -668,6 +674,14 @@
path = model;
sourceTree = "<group>";
};
3754ACC22ED6ED92009EBCAD /* Empty */ = {
isa = PBXGroup;
children = (
3754ACC32ED6EDA6009EBCAD /* SREmpty.swift */,
);
path = Empty;
sourceTree = "<group>";
};
3779D05F2ECF1C8D006B1698 /* V */ = {
isa = PBXGroup;
children = (
@ -859,6 +873,7 @@
03E9A7FA2EC56D03000D1067 /* String+SRAdd.swift in Sources */,
03B1A9192ECAF2E6006C353F /* SRHomePremiereNowView.swift in Sources */,
03B1A92C2ECC0A7A006C353F /* SRShortDetailPlayerCell.swift in Sources */,
3754ACC42ED6EDA6009EBCAD /* SREmpty.swift in Sources */,
03B1A8392EC5C8D6006C353F /* SRHud.swift in Sources */,
03E9A7EC2EC499A9000D1067 /* SRDeviceId.swift in Sources */,
03E9A7E22EC494F9000D1067 /* SRTargetType.swift in Sources */,
@ -922,6 +937,7 @@
03B1A91B2ECAFFD6006C353F /* UIView+SRAdd.swift in Sources */,
03B1A9222ECB456C006C353F /* SRDetailPlayerViewController.swift in Sources */,
03B1A91F2ECB2A0E006C353F /* SRHomeBannerMiniCell.swift in Sources */,
3754ACC12ED69105009EBCAD /* SRTopChartsHeaderView.swift in Sources */,
03B1A93E2ECC4568006C353F /* SRTableView.swift in Sources */,
03980F4F2ECEB91C0006E317 /* SRRecommendPlayerViewModel.swift in Sources */,
03B1A9422ECC4632006C353F /* SRHotSearchCell.swift in Sources */,

View File

@ -6,10 +6,10 @@
// Copyright © 2025 SR. All rights reserved.
//
let SRBaseURL = "https://api-hbqinjiu.hbqinjiu.com"
let SRUrlPathPrefix = "/eon"
let SRWebBaseURL = "https://www.hbqinjiu.com"
let SRCampaignWebURL = "https://campaign.hbqinjiu.com"
let SRBaseURL = "https://api-synthreeltv.synthreeltv.com"
let SRUrlPathPrefix = "/th"
let SRWebBaseURL = "https://www.synthreeltv.com"
let SRCampaignWebURL = "https://campaign.synthreeltv.com"
/*

View File

@ -7,6 +7,7 @@
//
import UIKit
import LYEmptyView
class SRCollectionView: UICollectionView {

View File

@ -22,6 +22,7 @@ class SRHomeModuleItem: NSObject, SmartCodable {
case bingeWorthy = "week_highest_recommend"
case viralHits = "highest_payment_hot_video"
case premiereNow = "new_recommand"
case catetoryList = "category_navigation"
}

View File

@ -0,0 +1,45 @@
//
// SRTopChartsHeaderView.swift
// SynthReel
//
// Created by CSGY on 2025/11/26.
// Copyright © 2025 SR. All rights reserved.
//
import UIKit
class SRTopChartsHeaderView: UICollectionReusableView {
lazy var titlelabel : SRLabel = {
let label = SRLabel()
label.text = "Live Trending Rankings".localized
label.font = .font(ofSize: 16, weight: .bold)
label.textColors = [UIColor.srGreen.cgColor,UIColor.white.cgColor, UIColor.srBlue.cgColor]
label.textStartPoint = .init(x: 0.5, y: 0)
label.textEndPoint = .init(x: 0.5, y: 1)
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
sr_setui()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension SRTopChartsHeaderView {
func sr_setui() {
addSubview(titlelabel)
titlelabel.snp.makeConstraints { make in
make.left.equalTo(15)
make.centerY.equalToSuperview()
}
}
}

View File

@ -36,6 +36,7 @@ class SRHomeChildViewController: SRViewController {
collectionView.dataSource = self
collectionView.showsVerticalScrollIndicator = false
collectionView.showsHorizontalScrollIndicator = false
collectionView.ly_emptyView = SREmpty.sr_emptyView(image: UIImage(named: "nothing"), title: "empty_title_02".localized)
collectionView.register(UINib(nibName: "SRHomeChildCell", bundle: nil), forCellWithReuseIdentifier: "cell")
collectionView.sr_addRefreshFooter { [weak self] in
self?.handleFooterRefresh(nil)

View File

@ -117,10 +117,11 @@ class SRHomeViewController: SRViewController {
override func viewDidLoad() {
super.viewDidLoad()
sr_setupUI()
print("authorization =", SRAccountManager.manager.token?.token ?? "")
Task {
await requestModuleList()
await requestCategoryList()
// await requestCategoryList()
}
}
@ -228,7 +229,7 @@ extension SRHomeViewController: JXPagingViewDelegate {
func pagingView(_ pagingView: JXPagingView, initListAtIndex index: Int) -> any JXPagingViewListViewDelegate {
let vc = SRHomeChildViewController()
vc.categoryId = self.viewModel.categoryArr[index].id
vc.categoryId = self.viewModel.categoryArr[index].category_id
return vc
}
@ -258,19 +259,21 @@ extension SRHomeViewController: JXPagingMainTableViewGestureDelegate {
extension SRHomeViewController {
func requestCategoryList() async {
await self.viewModel.requestCategoryList()
self.menuDataSource.titles = self.viewModel.categoryTitleArr
self.pageView.reloadData()
self.menuView.reloadData()
}
// func requestCategoryList() async {
// await self.viewModel.requestCategoryList()
//
//
//
//
// }
func requestModuleList() async {
await self.viewModel.requestModuleList()
self.headerView.reloadData()
self.menuDataSource.titles = self.viewModel.categoryTitleArr
self.pageView.reloadData()
self.menuView.reloadData()
}

View File

@ -34,6 +34,8 @@ class SRTopChartsViewController: SRViewController {
layout.minimumLineSpacing = 10
layout.itemSize = .init(width: itemWidth, height: itemHeight)
layout.sectionInset = .init(top: 10, left: 15, bottom: 10, right: 15)
layout.headerReferenceSize = CGSize(width: UIScreen.width, height: 44)
return layout
}()
@ -44,6 +46,7 @@ class SRTopChartsViewController: SRViewController {
collectionView.showsVerticalScrollIndicator = false
collectionView.showsHorizontalScrollIndicator = false
collectionView.register(SRTopChartsCell.self, forCellWithReuseIdentifier: "cell")
collectionView.register(SRTopChartsHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "SRTopChartsHeaderView")
collectionView.sr_addRefreshFooter { [weak self] in
self?.handleFooterRefresh(nil)
}
@ -99,4 +102,20 @@ extension SRTopChartsViewController: UICollectionViewDelegate, UICollectionViewD
vc.shortId = model.short_play_id
self.navigationController?.pushViewController(vc, animated: true)
}
func collectionView(_ collectionView: UICollectionView,
viewForSupplementaryElementOfKind kind: String,
at indexPath: IndexPath) -> UICollectionReusableView {
if kind == UICollectionView.elementKindSectionHeader {
let header = collectionView.dequeueReusableSupplementaryView(
ofKind: UICollectionView.elementKindSectionHeader,
withReuseIdentifier: "SRTopChartsHeaderView",
for: indexPath
) as! SRTopChartsHeaderView
return header
}
return UICollectionReusableView()
}
}

View File

@ -10,21 +10,21 @@ import UIKit
class SRHomeViewModel: NSObject {
lazy var categoryArr: [SRCategoryModel] = []
lazy var categoryArr: [SRShortModel] = []
lazy var categoryTitleArr: [String] = []
lazy var moduleArr: [SRHomeModuleItem] = []
func requestCategoryList() async {
if let list = await SRHomeApi.requestCategoryList() {
self.categoryArr = list
var titles: [String] = []
self.categoryArr.forEach {
titles.append($0.name ?? "")
}
self.categoryTitleArr = titles
}
}
// func requestCategoryList() async {
// if let list = await SRHomeApi.requestCategoryList() {
// self.categoryArr = list
// var titles: [String] = []
// self.categoryArr.forEach {
// titles.append($0.name ?? "")
// }
// self.categoryTitleArr = titles
// }
// }
func requestModuleList() async {
guard let list = await SRHomeApi.requestHomeModulesData() else { return }
@ -45,6 +45,7 @@ class SRHomeViewModel: NSObject {
var bingeWorthyItem: SRHomeModuleItem? = nil
var viralHitsItem: SRHomeModuleItem? = nil
var premiereNowItem: SRHomeModuleItem? = nil
var catetoryItem: SRHomeModuleItem? = nil
list.forEach {
@ -69,12 +70,22 @@ class SRHomeViewModel: NSObject {
case .premiereNow:
premiereNowItem = $0
case .catetoryList:
catetoryItem = $0
default:
break
}
}
// self.categoryArr.append(catetoryItem?.list)
var titles: [String] = []
catetoryItem?.list.forEach({ SRShortModel in
titles.append(SRShortModel.category_name ?? "")
})
self.categoryTitleArr = titles
self.categoryArr = catetoryItem!.list
moduleArr.removeAll()
if let item = bannerItem {

View File

@ -54,7 +54,7 @@ class SRFavoritesViewController: SRViewController {
collectionView.dataSource = self
collectionView.showsVerticalScrollIndicator = false
collectionView.showsHorizontalScrollIndicator = false
// collectionView.register(UINib(nibName: "SRHistoryCell", bundle: nil), forCellWithReuseIdentifier: "cell")
collectionView.ly_emptyView = SREmpty.sr_emptyView(image: UIImage(named: "nothing"), title: "empty_title_02".localized)
collectionView.register(SRFavoritesCell.self, forCellWithReuseIdentifier: "cell")
collectionView.sr_addRefreshFooter { [weak self] in
self?.handleFooterRefresh(nil)

View File

@ -54,6 +54,7 @@ class SRHistoryViewController: SRViewController {
collectionView.dataSource = self
collectionView.showsVerticalScrollIndicator = false
collectionView.showsHorizontalScrollIndicator = false
collectionView.ly_emptyView = SREmpty.sr_emptyView(image: UIImage(named: "nothing"), title: "empty_title_02".localized)
collectionView.register(SRHistoryCell.self, forCellWithReuseIdentifier: "cell")
collectionView.sr_addRefreshFooter { [weak self] in
self?.handleFooterRefresh(nil)

View File

@ -30,6 +30,8 @@ class SRShortModel: NSObject, SmartCodable {
var short_play_id: String?
var video_info: SRVideoInfoModel?
var category_name :String?
var category_id :String?
@SmartIgnored
var cellHeight: CGFloat = 0

View File

@ -62,6 +62,11 @@ class SRDetailPlayerViewController: JXPlayerListViewController {
self.viewModel.currentCell?.pause()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.isNavigationBarHidden = true
}
override func play() {
let videoInfo = self.viewModel.currentCell?.model as? SRVideoInfoModel
super.play()

View File

@ -0,0 +1,57 @@
//
// SREmpty.swift
// SynthReel
//
// Created by CSGY on 2025/11/26.
// Copyright © 2025 SR. All rights reserved.
//
import UIKit
import LYEmptyView
struct SREmpty {
static func sr_emptyView(image: UIImage? = UIImage(named: "nothing"), title: String? = "empty_title_02".localized) -> LYEmptyView {
let view = LYEmptyView.emptyActionView(with: image, titleStr: title, detailStr: nil, btnTitleStr: nil) {
// btnClickBlock?()
}
view?.titleLabFont = .font(ofSize: 14, weight: .medium)
view?.titleLabTextColor = .white
view?.contentViewOffset = -100
view?.subViewMargin = 25
return view!
}
static func sr_notNetworkEmptyView(clickBlock: (() -> Void)?) -> LYEmptyView {
let view = LYEmptyView.emptyActionView(with: UIImage(named: "__startap"), titleStr: "No connection", detailStr: "Please check your network", btnTitleStr: "Try again") {
clickBlock?()
}
view?.titleLabFont = .font(ofSize: 17, weight: .bold)
view?.titleLabTextColor = .white
view?.detailLabFont = .font(ofSize: 15, weight: .regular)
view?.detailLabTextColor = .white
view?.actionBtnHeight = 32
view?.actionBtnHorizontalMargin = 26
view?.actionBtnCornerRadius = 16
view?.actionBtnBorderWidth = 1
view?.actionBtnBorderColor = .white
view?.actionBtnBackGroundColor = .clear
view?.actionBtnTitleColor = .white
view?.actionBtnFont = .font(ofSize: 14, weight: .medium)
view?.contentViewOffset = -20
view?.titleLabMargin = 30
view?.detailLabMargin = 2
view?.actionBtnMargin = 20
return view!
}
}

View File

@ -1,6 +1,7 @@
{
"images" : [
{
"filename" : "appicon.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
@ -12,6 +13,7 @@
"value" : "dark"
}
],
"filename" : "appicon 1.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
@ -23,6 +25,7 @@
"value" : "tinted"
}
],
"filename" : "appicon 2.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "bg@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "bg@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "nothing@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "nothing@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
<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>
<scenes>
@ -11,10 +14,21 @@
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="bg" translatesAutoresizingMaskIntoConstraints="NO" id="HLQ-sY-bXG">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
</imageView>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="HLQ-sY-bXG" secondAttribute="trailing" id="5Y7-4G-4Gc"/>
<constraint firstAttribute="bottom" secondItem="HLQ-sY-bXG" secondAttribute="bottom" id="855-RC-s5N"/>
<constraint firstItem="HLQ-sY-bXG" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="Sa0-2f-1bY"/>
<constraint firstItem="HLQ-sY-bXG" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="vUW-co-To4"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
@ -22,4 +36,10 @@
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="bg" width="375" height="812"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View File

@ -29,4 +29,7 @@
"synthreel_user_agreement" = "User Agreement";
"synthreel_visit_website" = "visit website";
"Viral Hits" = "Viral Hits";
"Live Trending Rankings" = "Live Trending Rankings";
"empty_title_01" = "No search results";
"empty_title_02" = "There is no data for the moment.";