alert修改

This commit is contained in:
zeng 2025-07-24 19:21:38 +08:00
parent cb7fadea6b
commit 69f20b9cfb
22 changed files with 558 additions and 9 deletions

View File

@ -155,6 +155,9 @@
F39855202E32166300E2D28D /* BRFavoritesPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398551F2E32166300E2D28D /* BRFavoritesPageViewController.swift */; };
F39855222E32227D00E2D28D /* BRPlayHistorysViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855212E32227D00E2D28D /* BRPlayHistorysViewController.swift */; };
F39855242E3222BE00E2D28D /* BRPlayHistorysCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855232E3222BE00E2D28D /* BRPlayHistorysCell.swift */; };
F39855272E322A7100E2D28D /* BRBaseAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855262E322A7100E2D28D /* BRBaseAlert.swift */; };
F39855292E322B1800E2D28D /* BRAlertWindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855282E322B1800E2D28D /* BRAlertWindowManager.swift */; };
F398552B2E322C7C00E2D28D /* BRAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398552A2E322C7C00E2D28D /* BRAlert.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -321,6 +324,9 @@
F398551F2E32166300E2D28D /* BRFavoritesPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRFavoritesPageViewController.swift; sourceTree = "<group>"; };
F39855212E32227D00E2D28D /* BRPlayHistorysViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRPlayHistorysViewController.swift; sourceTree = "<group>"; };
F39855232E3222BE00E2D28D /* BRPlayHistorysCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRPlayHistorysCell.swift; sourceTree = "<group>"; };
F39855262E322A7100E2D28D /* BRBaseAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRBaseAlert.swift; sourceTree = "<group>"; };
F39855282E322B1800E2D28D /* BRAlertWindowManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRAlertWindowManager.swift; sourceTree = "<group>"; };
F398552A2E322C7C00E2D28D /* BRAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRAlert.swift; sourceTree = "<group>"; };
F70FA1F4169364C4C53534CE /* Pods-BeeReel.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BeeReel.release.xcconfig"; path = "Target Support Files/Pods-BeeReel/Pods-BeeReel.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -599,6 +605,7 @@
BF692AF62E0A480000A5C2DA /* Lib */ = {
isa = PBXGroup;
children = (
F39855252E32294C00E2D28D /* Alert */,
BF3A56862E30E0C2009E5CF9 /* Empty */,
BF692B452E0A9B5800A5C2DA /* Player */,
BF692B1D2E0A803000A5C2DA /* LocalizedManager */,
@ -986,6 +993,16 @@
name = Frameworks;
sourceTree = "<group>";
};
F39855252E32294C00E2D28D /* Alert */ = {
isa = PBXGroup;
children = (
F398552A2E322C7C00E2D28D /* BRAlert.swift */,
F39855262E322A7100E2D28D /* BRBaseAlert.swift */,
F39855282E322B1800E2D28D /* BRAlertWindowManager.swift */,
);
path = Alert;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -1133,9 +1150,12 @@
BF692B342E0A87C800A5C2DA /* UIDevice+BRAdd.swift in Sources */,
BF692B3E2E0A8D2300A5C2DA /* BRTabBarController.swift in Sources */,
BF02B7E12E2DE64200172177 /* BRVideoProgressView.swift in Sources */,
F39855272E322A7100E2D28D /* BRBaseAlert.swift in Sources */,
BF692B542E0AA8FA00A5C2DA /* BRCollectionView.swift in Sources */,
BF3338E82E15219500B10F76 /* UINavigationBar+BRAdd.swift in Sources */,
F39855292E322B1800E2D28D /* BRAlertWindowManager.swift in Sources */,
BF02B82D2E30855300172177 /* BRSearchTextView.swift in Sources */,
F398552B2E322C7C00E2D28D /* BRAlert.swift in Sources */,
BF692B472E0A9B7900A5C2DA /* BRPlayer.swift in Sources */,
BF692B6E2E0BD4CB00A5C2DA /* BRHomeHeaderView.swift in Sources */,
BF692AFA2E0A6F0900A5C2DA /* BRNetwork.swift in Sources */,

View File

@ -122,4 +122,8 @@ extension UIColor {
static func colorFFEFA1(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xFFEFA1, alpha: alpha)
}
static func colorC2C2C2(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xC2C2C2, alpha: alpha)
}
}

