jsdw_ios/QuickLocation/Section/AppRestrict/FamilyActivityPickerHost.swift

154 lines
5.1 KiB
Swift

//
// FamilyActivityPickerHost.swift
// QuickLocation
//
import FamilyControls
import SwiftUI
import UIKit
import ManagedSettings
@available(iOS 16.0, *)
private struct FamilyActivityPickerSheet: View {
@State private var selection: FamilyActivitySelection
@State private var isPresented = true
let onComplete: (FamilyActivitySelection) -> Void
init(initial: FamilyActivitySelection, onComplete: @escaping (FamilyActivitySelection) -> Void) {
_selection = State(initialValue: initial)
self.onComplete = onComplete
}
var body: some View {
Group {
if #available(iOS 26.2, *) {
Color.clear.familyActivityPicker(
title: "选择应用",
footerText: "请展开分类并勾选具体应用,分类“全部”无法加入配对库",
isPresented: $isPresented,
selection: $selection
)
} else {
Color.clear.familyActivityPicker(
footerText: "请展开分类并勾选具体应用,分类“全部”无法加入配对库",
isPresented: $isPresented,
selection: $selection
)
}
}
.environment(\.locale, Locale(identifier: "zh-Hans"))
.onChange(of: isPresented) { presented in
if !presented {
onComplete(selection)
}
}
}
}
@available(iOS 16.0, *)
final class FamilyActivityPickerPresenter: UIViewController {
private let initial: FamilyActivitySelection
var onComplete: ((FamilyActivitySelection) -> Void)?
init(selection: FamilyActivitySelection = FamilyActivitySelection(includeEntireCategory: false)) {
self.initial = selection
super.init(nibName: nil, bundle: nil)
modalPresentationStyle = .overFullScreen
view.backgroundColor = .clear
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
guard children.isEmpty else { return }
let root = FamilyActivityPickerSheet(initial: initial) { [weak self] selection in
guard let self else { return }
let completion = self.onComplete
self.dismiss(animated: false) {
completion?(selection)
}
}
let host = UIHostingController(rootView: root)
host.view.backgroundColor = .clear
addChild(host)
view.addSubview(host.view)
host.view.frame = .zero
host.didMove(toParent: self)
}
}
@available(iOS 16.0, *)
struct ApplicationTokenLabelView: View {
let token: ApplicationToken
var body: some View {
Label(token)
.labelStyle(.titleAndIcon)
.lineLimit(1)
}
}
@available(iOS 16.0, *)
struct ApplicationTokenIconView: View {
let token: ApplicationToken
var body: some View {
Label(token)
.labelStyle(.iconOnly)
.scaleEffect(2.4)
.frame(width: 40, height: 40)
.clipped()
}
}
@available(iOS 16.0, *)
final class ApplicationTokenIconHostingView: UIView {
private let hosting: UIHostingController<ApplicationTokenIconView>
init(token: ApplicationToken) {
hosting = UIHostingController(rootView: ApplicationTokenIconView(token: token))
super.init(frame: .zero)
hosting.view.backgroundColor = .clear
addSubview(hosting.view)
hosting.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
hosting.view.topAnchor.constraint(equalTo: topAnchor),
hosting.view.leadingAnchor.constraint(equalTo: leadingAnchor),
hosting.view.trailingAnchor.constraint(equalTo: trailingAnchor),
hosting.view.bottomAnchor.constraint(equalTo: bottomAnchor)
])
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
func update(token: ApplicationToken) {
hosting.rootView = ApplicationTokenIconView(token: token)
}
}
@available(iOS 16.0, *)
final class ApplicationTokenLabelHostingView: UIView {
private let hosting: UIHostingController<ApplicationTokenLabelView>
init(token: ApplicationToken) {
hosting = UIHostingController(rootView: ApplicationTokenLabelView(token: token))
super.init(frame: .zero)
hosting.view.backgroundColor = .clear
addSubview(hosting.view)
hosting.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
hosting.view.topAnchor.constraint(equalTo: topAnchor),
hosting.view.leadingAnchor.constraint(equalTo: leadingAnchor),
hosting.view.trailingAnchor.constraint(equalTo: trailingAnchor),
hosting.view.bottomAnchor.constraint(equalTo: bottomAnchor)
])
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
func update(token: ApplicationToken) {
hosting.rootView = ApplicationTokenLabelView(token: token)
}
}