- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用这个 Ray Wenderlich tutorial作为我正在从事的项目的指南。但是,我正在尝试扩展此模板以合并子目录、子子目录、子子子目录等。
例如,如果您单击主/主目录屏幕中的“Candy Cane”单元格,它将带您进入带有表格 View (也称为子目录屏幕)的"new" View Controller ,其中将显示各种糖果供应商以及它们的价格是贵还是便宜(这将是每一行的副标题)。见 subCategory
... txt 文件在下面。
我在这篇文章中交替使用了类别和目录这两个词。
这是第一个问题。过去,我创建了一个项目来做这件事,但是我通过许多 Storyboard和 View Controller 文件来完成我导航的每个子类别的工作。同样的原则也适用于从子类别移动到子子类别屏幕等等。
我不想做广告:但具体来说,我正在开发的应用程序名为 iEngineering它可以在 AppStore 上免费获得。请查看应用程序的库部分,因为我相信它会为理解我的最终目标提供额外帮助。请记住,当前版本的应用程序是使用无数 Storyboard和 View Controller 文件构建的,每次我在 Xcode 中运行模拟器时都必须构建这些文件。查看显示库功能的应用程序屏幕截图就足够了,而无需下载应用程序。
这是第二个问题。我在这个应用程序中也有子子类别等等。例如,如果您单击子类别屏幕中显示拐杖糖供应商和价格列表的单元格,它将导航到一个新屏幕(子子类别),以显示该特定供应商的所有不同拐杖糖销售量。所以在下面我虚构的文本文件中,subCandyCaneTextFile.txt
,如果您单击带有“Candy Cane King”标签的单元格,它将带您进入显示“Candy Cane King”作为导航标题的屏幕,并显示/加载列表(通过阅读文本文件导入)显示Candy Cane King 提供的所有 Lollipop 。 我没有提供这个和其他我认为是子子类别的 txt 文件 .当我在下面问我问题的根本/核心时,我希望你们都记住这一点。
对于这个项目,我想远离使用带有许多 View Controller 的多个 Storyboard。这是因为每次我在模拟器中构建它时,我之前的项目都需要大约 5 到 10 分钟来编译/构建。因此,我试图在项目运行时为我的应用程序中的每个新/类别屏幕读取文本文件。我希望这会给我带来更快的运行时间(约 10 秒)。
在下面的示例中,类别/主 View Controller 通过读取 txt 文件 candyTextFile.txt
来呈现其数据。
我的问题:我怎样才能为子类别屏幕处理(从|删除)旧数据和(加载|替换)新数据?我想过尝试让它成为 Ray Wenderlich tutorial 中的详细 View Controller 屏幕教程;但是,我不确定如何导航到子子类别屏幕。因此,我认为我的另一个选择可能是一遍又一遍地使用 UITableView(主 View Controller )重用一个 View Controller 。我不确定解决这个问题的正确方法,因为我对学习 Swift 和 Xcode 还比较陌生。
current project via Xcode概述对于这篇文章。
在我的 MasterViewController.swift 中,
import UIKit
class MasterViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// MARK: - Properties
@IBOutlet var tableView: UITableView!
@IBOutlet var searchFooter: SearchFooter!
var detailViewController: DetailViewController? = nil
var candies = [Candy]()
var filteredCandies = [Candy]()
let searchController = UISearchController(searchResultsController: nil)
// MARK: - View Setup
override func viewDidLoad() {
super.viewDidLoad()
// Setup the Search Controller
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search Candies"
navigationItem.searchController = searchController
definesPresentationContext = true
// Setup the Scope Bar
searchController.searchBar.scopeButtonTitles = ["All", "Chocolate","Hard", "Other"]
searchController.searchBar.delegate = self
// Setup the search footer
tableView.tableFooterView = searchFooter
setupArray()
if let splitViewController = splitViewController {
let controllers = splitViewController.viewControllers
detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
}
}
private func setupArray() {
if let filepath = Bundle.main.path(forResource: "candyTextFile", ofType: "txt") {
do {
let contents = try String(contentsOfFile: filepath)
let lines_separatedBy_n : [String] = contents.components(separatedBy: "\n")
let string = lines_separatedBy_n.map { String($0) }.joined(separator: ", ")
var lines_separatedBy_comma : [String] = string.components(separatedBy: ", ")
// I've put this in to remove the last bit of the file that was causing the count to be one too high.
// I'm guessing that's why you had something similar previously?
lines_separatedBy_comma.removeLast()
for (index, element) in lines_separatedBy_comma.enumerated() {
if index % 2 == 0 {
let newCategory = element
let newName = lines_separatedBy_comma[index + 1]
let newCandy = Candy(category: newCategory, name: newName)
candies.append(newCandy)
}
}
for candy in candies {
print("category: \(candy.category), name: \(candy.name)")
}
//("\ncandies: \(candies)")
} catch let error as NSError {
print(error.localizedDescription)
}
}
print("\ncandies: \(candies)")
}
override func viewWillAppear(_ animated: Bool) {
print("splitViewController!.isCollapsed: \(splitViewController!.isCollapsed)")
if splitViewController!.isCollapsed {
if let selectionIndexPath = tableView.indexPathForSelectedRow {
tableView.deselectRow(at: selectionIndexPath, animated: animated)
}
}
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table View
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isFiltering() {
print("Is filtering")
searchFooter.setIsFilteringToShow(filteredItemCount: filteredCandies.count, of: candies.count)
return filteredCandies.count
}
print("Is not filtering")
searchFooter.setNotFiltering()
return candies.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let candy: Candy
if isFiltering() {
candy = filteredCandies[indexPath.row]
} else {
candy = candies[indexPath.row]
}
cell.textLabel!.text = candy.name
cell.detailTextLabel!.text = candy.category
return cell
}
// MARK: - Segues
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let candy: Candy
if isFiltering() {
candy = filteredCandies[indexPath.row]
} else {
candy = candies[indexPath.row]
}
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
controller.detailCandy = candy
controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
}
func filterContentForSearchText(_ searchText: String, scope: String = "All") {
filteredCandies = candies.filter({
(candy : Candy) -> Bool in
let doesCategoryMatch = (scope == "All") || (candy.category == scope)
if searchBarIsEmpty(){
return doesCategoryMatch
}else {
return doesCategoryMatch && candy.name.lowercased().contains(searchText.lowercased())
}
})
tableView.reloadData()
}
func searchBarIsEmpty() -> Bool {
return searchController.searchBar.text?.isEmpty ?? true
}
func isFiltering() -> Bool {
let searchBarScoperIsFiltering = searchController.searchBar.selectedScopeButtonIndex != 0
return searchController.isActive && (!searchBarIsEmpty() || searchBarScoperIsFiltering)
}
}
extension MasterViewController: UISearchBarDelegate {
// MARK: - UISearchBar Delegate
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])
}
}
extension MasterViewController: UISearchResultsUpdating {
// MARK: - UISearchBar Delegate
func updateSearchResults(for searchController: UISearchController) {
let searchBar = searchController.searchBar
let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
filterContentForSearchText(searchController.searchBar.text!, scope: scope)
}
}
Chocolate, Chocolate Bar
Chocolate, Chocolate Chip
Chocolate, Dark Chocolate
Hard, Lollipop
Hard, Candy Cane
Hard, Jaw Breaker
Other, Caramel
Other, Sour Chew
Other, Gummi Bear
Other, Candy Floss
Chocolate, Chocolate Coin
Chocolate, Chocolate Egg
Other, Jelly Beans
Other, Liquorice
Hard, Toffee Apple
Cheap, Brachs
Expensive, Spangler
Expensive, Bobs
Cheap, Candy Cane King
Expensive, Jelly Belly
Cheap, Ghirardelli
Expensive, Dove
Expensive, Lindt
Cheap, Hersheys
Expensive, Hu Dark
Cheap, Zollipops
Cheap, YumEarth
Expensive, Dum Dums
最佳答案
您可以重复使用 DetailViewController
来自同一个 Storyboard。分配 Storyboard ID
到它,然后您可以创建 DetailViewController
的新实例从当前类(class)开始。您可以保留新 VC 的索引,例如递增它并使用它例如从预定义的数组中获取下一个类别文件名并将其加载到 viewDidLoad
中。
在 DetailViewController
类(class):
var index = 0;
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let st = UIStoryboard(name: "Main", bundle: nil)
let vc = st.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController
vc.index = self.index + 1;
self.navigationController?.pushViewController(vc, animated: true)
}
let files = ["file1", "file2", "file3"]
setupArray()
用它
if let filepath = Bundle.main.path(forResource: files[index], ofType: "txt")
关于ios - 在 Master-Detail 应用程序中为 Master/Detail View Controller 重用 UIViewController(带有 UITableView)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54058881/
这是我的代码。 1 Demo 1 2 Demo 2 3 Demo 3 我想做的是——如果任何一个的细节标签已打开,我打开/查看另一个 标签,那么较早的标签应该关闭/
我正在尝试构建一个 iPad Master-Detail 应用程序。主视图只是一个 TableViewController。我想为用户在主视图中点击的每个不同单元格更改完整的详细信息 View 。其中
我目前在我的子主题的 functions.php 文件中有一些代码,它应该在我的 WooCommerce 结帐页面上将“账单详细信息”更改为“运输详细信息”。 但是,当我更新到 WooCommerce
我想刷新 MasterDetail 项目中的详细信息页面。 (在模态 Controller 中进行编辑后应刷新详细信息。)我知道将代码块放在详细信息页面中的何处以强制刷新。我只是不知道要使用什么代码来
我的应用程序中有一个主从模式,但我希望细节能够切换 View 。我想尽可能多地节省空间,以便“内容”既漂亮又宽敞。 如何从一个“细节”导航到另一个“细节”,同时让“向上”按钮返回“主”列表?(参见“细
在过去,我有一个包含这样一个表的数据库: ProductID | ProductName | InStockWareHouse1 | InstockWareHouse2 ---------------
boost::details::pool::pthread_mutex 和 boost::details::pool::null_mutex 有什么区别。 我看到在最新的 boost 版本 - 1.4
我只获取数据源的详细信息,但没有获取 google fit 消耗的卡路里。如何获得燃烧卡路里的详细信息。我可以从( Google Fitness API returns only {} as resu
我刚刚在 Xcode 5 中创建了一个新的“Master-Detail application”项目。 然后在我的主视图 Controller 上,我将 TableView 更改为静态,并添加了一些项
我试图在“me”/me 部分下命名多个路由,以便在此命名空间下拥有所有基于用户配置文件/帐户的内容,以实现更干净的路由。 解决这个问题的最佳方法是什么?我发现重写默认的 REST 路由(profile
所以我是 Android 开发的新手,并试图了解主/细节流程设计。因此,我使用 Eclipse 为您创建的默认类 - 因此 ScreenDetailActivity、ScreenDetailFragm
我使用 var contacts:[details] 编写代码? = nil 我遇到了无法访问 contacts?.count 的问题,我不得不在任何地方使用可选值。例如 contacts[index
我已经成功地将 www.my-website/blog.php 重写为 www.my-website/blog 现在,我想对我的 blog-detail.php 页面做进一步的事情 从 www.my-
在问这个问题之前,我想说 this stackoverflow 中的问题与我的问题非常相似,但概念仍然不清楚,非常困惑。 我想了解依赖倒置原则,但我无法完全理解它? 下面是DIP说的两点 A. Hig
我是 SYCL/OpenCL/GPGPU 的新手。我正在尝试构建和运行常量加法程序的示例代码, #include #include #include #include namespace sy
我正在使用这个 Ray Wenderlich tutorial作为我正在从事的项目的指南。但是,我正在尝试扩展此模板以合并子目录、子子目录、子子子目录等。 例如,如果您单击主/主目录屏幕中的“Cand
我正在尝试创建一个小扩展,以便我可以从详细 View Controller 访问主视图 Controller 以更新变量。 import UIKit extension UISplitViewCont
我正在尝试基于由 MySQL 数据库支持的 Entity Framework 6 DbContext 实现基本的主从 View 。表格配置尽可能简单: 我的测试应用程序的表单包含两个 ComboBox
我知道这是一个老问题并且已经answered在 objective-c 中。但我正在寻找 Swift 中的解决方案。我在 AppDelegate 中的 splitviewController 代码如下
我的句子很少。在第一句话的结尾(在这一行),我想添加剧透,这将保留故事的其他部分。我正在尝试这样做,但是当单击更多时.. - 我的文本跳到下一行。我需要在一行中继续文本更多...请不要告诉我任何脚本,
我是一名优秀的程序员,十分优秀!