View File

@ -140,4 +140,25 @@ class BRVideoAPI {
extension BRVideoAPI {
/// [ "state" : isFavorite, "id" : shortPlayId,]
@objc static let updateShortFavoriteStateNotification = NSNotification.Name(rawValue: "BRVideoAPI.updateShortFavoriteStateNotification")
static func favoriteOrCancelFavorite(isFavorite: Bool, shortPlayId: String, videoId: String?) {
if isFavorite {
BRVideoAPI.requestFavorite(isFavorite: isFavorite, shortPlayId: shortPlayId, videoId: videoId) {
}
} else {
let alert = BRAlert(title: "kRemoveFavoritesAlertTitle".localized, detail: "kRemoveFavoritesAlertDetail".localized, image: nil, normalButtonText: "Cancel".localized, highlightButtonText: "Remove".localized).show()
alert.highlightButtonImage = UIImage(named: "delete_icon_02")
alert.clickHighlightButton = {
BRVideoAPI.requestFavorite(isFavorite: isFavorite, shortPlayId: shortPlayId, videoId: videoId) {
}
}
}
}
}

View File

@ -81,7 +81,7 @@ struct BRNetwork {
completion?(res)
} else {
if code == 402, parameters.isToast {
BRToast.show(text: "veloria_network_error_1".localized)
BRToast.show(text: "beereel_network_error_1".localized)
}
///token
self.requestToken { token in
@ -138,7 +138,7 @@ struct BRNetwork {
var res = BRNetworkResponse<T>()
res.code = -1
if parameters.isToast {
BRToast.show(text: "veloria_network".localized)
BRToast.show(text: "beereel_network".localized)
}
completion?(res)
break

View File

@ -76,9 +76,8 @@ class BRFavoritesCell: BRCollectionViewCell {
guard let shortPlayId = self.model?.short_play_id else { return }
let isFavorite = !(self.model?.is_collect ?? false)
BRVideoAPI.requestFavorite(isFavorite: isFavorite, shortPlayId: shortPlayId, videoId: model?.short_play_video_id) {
}
BRVideoAPI.favoriteOrCancelFavorite(isFavorite: isFavorite, shortPlayId: shortPlayId, videoId: model?.short_play_video_id)
}

View File

@ -114,10 +114,7 @@ class BRFavoritesHeaderView: UICollectionReusableView {
guard let shortPlayId = self.model?.short_play_id else { return }
let isFavorite = !(self.model?.is_collect ?? false)
BRVideoAPI.requestFavorite(isFavorite: isFavorite, shortPlayId: shortPlayId, videoId: model?.short_play_video_id) {
}
BRVideoAPI.favoriteOrCancelFavorite(isFavorite: isFavorite, shortPlayId: shortPlayId, videoId: model?.short_play_video_id)
}
@objc private func updateShortFavoriteStateNotification(sender: Notification) {

View File

@ -0,0 +1,183 @@
//
// BRAlert.swift
// BeeReel
//
// Created by 鸿 on 2025/7/24.
//
import UIKit
class BRAlert: BRBaseAlert {
var normalButtonTitle: String? {
didSet {
normalButton.setNeedsUpdateConfiguration()
}
}
var highlightButtonTitle: String? {
didSet {
highlightButton.setNeedsUpdateConfiguration()
}
}
var highlightButtonImage: UIImage? {
didSet {
highlightButton.setNeedsUpdateConfiguration()
}
}
var clickNormalButton: (() -> Void)?
var clickHighlightButton: (() -> Void)?
private lazy var bgView: UIView = {
let view = UIImageView(image: UIImage(named: "alert_bg_image"))
view.isUserInteractionEnabled = true
return view
}()
private lazy var normalButton: UIButton = {
var config = UIButton.Configuration.plain()
let button = UIButton(configuration: config)
button.layer.cornerRadius = 24
button.layer.masksToBounds = true
button.layer.borderColor = UIColor.colorC2C2C2().cgColor
button.layer.borderWidth = 1
button.configurationUpdateHandler = { [weak self] button in
guard let self = self else { return }
button.configuration?.attributedTitle = AttributedString.br_createAttributedString(string: normalButtonTitle ?? "", color: .colorC2C2C2(), font: .fontRegular(ofSize: 14))
}
button.addTarget(self, action: #selector(handleNormalButton), for: .touchUpInside)
return button
}()
private lazy var highlightButton: UIButton = {
var config = UIButton.Configuration.plain()
config.background.image = UIImage(named: "选中光效")
config.background.backgroundColor = .color1C1C1C()
config.imagePadding = 4
let button = UIButton(configuration: config)
button.layer.cornerRadius = 24
button.layer.masksToBounds = true
button.configurationUpdateHandler = { [weak self] button in
guard let self = self else { return }
button.configuration?.image = highlightButtonImage
button.configuration?.attributedTitle = AttributedString.br_createAttributedString(string: highlightButtonTitle ?? "", color: .colorFFFFFF(), font: .fontMedium(ofSize: 14))
}
button.addTarget(self, action: #selector(handleHighlightButton), for: .touchUpInside)
return button
}()
init(title: String, detail: String?, image: UIImage?, normalButtonText: String?, highlightButtonText: String?) {
super.init(frame: .zero)
let titleLabel = UILabel()
titleLabel.font = .fontBold(ofSize: 18)
titleLabel.textColor = .color000000()
titleLabel.text = title
let titleIconImageView = UIImageView(image: UIImage(named: "Vector 22"))
let stackView = UIStackView()
stackView.axis = .vertical
if let image = image {
let imageView = UIImageView(image: image)
stackView.addArrangedSubview(imageView)
}
if let detail = detail {
let label = UILabel()
label.text = detail
label.font = .fontRegular(ofSize: 15)
label.textColor = .color1C1C1C()
label.textAlignment = .center
label.numberOfLines = 0
stackView.addArrangedSubview(label)
}
let buttonStackView = UIStackView()
buttonStackView.axis = .horizontal
buttonStackView.spacing = 19
buttonStackView.distribution = .fillEqually
if let normalButtonText = normalButtonText {
self.normalButtonTitle = normalButtonText
buttonStackView.addArrangedSubview(normalButton)
}
if let highlightButtonText = highlightButtonText {
self.highlightButtonTitle = highlightButtonText
buttonStackView.addArrangedSubview(highlightButton)
}
contentView.addSubview(bgView)
bgView.addSubview(titleIconImageView)
bgView.addSubview(titleLabel)
bgView.addSubview(stackView)
bgView.addSubview(buttonStackView)
bgView.snp.makeConstraints { make in
make.edges.equalToSuperview()
make.width.equalTo(305)
}
titleIconImageView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(42)
}
titleLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(30)
}
stackView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.left.equalToSuperview().offset(30)
make.top.equalToSuperview().offset(73)
make.bottom.equalToSuperview().offset(-111)
}
buttonStackView.snp.makeConstraints { make in
make.bottom.equalToSuperview().offset(-30)
make.height.equalTo(48)
make.centerX.equalToSuperview()
if buttonStackView.arrangedSubviews.count == 1 {
make.left.equalToSuperview().offset(28)
} else {
make.left.equalToSuperview().offset(15)
}
}
}
@MainActor required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc private func handleNormalButton() {
self.dismiss()
self.clickNormalButton?()
}
@objc private func handleHighlightButton() {
self.dismiss()
self.clickHighlightButton?()
}
}

View File

@ -0,0 +1,43 @@
//
// BRAlertWindowManager.swift
// BeeReel
//
// Created by 鸿 on 2025/7/24.
//
import UIKit
class BRAlertWindowManager: NSObject {
static let manager = BRAlertWindowManager()
private(set) var window: UIWindow?
func createWindow() -> UIWindow {
guard let window = window else {
let window = UIWindow(windowScene: BRAppTool.windowScene!)
window.backgroundColor = .clear
window.windowLevel = .alert
window.isHidden = false
self.window = window
return window
}
return window
}
func dismissWindow() {
guard let window = self.window else { return }
var isHidden = true
window.subviews.forEach {
if $0.isKind(of: BRBaseAlert.self) {
isHidden = false
}
}
if isHidden {
window.isHidden = true
self.window = nil
}
}
}

View File

@ -0,0 +1,73 @@
//
// BRBaseAlert.swift
// BeeReel
//
// Created by 鸿 on 2025/7/24.
//
import UIKit
class BRBaseAlert: UIView {
private(set) var contentView: UIView = {
let view = UIView()
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .color000000(alpha: 0.4)
addSubview(contentView)
contentView.snp.makeConstraints { make in
make.center.equalToSuperview()
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@discardableResult
@objc func show(in view: UIView? = nil) -> Self {
guard self.superview == nil else { return self }
var inView: UIView
if let view = view {
inView = view
} else {
inView = BRAlertWindowManager.manager.createWindow()
}
inView.addSubview(self)
self.frame = inView.bounds
showAnimation()
return self
}
@objc func dismiss() {
dismissAnimation()
}
}
extension BRBaseAlert {
private func showAnimation() {
contentView.transform = CGAffineTransform(translationX: 0, y: 200)
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0) {
self.contentView.transform = CGAffineTransform.identity
}
}
private func dismissAnimation() {
UIView.animate(withDuration: 0.3) {
self.alpha = 0
self.contentView.transform = CGAffineTransform(translationX: 0, y: 500)
} completion: { _ in
self.removeFromSuperview()
BRAlertWindowManager.manager.dismissWindow()
}
}
}

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 B

View File

@ -0,0 +1,44 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "选中光效@2x.png",
"idiom" : "universal",
"resizing" : {
"cap-insets" : {
"left" : 62,
"right" : 158
},
"center" : {
"mode" : "tile",
"width" : 1
},
"mode" : "3-part-horizontal"
},
"scale" : "2x"
},
{
"filename" : "选中光效@3x.png",
"idiom" : "universal",
"resizing" : {
"cap-insets" : {
"left" : 98,
"right" : 233
},
"center" : {
"mode" : "tile",
"width" : 2
},
"mode" : "3-part-horizontal"
},
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,44 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Rectangle 85@2x.png",
"idiom" : "universal",
"resizing" : {
"cap-insets" : {
"bottom" : 67,
"top" : 203
},
"center" : {
"height" : 1,
"mode" : "tile"
},
"mode" : "3-part-vertical"
},
"scale" : "2x"
},
{
"filename" : "Rectangle 85@3x.png",
"idiom" : "universal",
"resizing" : {
"cap-insets" : {
"bottom" : 79,
"top" : 259
},
"center" : {
"height" : 1,
"mode" : "tile"
},
"mode" : "3-part-vertical"
},
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

View File

@ -23,6 +23,28 @@
}
}
},
"beereel_network" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "The service is abnormal. Check the network."
}
}
}
},
"beereel_network_error_1" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Your account is already logged in on another device~"
}
}
}
},
"Browse Genres" : {
"extractionState" : "manual",
"localizations" : {
@ -34,6 +56,17 @@
}
}
},
"Cancel" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cancel"
}
}
}
},
"Categories" : {
"extractionState" : "manual",
"localizations" : {
@ -67,6 +100,17 @@
}
}
},
"Error" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Error"
}
}
}
},
"Expand Your Favorites" : {
"extractionState" : "manual",
"localizations" : {
@ -144,6 +188,28 @@
}
}
},
"kRemoveFavoritesAlertDetail" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "You may not find this collection after you unncollect it."
}
}
}
},
"kRemoveFavoritesAlertTitle" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove from favorites?"
}
}
}
},
"kSearchEmptyDetail" : {
"extractionState" : "manual",
"localizations" : {
@ -221,6 +287,17 @@
}
}
},
"Remove" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Remove"
}
}
}
},
"Search Results" : {
"extractionState" : "manual",
"localizations" : {