diff --git a/suixinkan/Base/BaseViewController.swift b/suixinkan/Base/BaseViewController.swift index 66a47d7..e7bdf43 100644 --- a/suixinkan/Base/BaseViewController.swift +++ b/suixinkan/Base/BaseViewController.swift @@ -119,6 +119,30 @@ class BaseViewController: UIViewController { navigationController?.popViewController(animated: true) } + /// 沿 presentation 链找到当前最顶层控制器,避免 Sheet 已展示时 present 冲突。 + func topMostPresentedViewController() -> UIViewController { + var top: UIViewController = self + while let presented = top.presentedViewController { + top = presented + } + return top + } + + /// 在当前可见 presentation 链顶端弹出页面。 + func presentOnTop( + _ viewController: UIViewController, + animated: Bool = true, + completion: (() -> Void)? = nil + ) { + topMostPresentedViewController().present(viewController, animated: animated, completion: completion) + } + + /// 全屏预览网络图片。 + func presentImagePreview(imageURLs: [String], startIndex: Int) { + guard !imageURLs.isEmpty else { return } + presentOnTop(ImagePreviewViewController(imageURLs: imageURLs, startIndex: startIndex)) + } + // MARK: - Notifications private func registerBaseNotifications() { diff --git a/suixinkan/UI/Orders/OrderSourceLeadListViewController.swift b/suixinkan/UI/Orders/OrderSourceLeadListViewController.swift index 7d37332..08311e3 100644 --- a/suixinkan/UI/Orders/OrderSourceLeadListViewController.swift +++ b/suixinkan/UI/Orders/OrderSourceLeadListViewController.swift @@ -16,7 +16,6 @@ final class OrderSourceLeadListViewController: BaseViewController, UITableViewDa private let loadLeads: (OrderSourcePerson) async -> Void private let onLeadBound: (OrderSourceSelection) -> Void private let onCallPhone: (String) -> Void - private let onPreviewImages: ([String], Int) -> Void private let phoneRow = UIStackView() private let phoneLabel = UILabel() @@ -32,8 +31,7 @@ final class OrderSourceLeadListViewController: BaseViewController, UITableViewDa referralOrder: BoundReferralOrderEntity?, loadLeads: @escaping (OrderSourcePerson) async -> Void, onLeadBound: @escaping (OrderSourceSelection) -> Void, - onCallPhone: @escaping (String) -> Void, - onPreviewImages: @escaping ([String], Int) -> Void + onCallPhone: @escaping (String) -> Void ) { self.person = person self.orderNumber = orderNumber @@ -42,7 +40,6 @@ final class OrderSourceLeadListViewController: BaseViewController, UITableViewDa self.loadLeads = loadLeads self.onLeadBound = onLeadBound self.onCallPhone = onCallPhone - self.onPreviewImages = onPreviewImages super.init(nibName: nil, bundle: nil) } @@ -178,7 +175,9 @@ final class OrderSourceLeadListViewController: BaseViewController, UITableViewDa && currentSelection?.lead.key == lead.key cell.configure(lead: lead, selected: selected) cell.onCallPhone = onCallPhone - cell.onImageTap = onPreviewImages + cell.onImageTap = { [weak self] urls, index in + self?.presentImagePreview(imageURLs: urls, startIndex: index) + } cell.onSelect = { [weak self] in guard let self else { return } let selection = OrderSourceSelection(person: self.person, lead: lead) diff --git a/suixinkan/UI/Orders/OrderSourcePickerViewController.swift b/suixinkan/UI/Orders/OrderSourcePickerViewController.swift index d947b7f..6a7912f 100644 --- a/suixinkan/UI/Orders/OrderSourcePickerViewController.swift +++ b/suixinkan/UI/Orders/OrderSourcePickerViewController.swift @@ -15,7 +15,6 @@ final class OrderSourcePickerViewController: UIViewController, UITableViewDataSo private let loadLeads: (OrderSourcePerson) async -> Void private let onLeadBound: (OrderSourceSelection) -> Void private let onCallPhone: (String) -> Void - private let onPreviewImages: ([String], Int) -> Void private let titleLabel = UILabel() private let subtitleLabel = UILabel() @@ -29,8 +28,7 @@ final class OrderSourcePickerViewController: UIViewController, UITableViewDataSo referralOrder: BoundReferralOrderEntity?, loadLeads: @escaping (OrderSourcePerson) async -> Void, onLeadBound: @escaping (OrderSourceSelection) -> Void, - onCallPhone: @escaping (String) -> Void, - onPreviewImages: @escaping ([String], Int) -> Void + onCallPhone: @escaping (String) -> Void ) { self.orderNumber = orderNumber self.viewModel = viewModel @@ -38,7 +36,6 @@ final class OrderSourcePickerViewController: UIViewController, UITableViewDataSo self.loadLeads = loadLeads self.onLeadBound = onLeadBound self.onCallPhone = onCallPhone - self.onPreviewImages = onPreviewImages super.init(nibName: nil, bundle: nil) } @@ -157,8 +154,7 @@ final class OrderSourcePickerViewController: UIViewController, UITableViewDataSo referralOrder: referralOrder, loadLeads: loadLeads, onLeadBound: onLeadBound, - onCallPhone: onCallPhone, - onPreviewImages: onPreviewImages + onCallPhone: onCallPhone ) navigationController?.setNavigationBarHidden(false, animated: true) navigationController?.pushViewController(leadController, animated: true) diff --git a/suixinkan/UI/Orders/OrdersViewController.swift b/suixinkan/UI/Orders/OrdersViewController.swift index 7b3877f..87db859 100644 --- a/suixinkan/UI/Orders/OrdersViewController.swift +++ b/suixinkan/UI/Orders/OrdersViewController.swift @@ -377,7 +377,7 @@ final class OrdersViewController: BaseViewController, UITableViewDataSource, UIT self?.presentOrderSourcePicker(for: order) } actions.onOrderSourceImageTap = { [weak self] images, index in - self?.presentImagePreview(images: images, startIndex: index) + self?.presentImagePreview(imageURLs: images, startIndex: index) } if let travel = order.photoTravel, travel.canGiftRetouch { actions.onSendGift = { [weak self] in @@ -492,9 +492,6 @@ final class OrdersViewController: BaseViewController, UITableViewDataSource, UIT }, onCallPhone: { [weak self] phone in self?.callPhone(phone) - }, - onPreviewImages: { [weak self] urls, index in - self?.presentImagePreview(images: urls, startIndex: index) } ) self.orderSourcePicker = controller @@ -524,9 +521,4 @@ final class OrdersViewController: BaseViewController, UITableViewDataSource, UIT guard !trimmed.isEmpty, let url = URL(string: "tel://\(trimmed)") else { return } UIApplication.shared.open(url) } - - private func presentImagePreview(images: [String], startIndex: Int) { - guard !images.isEmpty else { return } - present(ImagePreviewViewController(imageURLs: images, startIndex: startIndex), animated: true) - } }