// /* * Copyright (c) 2023 BWI GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import SwiftUI import Foundation /// model for swiftui cell @objcMembers class BWIToggleWithLabelAndSubLabelCellData: NSObject, ObservableObject { @Published var toggleValue: Bool = false @Published var isToggleDisabled: Bool = false @Published var toggleText: String @Published var subText: String let initalToggleValue: Bool init(initalToggleValue: Bool, isToggleDisabled: Bool, toggleText: String, subText: String) { self.initalToggleValue = initalToggleValue self.toggleValue = initalToggleValue self.isToggleDisabled = isToggleDisabled self.toggleText = toggleText self.subText = subText } } /// Helper class for making our SwiftUI view available to ObjectiveC @objcMembers class TableViewCellWithLabelSubLabelAndSwitch: MXKTableViewCell { private var parentViewController: UIViewController? private var hostingController: UIHostingController? private var cellToggleData: BWIToggleWithLabelAndSubLabelCellData? private var theme: Theme! public func makeViewController(parent: UIViewController, rootView: TableViewCellWithLabelSubLabelAndSwitchView) { hostingController = UIHostingController(rootView: rootView) setupView(parent: parent) } // support for objective c vc func makeViewController(parent: UIViewController, toggleData: BWIToggleWithLabelAndSubLabelCellData, onValueChanged:((_ newValue: Bool)-> Void)?) { self.cellToggleData = toggleData if let cellToggleData = self.cellToggleData { hostingController = UIHostingController(rootView: TableViewCellWithLabelSubLabelAndSwitchView(toggleData: bwiToggle, onValueChanged: onValueChanged)) setupView(parent: parent) } } override init!(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupView(parent: UIViewController) { self.parentViewController = parent if let hostingController = hostingController { let shouldControllerMove = hostingController.parent != parent if shouldControllerMove { removeController() parent.addChild(hostingController) } if !self.contentView.subviews.contains(hostingController.view) { self.contentView.addSubview(hostingController.view) self.contentView.vc_addSubViewMatchingParentSafeArea(hostingController.view) } if shouldControllerMove { hostingController.didMove(toParent: parent) } registerThemeServiceDidChangeThemeNotification() update(theme: ThemeService.shared().theme) } } private func registerThemeServiceDidChangeThemeNotification() { NotificationCenter.default.addObserver(self, selector: #selector(themeDidChange), name: .themeServiceDidChangeTheme, object: nil) } @objc private func themeDidChange() { update(theme: ThemeService.shared().theme) } private func update(theme: Theme) { self.theme = theme if let hostingController = hostingController { hostingController.view.backgroundColor = theme.headerBackgroundColor } } func hasBeenInitialized() -> Bool { return self.hostingController != nil } deinit { removeController() } private func removeController() { if let hostingController = hostingController { hostingController.willMove(toParent: nil) hostingController.view.removeFromSuperview() hostingController.removeFromParent() parentViewController = nil } } } struct TableViewCellWithLabelSubLabelAndSwitchView: View { @ObservedObject var toggleData: BWIToggleWithLabelAndSubLabelCellData @Environment(\.theme) private var theme var onValueChanged:((_ newValue: Bool)-> Void)? var body: some View { VStack(alignment: .leading) { HStack { Toggle(isOn: $toggleData.toggleValue) { Text(toggleData.toggleText) .lineLimit(nil) } .onChange(of: toggleData.toggleValue) { newValue in onValueChanged?(newValue) } .toggleStyle(SwitchToggleStyle(tint: Color(ThemeService.shared().theme.tintColor))) .disabled(toggleData.isToggleDisabled) } Text(toggleData.subText) .font(.system(size: 15)) .foregroundColor(theme.colors.secondaryContent) .lineLimit(nil) } .padding([.leading, .trailing], 16) .padding([.top, .bottom], 8) } }