mirror of
https://github.com/Finb/Bark.git
synced 2025-12-08 21:36:01 +00:00
添加 iPad 支持
This commit is contained in:
parent
c18403e845
commit
c00fe98b8d
@ -184,6 +184,9 @@
|
||||
06F11E7727D9D5FB00F00298 /* QRScannerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F11E7627D9D5FB00F00298 /* QRScannerViewController.swift */; };
|
||||
06FB04042C53575400F3A213 /* SharedDefines.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06FB04032C53575400F3A213 /* SharedDefines.swift */; };
|
||||
06FB04052C53575400F3A213 /* SharedDefines.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06FB04032C53575400F3A213 /* SharedDefines.swift */; };
|
||||
1E73F99E2C282822002BF649 /* SectionViewController-iPad.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E73F99D2C282822002BF649 /* SectionViewController-iPad.swift */; };
|
||||
1EFB545D2C314A6800B8E51B /* BarkSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EFB545C2C314A6800B8E51B /* BarkSplitViewController.swift */; };
|
||||
1EFB545F2C32514000B8E51B /* SectionViewModel-iPad.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EFB545E2C32514000B8E51B /* SectionViewModel-iPad.swift */; };
|
||||
3428272069AFAFE2C683FEB0 /* libPods-Bark.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CCC722470308049D180876C7 /* libPods-Bark.a */; };
|
||||
879AE4D4178855A9672009E4 /* libPods-NotificationServiceExtension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B7F8BDFAA047451561798F58 /* libPods-NotificationServiceExtension.a */; };
|
||||
B963F7D5BA7AC2571E71EF66 /* libPods-BarkTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 76381A752CCCD4DA6BB2A566 /* libPods-BarkTests.a */; };
|
||||
@ -375,6 +378,9 @@
|
||||
06FB04032C53575400F3A213 /* SharedDefines.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharedDefines.swift; sourceTree = "<group>"; };
|
||||
121D9B1ED4E8D26F345BC5C0 /* Pods-BarkTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BarkTests.release.xcconfig"; path = "Target Support Files/Pods-BarkTests/Pods-BarkTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
138CE8CB688587E893BC5C44 /* Pods-Bark.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Bark.debug.xcconfig"; path = "Target Support Files/Pods-Bark/Pods-Bark.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
1E73F99D2C282822002BF649 /* SectionViewController-iPad.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SectionViewController-iPad.swift"; sourceTree = "<group>"; };
|
||||
1EFB545C2C314A6800B8E51B /* BarkSplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarkSplitViewController.swift; sourceTree = "<group>"; };
|
||||
1EFB545E2C32514000B8E51B /* SectionViewModel-iPad.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SectionViewModel-iPad.swift"; sourceTree = "<group>"; };
|
||||
519481D715B40109627E1B49 /* Pods-NotificationServiceExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationServiceExtension.release.xcconfig"; path = "Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.release.xcconfig"; sourceTree = "<group>"; };
|
||||
76381A752CCCD4DA6BB2A566 /* libPods-BarkTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-BarkTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A69B47DA6DB3B168D5770B45 /* Pods-Bark.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Bark.release.xcconfig"; path = "Target Support Files/Pods-Bark/Pods-Bark.release.xcconfig"; sourceTree = "<group>"; };
|
||||
@ -447,6 +453,9 @@
|
||||
06EEF332291CCFF400CA228A /* CryptoSettingController.swift */,
|
||||
06EEF334291CD00000CA228A /* CryptoSettingViewModel.swift */,
|
||||
06787C3A2AB82BDB008ABDD7 /* CrashReportViewController.swift */,
|
||||
1E73F99D2C282822002BF649 /* SectionViewController-iPad.swift */,
|
||||
1EFB545E2C32514000B8E51B /* SectionViewModel-iPad.swift */,
|
||||
1EFB545C2C314A6800B8E51B /* BarkSplitViewController.swift */,
|
||||
);
|
||||
path = Controller;
|
||||
sourceTree = "<group>";
|
||||
@ -1098,6 +1107,7 @@
|
||||
06840DBB272298FB001B3193 /* BKColor.swift in Sources */,
|
||||
06C2CF232685B88D0034B127 /* TextCell.swift in Sources */,
|
||||
06BBB896256518760076F63E /* NewServerViewModel.swift in Sources */,
|
||||
1EFB545D2C314A6800B8E51B /* BarkSplitViewController.swift in Sources */,
|
||||
06BBB8C92567B6730076F63E /* Operators.swift in Sources */,
|
||||
0603706920E1F89500F4CA05 /* PreviewCardCell.swift in Sources */,
|
||||
0627DABB298B6EA2002F3F69 /* DropBoxView.swift in Sources */,
|
||||
@ -1161,12 +1171,14 @@
|
||||
06C2CF252685BDB80034B127 /* SpacerCell.swift in Sources */,
|
||||
06BBB8BC2567B3AD0076F63E /* ArchiveSettingCellViewModel.swift in Sources */,
|
||||
0642B55A27EB13F100453D91 /* MutableTextCell.swift in Sources */,
|
||||
1EFB545F2C32514000B8E51B /* SectionViewModel-iPad.swift in Sources */,
|
||||
06EEF335291CD00000CA228A /* CryptoSettingViewModel.swift in Sources */,
|
||||
0637FA8020E0981E00E80174 /* BarkSettings.swift in Sources */,
|
||||
065BE4402563D649002A8CA4 /* SoundsViewModel.swift in Sources */,
|
||||
065BE4462563D7E5002A8CA4 /* ViewModelType.swift in Sources */,
|
||||
0603706B20E20A7C00F4CA05 /* String+Extension.swift in Sources */,
|
||||
068F66B3247BD84C00DAD25A /* MessageListViewController.swift in Sources */,
|
||||
1E73F99E2C282822002BF649 /* SectionViewController-iPad.swift in Sources */,
|
||||
06BBB8B72567AC140076F63E /* MessageSettingsViewModel.swift in Sources */,
|
||||
06BBB8C12567B3EF0076F63E /* BaseTableViewCell.swift in Sources */,
|
||||
0661A543204FDA4100965E4E /* AppDelegate.swift in Sources */,
|
||||
@ -1433,8 +1445,10 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = me.fin.bark;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "match Development me.fin.bark";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@ -1455,8 +1469,10 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = me.fin.bark;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "match AppStore me.fin.bark";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
@ -78,25 +78,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
||||
setupRealm()
|
||||
|
||||
IQKeyboardManager.shared.enable = true
|
||||
|
||||
let tabBarController = StateStorageTabBarController()
|
||||
tabBarController.tabBar.tintColor = BKColor.grey.darken4
|
||||
|
||||
self.window?.rootViewController = BarkSnackbarController(
|
||||
rootViewController: tabBarController
|
||||
)
|
||||
|
||||
tabBarController.viewControllers = [
|
||||
BarkNavigationController(rootViewController: HomeViewController(viewModel: HomeViewModel())),
|
||||
BarkNavigationController(rootViewController: MessageListViewController(viewModel: MessageListViewModel())),
|
||||
BarkNavigationController(rootViewController: MessageSettingsViewController(viewModel: MessageSettingsViewModel()))
|
||||
]
|
||||
|
||||
let tabBarItems = [UITabBarItem(title: NSLocalizedString("service"), image: UIImage(named: "baseline_gite_black_24pt"), tag: 0),
|
||||
UITabBarItem(title: NSLocalizedString("historyMessage"), image: Icon.history, tag: 1),
|
||||
UITabBarItem(title: NSLocalizedString("settings"), image: UIImage(named: "baseline_manage_accounts_black_24pt"), tag: 2)]
|
||||
for (index, viewController) in tabBarController.viewControllers!.enumerated() {
|
||||
viewController.tabBarItem = tabBarItems[index]
|
||||
if #available(iOS 14, *), UIDevice.current.userInterfaceIdiom == .pad {
|
||||
let splitViewController = BarkSplitViewController.init(style: .doubleColumn)
|
||||
splitViewController.initViewControllers()
|
||||
self.window?.rootViewController = splitViewController;
|
||||
} else {
|
||||
let tabBarController = StateStorageTabBarController()
|
||||
tabBarController.tabBar.tintColor = BKColor.grey.darken4
|
||||
|
||||
self.window?.rootViewController = BarkSnackbarController(
|
||||
rootViewController: tabBarController
|
||||
)
|
||||
|
||||
tabBarController.viewControllers = [
|
||||
BarkNavigationController(rootViewController: HomeViewController(viewModel: HomeViewModel())),
|
||||
BarkNavigationController(rootViewController: MessageListViewController(viewModel: MessageListViewModel())),
|
||||
BarkNavigationController(rootViewController: MessageSettingsViewController(viewModel: MessageSettingsViewModel()))
|
||||
]
|
||||
|
||||
let tabBarItems = [UITabBarItem(title: NSLocalizedString("service"), image: UIImage(named: "baseline_gite_black_24pt"), tag: 0),
|
||||
UITabBarItem(title: NSLocalizedString("historyMessage"), image: Icon.history, tag: 1),
|
||||
UITabBarItem(title: NSLocalizedString("settings"), image: UIImage(named: "baseline_manage_accounts_black_24pt"), tag: 2)]
|
||||
for (index, viewController) in tabBarController.viewControllers!.enumerated() {
|
||||
viewController.tabBarItem = tabBarItems[index]
|
||||
}
|
||||
}
|
||||
|
||||
// 需先配置好 tabBarController 的 viewControllers,显示时会默认显示上次打开的页面
|
||||
|
||||
68
Controller/BarkSplitViewController.swift
Normal file
68
Controller/BarkSplitViewController.swift
Normal file
@ -0,0 +1,68 @@
|
||||
//
|
||||
// BarkSplitViewController.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by sidguan on 2024/6/30.
|
||||
// Copyright © 2024 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Material
|
||||
|
||||
class BarkSplitViewController: UISplitViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
// self.displayModeButtonItem.tintColor = BKColor.grey.darken4
|
||||
// self.delegate = self
|
||||
// Do any additional setup after loading the view.
|
||||
}
|
||||
|
||||
func initViewControllers() {
|
||||
if #available(iOS 14, *) {
|
||||
let sectionViewController = BarkNavigationController(rootViewController: SectionViewController_iPad(viewModel: SectionViewModel()));
|
||||
let homeViewController = BarkNavigationController(rootViewController: HomeViewController(viewModel: HomeViewModel()));
|
||||
let tabBarController = StateStorageTabBarController()
|
||||
tabBarController.tabBar.tintColor = BKColor.grey.darken4
|
||||
|
||||
let snackBarController = BarkSnackbarController(
|
||||
rootViewController: tabBarController
|
||||
)
|
||||
|
||||
tabBarController.viewControllers = [
|
||||
BarkNavigationController(rootViewController: HomeViewController(viewModel: HomeViewModel())),
|
||||
BarkNavigationController(rootViewController: MessageListViewController(viewModel: MessageListViewModel())),
|
||||
BarkNavigationController(rootViewController: MessageSettingsViewController(viewModel: MessageSettingsViewModel()))
|
||||
]
|
||||
|
||||
let tabBarItems = [
|
||||
UITabBarItem(title: NSLocalizedString("service"), image: UIImage(named: "baseline_gite_black_24pt"), tag: 0),
|
||||
UITabBarItem(title: NSLocalizedString("historyMessage"), image: Icon.history, tag: 1),
|
||||
UITabBarItem(title: NSLocalizedString("settings"), image: UIImage(named: "baseline_manage_accounts_black_24pt"), tag: 2)
|
||||
]
|
||||
for (index, viewController) in tabBarController.viewControllers!.enumerated() {
|
||||
viewController.tabBarItem = tabBarItems[index]
|
||||
}
|
||||
|
||||
|
||||
self.setViewController(sectionViewController, for: .primary)
|
||||
self.setViewController(homeViewController, for: .secondary)
|
||||
self.setViewController(snackBarController, for: .compact)
|
||||
}
|
||||
}
|
||||
|
||||
// func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
|
||||
// return true
|
||||
// }
|
||||
|
||||
/*
|
||||
// MARK: - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
// Get the new view controller using segue.destination.
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
@ -28,7 +28,11 @@ class BaseViewController<T>: UIViewController where T: ViewModel {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.navigationItem.largeTitleDisplayMode = .automatic
|
||||
if UIDevice.current.userInterfaceIdiom == .pad {
|
||||
navigationItem.largeTitleDisplayMode = .never
|
||||
} else {
|
||||
navigationItem.largeTitleDisplayMode = .automatic
|
||||
}
|
||||
makeUI()
|
||||
}
|
||||
|
||||
|
||||
@ -31,18 +31,18 @@ enum MessageDeleteType: Int {
|
||||
}
|
||||
|
||||
class MessageListViewController: BaseViewController<MessageListViewModel> {
|
||||
let deleteButton: BKButton = {
|
||||
let deleteButton: UIBarButtonItem = {
|
||||
let btn = BKButton()
|
||||
btn.setImage(UIImage(named: "baseline_delete_outline_black_24pt"), for: .normal)
|
||||
btn.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
|
||||
return btn
|
||||
return UIBarButtonItem(customView: btn)
|
||||
}()
|
||||
|
||||
let groupButton: BKButton = {
|
||||
let groupButton: UIBarButtonItem = {
|
||||
let btn = BKButton()
|
||||
btn.setImage(UIImage(named: "baseline_folder_open_black_24pt"), for: .normal)
|
||||
btn.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
|
||||
return btn
|
||||
return UIBarButtonItem(customView: btn)
|
||||
}()
|
||||
|
||||
let tableView: UITableView = {
|
||||
@ -59,7 +59,7 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
|
||||
navigationItem.searchController?.obscuresBackgroundDuringPresentation = false
|
||||
navigationItem.searchController?.delegate = self
|
||||
|
||||
navigationItem.setBarButtonItems(items: [UIBarButtonItem(customView: deleteButton), UIBarButtonItem(customView: groupButton)], position: .right)
|
||||
navigationItem.setBarButtonItems(items: [deleteButton, groupButton], position: .right)
|
||||
|
||||
self.view.addSubview(tableView)
|
||||
tableView.snp.makeConstraints { make in
|
||||
@ -96,9 +96,12 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
|
||||
}
|
||||
|
||||
override func bindViewModel() {
|
||||
let batchDelete = deleteButton.rx
|
||||
guard let deleteBtn = deleteButton.customView as? BKButton else {
|
||||
return;
|
||||
}
|
||||
let batchDelete = deleteBtn.rx
|
||||
.tap
|
||||
.flatMapLatest { _ -> PublishRelay<MessageDeleteType> in
|
||||
.flatMapLatest {_ -> PublishRelay<MessageDeleteType> in
|
||||
let relay = PublishRelay<MessageDeleteType>()
|
||||
|
||||
func alert(_ type: MessageDeleteType) {
|
||||
@ -124,19 +127,31 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
|
||||
alert(.allTime)
|
||||
}))
|
||||
alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel"), style: .cancel, handler: nil))
|
||||
if UIDevice.current.userInterfaceIdiom == .pad {
|
||||
alertController.modalPresentationStyle = .popover
|
||||
if #available(iOS 16.0, *) {
|
||||
alertController.popoverPresentationController?.sourceItem = self.deleteButton
|
||||
} else {
|
||||
alertController.popoverPresentationController?.barButtonItem = self.deleteButton
|
||||
}
|
||||
}
|
||||
self.navigationController?.present(alertController, animated: true, completion: nil)
|
||||
|
||||
return relay
|
||||
}
|
||||
|
||||
guard let groupBtn = groupButton.customView as? BKButton else {
|
||||
return;
|
||||
}
|
||||
|
||||
let output = viewModel.transform(
|
||||
input: MessageListViewModel.Input(
|
||||
refresh: tableView.refreshControl!.rx.controlEvent(.valueChanged).asDriver(),
|
||||
loadMore: tableView.mj_footer!.rx.refresh.asDriver(),
|
||||
itemDelete: tableView.rx.itemDeleted.asDriver(),
|
||||
itemSelected: tableView.rx.modelSelected(MessageTableViewCellViewModel.self).asDriver(),
|
||||
itemSelected: tableView.rx.itemSelected.asDriver(),
|
||||
delete: batchDelete.asDriver(onErrorDriveWith: .empty()),
|
||||
groupTap: groupButton.rx.tap.asDriver(),
|
||||
groupTap: groupBtn.rx.tap.asDriver(),
|
||||
searchText: navigationItem.searchController!.searchBar.rx.text.asObservable()))
|
||||
|
||||
// tableView 刷新状态
|
||||
@ -166,7 +181,7 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
|
||||
|
||||
// message操作alert
|
||||
output.alertMessage.drive(onNext: { [weak self] message in
|
||||
self?.alertMessage(message: message)
|
||||
self?.alertMessage(message: message.0, indexPath: message.1)
|
||||
}).disposed(by: rx.disposeBag)
|
||||
|
||||
// 选择群组
|
||||
@ -183,7 +198,7 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
|
||||
self.scrollToTop()
|
||||
}
|
||||
|
||||
func alertMessage(message: String) {
|
||||
func alertMessage(message: String, indexPath: IndexPath) {
|
||||
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
|
||||
let copyAction = UIAlertAction(title: NSLocalizedString("CopyAll"), style: .default, handler: { [weak self]
|
||||
(_: UIAlertAction) -> Void in
|
||||
@ -195,6 +210,13 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
|
||||
|
||||
alertController.addAction(copyAction)
|
||||
alertController.addAction(cancelAction)
|
||||
if UIDevice.current.userInterfaceIdiom == .pad {
|
||||
alertController.modalPresentationStyle = .popover
|
||||
if let cell = self.tableView.cellForRow(at: indexPath) {
|
||||
alertController.popoverPresentationController?.sourceView = self.tableView
|
||||
alertController.popoverPresentationController?.sourceRect = cell.frame
|
||||
}
|
||||
}
|
||||
|
||||
self.navigationController?.present(alertController, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@ -11,13 +11,14 @@ import RealmSwift
|
||||
import RxCocoa
|
||||
import RxDataSources
|
||||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
class MessageListViewModel: ViewModel, ViewModelType {
|
||||
struct Input {
|
||||
var refresh: Driver<Void>
|
||||
var loadMore: Driver<Void>
|
||||
var itemDelete: Driver<IndexPath>
|
||||
var itemSelected: Driver<MessageTableViewCellViewModel>
|
||||
var itemSelected: Driver<IndexPath>
|
||||
var delete: Driver<MessageDeleteType>
|
||||
var groupTap: Driver<Void>
|
||||
var searchText: Observable<String?>
|
||||
@ -26,7 +27,7 @@ class MessageListViewModel: ViewModel, ViewModelType {
|
||||
struct Output {
|
||||
var messages: Driver<[MessageSection]>
|
||||
var refreshAction: Driver<MJRefreshAction>
|
||||
var alertMessage: Driver<String>
|
||||
var alertMessage: Driver<(String, IndexPath)>
|
||||
var groupFilter: Driver<GroupFilterViewModel>
|
||||
var title: Driver<String>
|
||||
}
|
||||
@ -70,8 +71,12 @@ class MessageListViewModel: ViewModel, ViewModelType {
|
||||
}
|
||||
|
||||
func transform(input: Input) -> Output {
|
||||
let alertMessage = input.itemSelected.map { model -> String in
|
||||
let message = model.message
|
||||
let alertMessage = input.itemSelected.map({ [weak self] indexPath in
|
||||
guard let results = self?.results else {
|
||||
return ("", IndexPath(row: 0, section: 0));
|
||||
}
|
||||
let message = results[indexPath.row]
|
||||
// let message = model.message
|
||||
|
||||
var copyContent: String = ""
|
||||
if let title = message.title {
|
||||
@ -85,8 +90,8 @@ class MessageListViewModel: ViewModel, ViewModelType {
|
||||
}
|
||||
copyContent = String(copyContent.prefix(copyContent.count - 1))
|
||||
|
||||
return copyContent
|
||||
}
|
||||
return (copyContent, indexPath)
|
||||
})
|
||||
// 标题
|
||||
let titleRelay = BehaviorRelay<String>(value: NSLocalizedString("historyMessage"))
|
||||
// 数据源
|
||||
|
||||
@ -64,14 +64,18 @@ class MessageSettingsViewController: BaseViewController<MessageSettingsViewModel
|
||||
/// 生成导入导出事件
|
||||
func getBackupOrRestoreAction() -> (Driver<Void>, Driver<Data>) {
|
||||
let backupOrRestoreAction = self.tableView.rx
|
||||
.modelSelected(MessageSettingItem.self)
|
||||
.filter { item in
|
||||
if case MessageSettingItem.backup = item {
|
||||
// .modelSelected(MessageSettingItem.self)
|
||||
.itemSelected
|
||||
.filter { indexPath in
|
||||
guard let viewModel: MessageSettingItem = try? self.tableView.rx.model(at: indexPath) else {
|
||||
return false;
|
||||
}
|
||||
if case MessageSettingItem.backup = viewModel {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
.flatMapLatest { [weak self] _ in
|
||||
.flatMapLatest { [weak self] indexPath in
|
||||
guard let strongSelf = self else {
|
||||
return Observable<BackupOrRestoreActionEnum>.empty()
|
||||
}
|
||||
@ -91,7 +95,15 @@ class MessageSettingsViewController: BaseViewController<MessageSettingsViewModel
|
||||
}))
|
||||
|
||||
alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel"), style: .cancel, handler: nil))
|
||||
strongSelf.navigationController?.present(alertController, animated: true, completion: nil)
|
||||
if UIDevice.current.userInterfaceIdiom == .pad {
|
||||
alertController.modalPresentationStyle = .popover
|
||||
if let cell = strongSelf.tableView.cellForRow(at: indexPath) {
|
||||
alertController.popoverPresentationController?.sourceView = strongSelf.tableView
|
||||
alertController.popoverPresentationController?.sourceRect = cell.frame
|
||||
}
|
||||
|
||||
}
|
||||
strongSelf.present(alertController, animated: true, completion: nil)
|
||||
|
||||
return strongSelf.backupOrRestoreActionRelay.asObservable()
|
||||
}
|
||||
@ -210,6 +222,10 @@ class MessageSettingsViewController: BaseViewController<MessageSettingsViewModel
|
||||
}
|
||||
|
||||
let activityController = UIActivityViewController(activityItems: [linkURL], applicationActivities: nil)
|
||||
if UIDevice.current.userInterfaceIdiom == .pad {
|
||||
activityController.popoverPresentationController?.sourceView = self?.view
|
||||
activityController.popoverPresentationController?.sourceRect = self?.view.frame ?? .zero
|
||||
}
|
||||
self?.navigationController?.present(activityController, animated: true, completion: nil)
|
||||
|
||||
}.disposed(by: rx.disposeBag)
|
||||
|
||||
134
Controller/SectionViewController-iPad.swift
Normal file
134
Controller/SectionViewController-iPad.swift
Normal file
@ -0,0 +1,134 @@
|
||||
//
|
||||
// SectionTableViewController-iPad.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by sidguan on 2024/6/23.
|
||||
// Copyright © 2024 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
import NSObject_Rx
|
||||
import RxCocoa
|
||||
import RxDataSources
|
||||
import RxSwift
|
||||
|
||||
class SectionViewController_iPad: BaseViewController<SectionViewModel>, UITableViewDelegate {
|
||||
|
||||
let tableView: UITableView = {
|
||||
let tableView = UITableView(frame: .zero, style: .grouped)
|
||||
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "\(UITableViewCell.self)")
|
||||
tableView.backgroundColor = BKColor.background.primary
|
||||
return tableView
|
||||
}()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.title = "Bark"
|
||||
navigationItem.largeTitleDisplayMode = .automatic
|
||||
}
|
||||
|
||||
override func makeUI() {
|
||||
self.view.addSubview(tableView)
|
||||
tableView.delegate = self
|
||||
tableView.snp.makeConstraints { make in
|
||||
make.edges.equalToSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
override func bindViewModel() {
|
||||
let output = viewModel.transform(input: SectionViewModel.Input())
|
||||
let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, SectionItem>> {
|
||||
_, tableView, _, item -> UITableViewCell in
|
||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: "\(UITableViewCell.self)") else {
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
if #available(iOS 14, *) {
|
||||
cell.backgroundConfiguration = UIBackgroundConfiguration.listPlainCell()
|
||||
}
|
||||
cell.selectionStyle = .gray
|
||||
cell.imageView?.image = item.image
|
||||
cell.imageView?.tintColor = BKColor.grey.darken4
|
||||
cell.textLabel?.text = item.title
|
||||
return cell
|
||||
}
|
||||
tableView.rx
|
||||
.itemSelected
|
||||
.flatMapLatest { indexPath -> Observable<IndexPath> in
|
||||
return Observable.just(indexPath)
|
||||
}
|
||||
.subscribe { indexPath in
|
||||
if #available(iOS 14, *) {
|
||||
if indexPath.row == 0 {
|
||||
self.splitViewController?.setViewController(
|
||||
BarkNavigationController(rootViewController: HomeViewController(viewModel: HomeViewModel())), for: .secondary)
|
||||
} else if indexPath.row == 1 {
|
||||
self.splitViewController?.setViewController(
|
||||
BarkNavigationController(rootViewController: MessageListViewController(viewModel: MessageListViewModel())), for: .secondary)
|
||||
} else if (indexPath.row == 2) {
|
||||
|
||||
self.splitViewController?.setViewController(
|
||||
BarkNavigationController(rootViewController: MessageSettingsViewController(viewModel: MessageSettingsViewModel())), for: .secondary)
|
||||
}
|
||||
} else {
|
||||
// 正常应该走不到这里了
|
||||
}
|
||||
|
||||
}.disposed(by: rx.disposeBag)
|
||||
output.items
|
||||
.bind(to: tableView.rx.items(dataSource: dataSource))
|
||||
.disposed(by: rx.disposeBag)
|
||||
}
|
||||
|
||||
|
||||
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
|
||||
return 55
|
||||
}
|
||||
|
||||
/*
|
||||
// Override to support conditional editing of the table view.
|
||||
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
|
||||
// Return false if you do not want the specified item to be editable.
|
||||
return true
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// Override to support editing the table view.
|
||||
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
|
||||
if editingStyle == .delete {
|
||||
// Delete the row from the data source
|
||||
tableView.deleteRows(at: [indexPath], with: .fade)
|
||||
} else if editingStyle == .insert {
|
||||
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// Override to support rearranging the table view.
|
||||
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// Override to support conditional rearranging of the table view.
|
||||
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
|
||||
// Return false if you do not want the item to be re-orderable.
|
||||
return true
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// MARK: - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
// Get the new view controller using segue.destination.
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
50
Controller/SectionViewModel-iPad.swift
Normal file
50
Controller/SectionViewModel-iPad.swift
Normal file
@ -0,0 +1,50 @@
|
||||
//
|
||||
// SectionViewModel-iPad.swift
|
||||
// Bark
|
||||
//
|
||||
// Created by sidguan on 2024/7/1.
|
||||
// Copyright © 2024 Fin. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import RxCocoa
|
||||
import RxDataSources
|
||||
import RxSwift
|
||||
import Material
|
||||
|
||||
struct SectionItem {
|
||||
let image: UIImage?
|
||||
let title: String
|
||||
}
|
||||
|
||||
class SectionViewModel: ViewModel, ViewModelType {
|
||||
struct Input {
|
||||
// var sectionSelected: Driver<SectionItem>
|
||||
}
|
||||
|
||||
struct Output {
|
||||
var items: Observable<[SectionModel<String, SectionItem>]>
|
||||
// var selectedItem: Observable<SectionItem?>
|
||||
}
|
||||
|
||||
func initSectionItems() -> Observable<[SectionModel<String, SectionItem>]> {
|
||||
return Observable.create { (observer) -> Disposable in
|
||||
let sectionItems = [
|
||||
SectionItem(image: UIImage(named: "baseline_gite_black_24pt"), title: NSLocalizedString("service")),
|
||||
SectionItem(image: Icon.history, title: NSLocalizedString("historyMessage")),
|
||||
SectionItem(image: UIImage(named: "baseline_manage_accounts_black_24pt"), title: NSLocalizedString("settings")),
|
||||
]
|
||||
let section = [SectionModel(model: "", items: sectionItems)]
|
||||
observer.onNext(section)
|
||||
observer.onCompleted()
|
||||
return Disposables.create()
|
||||
}
|
||||
}
|
||||
|
||||
func transform(input: Input) -> Output {
|
||||
let sectionItems = initSectionItems()
|
||||
return Output(
|
||||
items: sectionItems
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -124,9 +124,12 @@ class ServerListViewController: BaseViewController<ServerListViewModel> {
|
||||
func getServerAction() -> Driver<(Server, ServerActionType)> {
|
||||
|
||||
return tableView.rx
|
||||
.modelSelected(ServerListTableViewCellViewModel.self)
|
||||
.flatMapLatest { viewModel -> PublishRelay<(Server, ServerActionType)> in
|
||||
.itemSelected
|
||||
.flatMapLatest { indexPath in
|
||||
let relay = PublishRelay<(Server, ServerActionType)>()
|
||||
guard let viewModel: ServerListTableViewCellViewModel = try? self.tableView.rx.model(at: indexPath) else {
|
||||
return relay;
|
||||
}
|
||||
|
||||
let alertController = UIAlertController(title: nil, message: "\(viewModel.address.value)", preferredStyle: .actionSheet)
|
||||
alertController.addAction(UIAlertAction(title: NSLocalizedString("copyAddressAndKey"), style: .default, handler: { _ in
|
||||
@ -157,6 +160,14 @@ class ServerListViewController: BaseViewController<ServerListViewModel> {
|
||||
}))
|
||||
|
||||
alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel"), style: .cancel, handler: nil))
|
||||
|
||||
if UIDevice.current.userInterfaceIdiom == .pad {
|
||||
alertController.modalPresentationStyle = .popover
|
||||
if let cell = self.tableView.cellForRow(at: indexPath) {
|
||||
alertController.popoverPresentationController?.sourceView = self.tableView
|
||||
alertController.popoverPresentationController?.sourceRect = cell.frame
|
||||
}
|
||||
}
|
||||
self.navigationController?.present(alertController, animated: true, completion: nil)
|
||||
|
||||
return relay
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user