- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是使用 Swift 进行 iOS 开发的新手。所以,我可能在 Swift 中遗漏了一个我不知道的简单解决方案。
我正在开发一个 tvOS 应用程序,在其中显示用户可以从中选择的视频内容列表。该应用程序还包含一个设置选项卡,允许用户配置 5 种不同类型的设置。一旦他们选择了一个特定的类别,它就会显示一个新的表格 View ,其中包含选项数组中的相应选项。这就是我需要帮助的“问题”。
我有这个结构,我将其用作单例:
struct BMUserSettings
{
internal static var shared = BMUserSettings()
var categories = [String]()
var options = [[String]]()
var currOptionsSelected: [Int] = [0,0,0,0,0] // This array corresponds to the categories array. It tells us what option within that group was selected.
init()
{
self.categories = ["Brand", "Environment","UI Language", "Playback Language", "Geo Location Permission"]
let brandOptionsGroup: [String] = ["CTV", "CTVHUB", "TSN", "Snackable", "RDS", "CP24", "BNN", "CTVNews", "Crave", "BRAVO", "E_BRAND", "SE", "VIDIQA"]
let environmentOptionsGroup: [String] = ["Staging", "Prod"]
let uiLanguageOptionsGroup: [String] = ["en", "fr"]
let playbackLanguageOptionsGroup: [String] = ["en", "fr"]
let geoLocationOptionsGroup: [String] = ["Allow", "Don't Allow"]
options.append(brandOptionsGroup)
options.append(environmentOptionsGroup)
options.append(uiLanguageOptionsGroup)
options.append(playbackLanguageOptionsGroup)
options.append(geoLocationOptionsGroup)
}
// MARK: - Custom Methods
func displayUserSettings() -> String
{
let displayText: String = "Brand=\(options[0][currOptionsSelected[0]]) Environment=\(options[1][currOptionsSelected[1]]) UI Language=\(options[2][currOptionsSelected[2]]) Playback Language=\(options[3][currOptionsSelected[3]]) Geo Location=\(options[4][currOptionsSelected[4]])"
return displayText
}
// MARK: - User Defaults
func saveToUserDefaults()
{
UserDefaults.standard.set(BMUserSettings.shared.currOptionsSelected, forKey: "currentoptions")
}
func loadFromUserDefaults(){
if let currentOptionsSelected = UserDefaults.standard.object(forKey: "currentoptions") as? [Int]{
BMUserSettings.shared.currOptionsSelected = currentOptionsSelected
}
else{
BMUserSettings.shared.currOptionsSelected = [0,0,0,0,0]
}
}
}
import UIKit
final class BMSettingsViewController: UIViewController
{
// MARK: - Instance Variables
private static let reuseIdentifier = String(describing: BMContentCell.self)
private let tableview = UITableView(backgroundColor: .white, autoResizingMask: false)
private let tabBarBannerHeight: CGFloat = 150
private var selectedCategoryIndex: Int = 0
private var settingsDetailVC: BMDetailSettingsViewController?
private var categoryNames: [String] = [String]()
private var categoryOptions: [String] = [String]()
// MARK: - View Lifecycle Methods
override func viewWillAppear(_ animated: Bool)
{
super.viewWillAppear(animated)
categoryNames = BMCategory.allValues
categoryOptions = BMUserSettings.shared.currOptionsSelected.map { $0.value }
self.tableview.reloadData()
}
override func viewWillDisappear(_ animated: Bool)
{
BMUserSettings.shared.saveToUserDefaults()
}
override func loadView()
{
super.loadView()
self.tableview.dataSource = self
self.tableview.delegate = self
self.tableview.register(BMUserSettingsCell.self, forCellReuseIdentifier: BMSettingsViewController.reuseIdentifier)
displayContent()
}
// MARK: - Custom Methods
private func displayContent()
{
view.addSubview(tableview)
tableview.anchor(
top: self.view.topAnchor,
leading: self.view.leadingAnchor,
bottom: self.view.bottomAnchor,
trailing: self.view.trailingAnchor,
padding: UIEdgeInsets(top: tabBarBannerHeight, left: 0, bottom: 0, right: 0)
)
}
}
// MARK: - UITableView Datasource & Delegate Extension
extension BMSettingsViewController: UITableViewDataSource, UITableViewDelegate
{
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
{
return "Select an option below to configure it's settings..."
}
func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return categoryNames.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: BMSettingsViewController.reuseIdentifier, for: indexPath) as! BMUserSettingsCell
cell.configureCell(categoryName: categoryNames[indexPath.row], optionDetailDescription: categoryOptions[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let selectedCategory = categoryNames[indexPath.row]
settingsDetailVC = BMDetailSettingsViewController()
guard let settingsVC = settingsDetailVC else {return}
settingsVC.options = BMUserSettings.shared.options[BMCategory.init(rawValue: selectedCategory)!]!
settingsVC.delegate = self
settingsVC.selectedCategoryIndex = indexPath.row
BMViewControllerManager.shared.getTopViewController()?.present(settingsVC, animated: true)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return 120
}
}
// MARK: - Protocol Extension
extension BMSettingsViewController: OptionsSelector
{
func didFinishSelectingOption(selectedCategoryIndex: Int, selectedOptionIndex: Int)
{
self.selectedCategoryIndex = selectedCategoryIndex
// BMUserSettings.shared.currOptionsSelected[self.selectedCategoryIndex] = selectedOptionIndex
}
}
import UIKit
// MARK: - Protocol (used to notify Settings view controller when an option was selected)
protocol OptionsSelector
{
func didFinishSelectingOption(selectedCategoryIndex: Int, selectedOptionIndex: Int)
}
final class BMDetailSettingsViewController: UIViewController
{
// MARK: - Instance Variables
private let cellId = "cellId"
private let tabBarBannerHeight: CGFloat = 150
private var selectedOptionIndex: Int = 0
private let tableview = UITableView(backgroundColor: .white, autoResizingMask: false)
var options: [String] = [String]()
var selectedCategoryIndex: Int = 0
var delegate: OptionsSelector?
// MARK: - View Life Cycle Methods
override func loadView()
{
super.loadView()
self.tableview.dataSource = self
self.tableview.delegate = self
self.tableview.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
displayContent()
}
// MARK: - Custom Methods
private func displayContent()
{
view.addSubview(tableview)
tableview.anchor(
top: self.view.topAnchor,
leading: self.view.leadingAnchor,
bottom: self.view.bottomAnchor,
trailing: self.view.trailingAnchor,
padding: UIEdgeInsets(top: tabBarBannerHeight, left: 0, bottom: 0, right: 0)
)
}
}
// MARK: - UITableView Datasource & Delegate Extension
extension BMDetailSettingsViewController: UITableViewDataSource, UITableViewDelegate
{
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return "Select an option below..." }
func numberOfSections(in tableView: UITableView) -> Int { return 1 }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return options.count }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
cell.textLabel?.text = "\(options[indexPath.row])"
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
BMViewControllerManager.shared.getTopViewController()?.dismiss(animated: true)
self.selectedOptionIndex = indexPath.row
self.delegate?.didFinishSelectingOption(selectedCategoryIndex: self.selectedCategoryIndex, selectedOptionIndex: self.selectedOptionIndex)
}
}
最佳答案
首先创建一个enum Category
,
enum Category: String {
case brand = "Brand"
case environment = "Environment"
case uiLanguage = "UI Language"
case playbackLanguage = "Playback Language"
case geoLocationPermission = "Geo Location"
}
options
类型 [Category:[String]]
, currOptionsSelected
类型 [Category:String]
和 defaultOptions
类型 [Category:String]
. displayUserSettings
, 符合 struct BMUserSettings
至CustomStringConvertible
并实现 description
返回相关String
值(value)。 init()
如private
. array
对于 categories
. struct BMUserSettings
会像,
struct BMUserSettings: CustomStringConvertible {
static var shared = BMUserSettings()
let options: [Category:[String]]
let defaultOptions: [Category:String]
var currOptionsSelected: [Category:String]
let categories: [Category]
private init() {
options = [
.brand : ["CTV", "CTVHUB", "TSN", "Snackable", "RDS", "CP24", "BNN", "CTVNews", "Crave", "BRAVO", "E_BRAND", "SE", "VIDIQA"],
.environment : ["Staging", "Prod"],
.uiLanguage : ["en", "fr"],
.playbackLanguage : ["en", "fr"],
.geoLocationPermission : ["Allow", "Don't Allow"]
]
defaultOptions = self.options.mapValues{ $0.first! }
currOptionsSelected = self.defaultOptions
categories = [.brand, .environment, .uiLanguage, .playbackLanguage, .geoLocationPermission]
}
var description: String {
return self.currOptionsSelected.reduce("") { (result, option) -> String in
return "\(result) \(option.key.rawValue) = \(option.value)\n"
}
}
// MARK: - User Defaults
func saveToUserDefaults() {
var dict = [String:String]()
currOptionsSelected.forEach { dict[$0.key.rawValue] = $0.value }
UserDefaults.standard.set(dict, forKey: "currentoptions")
}
mutating func loadFromUserDefaults() {
if let currentOptionsSelected = UserDefaults.standard.object(forKey: "currentoptions") as? [String:String] {
var dict = [Category:String]()
currentOptionsSelected.forEach {
if let category = Category(rawValue: $0.key) {
dict[category] = $0.value
}
}
self.currOptionsSelected = dict
}
else {
self.currOptionsSelected = self.defaultOptions
}
}
}
BMUserSettings.shared.currOptionsSelected[.brand] = "Snackable"
BMUserSettings.shared.saveToUserDefaults()
BMUserSettings.shared.loadFromUserDefaults()
print(BMUserSettings.shared)
BMUserSettings.shared.categories.forEach {
print($0.rawValue, ":", BMUserSettings.shared.currOptionsSelected[$0]!)
}
关于ios - 处理此类问题的更好方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60282026/
对于 Metal ,如果对主纹理进行 mipmap 处理,是否还需要对多采样纹理进行 mipmap 处理?我阅读了苹果文档,但没有得到任何相关信息。 最佳答案 Mipmapping 适用于您将从中
我正在使用的代码在后端 Groovy 代码中具有呈现 GSP(Groovy 服务器页面)的 Controller 。对于前端,我们使用 React-router v4 来处理路由。我遇到的问题是,通过
我们正在 build 一个巨大的网站。我们正在考虑是在服务器端(ASP .Net)还是在客户端进行 HTML 处理。 例如,我们有 HTML 文件,其作用类似于用于生成选项卡的模板。服务器端获取 HT
我正在尝试将图像加载到 void setup() 中的数组中,但是当我这样做时出现此错误:“类型不匹配,'processing .core.PImage' does not匹配“processing.
我正在尝试使用其私有(private)应用程序更新 Shopify 上的客户标签。我用 postman 尝试过,一切正常,但通过 AJAX,它带我成功回调而不是错误,但成功后我得到了身份验证链接,而不
如何更改我的 Processing appIconTest.exe 导出的默认图标在窗口中的应用程序? 默认一个: 最佳答案 经过一些研究,我能找到的最简单的解决方案是: 进入 ...\process
我在 Processing 中做了一个简单的小游戏,但需要一些帮助。我有一个 mp3,想将它添加到我的应用程序中,以便在后台循环运行。 这可能吗?非常感谢。 最佳答案 您可以使用声音库。处理已经自带
我有几个这样创建的按钮: 在 setup() PImage[] imgs1 = {loadImage("AREA1_1.png"),loadImage("AREA1_2.png"),loadImage
我正在尝试使用 Processing 创建一个多人游戏,但无法弄清楚如何将屏幕分成两个以显示玩家的不同情况? 就像在 c# 中一样,我们有Viewport leftViewport,rightView
我一直在尝试使用 Moore 邻域在处理过程中创建元胞自动机,到目前为止非常成功。我已经设法使基本系统正常工作,现在我希望通过添加不同的功能来使用它。现在,我检查细胞是否存活。如果是,我使用 fill
有没有办法用 JavaScript 代码检查资源使用情况?我可以检查脚本的 RAM 使用情况和 CPU 使用情况吗? 由于做某事有多种方法,我可能会使用不同的方法编写代码,并将其保存为两个不同的文件,
我想弄清楚如何处理这样的列表: [ [[4,6,7], [1,2,4,6]] , [[10,4,2,4], [1]] ] 这是一个整数列表的列表 我希望我的函数将此列表作为输入并返回列表中没有重复的整
有没有办法在不需要时处理 MethodChannel/EventChannel ?我问是因为我想为对象创建多个方法/事件 channel 。 例子: class Call { ... fields
我有一个关于在 Python3 中处理 ConnectionResetError 的问题。这通常发生在我使用 urllib.request.Request 函数时。我想知道如果我们遇到这样的错误是否可
我一直在努力解决这个问题几个小时,但无济于事。代码很简单,一个弹跳球(粒子)。将粒子的速度初始化为 (0, 0) 将使其保持上下弹跳。将粒子的初始化速度更改为 (0, 0.01) 或任何十进制浮点数都
我把自己弄得一团糟。 我想在我的系统中添加 python3.6 所以我决定在我的 Ubuntu 19.10 中卸载现有的。但是现在每次我想安装一些东西我都会得到这样的错误: dpkg: error w
我正在努力解决 Rpart 包中的 NA 功能。我得到了以下数据框(下面的代码) Outcome VarA VarB 1 1 1 0 2 1 1 1
我将 Java 与 JSF 一起使用,这是 Glassfish 3 容器。 在我的 Web 应用程序中,我试图实现一个文件(图像)管理系统。 我有一个 config.properties我从中读取上传
所以我一直在Processing工作几个星期以来,虽然我没有编程经验,但我已经转向更复杂的项目。我正在编写一个进化模拟器,它会产生具有随机属性的生物。 最终,我将添加复制,但现在这些生物只是在屏幕上漂
有人知道 Delphi 2009 对“with”的处理有什么不同吗? 我昨天解决了一个问题,只是将“with”解构为完整引用,如“with Datamodule、Dataset、MainForm”。
我是一名优秀的程序员,十分优秀!