我有一个复杂的问题,我想通过视觉和代码解释。
目前,这就是我的应用程序可视化工作的方式:
我有一个ViewControllerOne
类,其中包含一个包含9个单元格的UITableView
。选择除第2行,第6行和第7行之外的任何行都将使用自己的ViewControllerTwo
和行数转换为UITableView
。
如果选择了行2,6或7,则push segue会将另一个ViewControllerOne
堆叠到现有ViewControllerOne
上。这样做的原因是因为每一行都是一个类别,但第2,6和7行也包含与左侧的ViewControllerOne
Main-VC 完全相同的子类别。 / p>
我想重用ViewControllerOne
类,而不是创建另一个包含与 Main-VC 完全相同的代码的类。
现在,如果选择了 SUB-VC 中的任何行,则也执行推送到ViewControllerTwo
的行。
由于ViewControllerOne
和ViewControllerTwo
已嵌入UINavigationController
,我所拥有的问题位于第5个步骤中:
ViewControllerTwo
(应该这样)MAIN-VC
中的第2,6或7行,我将转到SUB-VC
(如它应该)ViewControllerTwo
(应该这样)ViewControllerTwo
我有一个Manager
类来处理逻辑并与ViewControllerOne
和ViewControllerTwo
进行通信以显示数据。
import UIKit
enum SubGroupState
{
case SubGroup1, None, SubGroup2, SubGroup3
}
class Manager: NSObject
{
public var subGroupState = SubGroupState.None
public var oldSubGroupState = SubGroupState.None
public var showSubGroups = Bool()
override init()
{
super.init()
}
public func initializeGroupState(row: Int) -> UIViewController
{
if showSubGroups == false && oldSubGroupState == .None
{
switch row
{
case 2:
subGroupState = .SubGroup1
break
case 6:
subGroupState = .SubGroup2
break
case 7:
subGroupState = .SubGroup3
break
default:
subGroupState = .None
break
}
}
if (subGroupState != .None && oldSubGroupState == .None)
|| (subGroupState == .None && oldSubGroupState != .None)
{
showSubGroups = true
}
else
{
showSubGroups = false
}
return initializeGroupVC(row: row)
}
fileprivate func initializeGroupVC(row: Int) -> UIViewController
{
let storyboard = UIStoryboard(name: "Main",
bundle: nil)
if showSubGroups == true
&& subGroupState != .None
{
guard let viewControllerOne = storyboard.instantiateViewController(withIdentifier: "ViewControllerOne")
as? ViewControllerOne else {
return UIViewController()
}
viewControllerOne.manager.oldSubGroupState = muscleSubGroupState
viewControllerOne.manager.showSubGroups = showSubGroups
return viewControllerOne
}
else
{
guard let viewControllerTwo = storyboard.instantiateViewController(withIdentifier: "ViewControllerTwo")
as? ViewControllerTwo else {
return UIViewController()
}
return muscleGroupExercisesVC
}
}
}
states
的目的是让我可以处理根据所选单元格的state
显示不同的子类别。
当用户选择一个单元格时,我在Manager
中创建了ViewControllerOne
的实例:
extension ViewControllerOne: UITableViewDataSource
{
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
tableView.deselectRow(at: indexPath,
animated: true)
let viewController = manager.initializeGroupState(row: indexPath.row)
self.navigationController?.pushViewController(viewController,
animated: true)
}
}
class ViewControllerOne: UIViewController
{
public var manager = Manager()
....
}
问题在于函数initializeGroupState
中的逻辑处理,但我尝试了其他不同的组合,并且总是将 Sub-VC 堆叠在现有的之上第2行,第6行和第7行的子VC ,显然对应于 Main-VC 中的子组行,这就是问题我处理逻辑时遇到的困难用。
如果我这样做的方式不对,那么在不重复代码的情况下,是否有更好的替代方案?
注意:我的Storboard只有 Main-VC ViewControllerOne
且segue为ViewControllerTwo
。添加的 Sub-VC ViewControllerOne
可以直观地看到我正在尝试做的事情,但实际上并没有存在于我的故事板中。
答案 0 :(得分:1)
我认为我们可以保持简单可行
class ViewControllerOne: UIViewController, UITableViewDelegate {
var isSubVC = false
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
if self.isSubVC {
// Push to ViewControllerTwo
} else {
// MainVC
if indexPath.row == 2 || indexPath.row == 6 || indexPath.row == 7 {
let subVC = self.storyboard?.instantiateViewController(withIdentifier: "ViewControllerOne") as! ViewControllerOne
subVC.isSubVC = true
self.navigationController?.pushViewController(subVC, animated: true)
} else {
// Push to ViewControllerTwo
}
}
}
}
以下是使用您的经理创意进行导航而无需任何测试的代码。
enum ViewControllerType {
case main, subGroup1, subGroup2, subGroup3
}
class Manager {
public var currentState = ViewControllerType.main
public func initializeGroupState(row: Int) -> UIViewController {
if self.currentState == .main {
// MainVC, should push to SubVC if match condition
switch row {
case 2:
return self.makeSubViewController(state: .subGroup1)
case 6:
return self.makeSubViewController(state: .subGroup2)
case 7:
return self.makeSubViewController(state: .subGroup3)
default:
return self.makeViewControllerTwo()
}
} else {
// Current is SubVC, dont care kind of row, should push to ViewControllerTwo
return self.makeViewControllerTwo()
}
}
private func makeViewControllerTwo() -> UIViewController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "ViewControllerTwo")
return vc
}
private func makeSubViewController(state: ViewControllerType) -> UIViewController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "ViewControllerOne") as! ViewControllerOne
vc.manager.currentState = state
return vc
}
}
答案 1 :(得分:0)
OK!这里发生的是你有一些segues连接到你的tableView,当你在代码中推送一个新的视图控制器时,这会导致问题。
根据您在此处发布的代码,我认为只是从故事板中删除segue就可以解决问题。仅在您tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
中已经执行的代码中完成此操作非常好。
您可以通过单击它们并按退格键来删除segues,视图控制器可以在故事板中自行浮动而不通过segues连接。
答案 2 :(得分:0)
在Objective-C中,逻辑应该是相同的,这就是我要做的事情:
CustomModel:
@property (nonatomic, strong) NSArray *subdata;
@property (nonatomic, strong) NSString *title;
@property (nonatomic, assing) BOOL isSpecial; //of course wording should be adapted to the real logic and your needs
默认情况下,在CustomModel
对象的init上,isSpecial
设置为NO。
ViewControllers:
@property (nonatomic, strong), NSArray *tableViewDataSource;
tableViewDataSource
的{{1}}应该是这样的:
MainViewController
决定下一个viewcontroller的逻辑: 你可以使用Segue或手动实例化/推送,但我建议你继续为这两个方法做同样的方法
- CustomData isSpecial: NO
subdata = [CustomData11, CustomData12...]
- CustomData isSpecial: NO
subdata = [CustomData21, CustomData22...]
- CustomData isSpecial: YES
subdata = [CustomData31, CustomData32...]
- CustomData isSpecial: NO
subdata = [CustomData41, CustomData42...]
- CustomData isSpecial: NO
subdata = [CustomData51, CustomData52...]
- CustomData isSpecial: NO
subdata = [CustomData61, CustomData62...]
- CustomData isSpecial: YES
subdata = [CustomData71, CustomData72...]
- CustomData isSpecial: YES
subdata = [CustomData81, CustomData82...]
- CustomData isSpecial: NO
subdata = [CustomData91, CustomData92...]
答案 3 :(得分:0)
您可以管理viewcontroller和manager类,如下所示:
class ViewControllerOne: UIViewController, UITableViewDelegate {
var isSubVC = false
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
let wireframe = WireFrame()
let nextVC = wireframe.getNextVC(forView: self)
self.navigationController?.pushViewController(nextVC, animated: true)
}
}
class WireFrame {
func getNextVC (forView view: UIViewController) -> UIViewController {
if view.isKind(of: ViewControllerOne) {
return ViewControllerTwo
} else {
// MainVC
if indexPath.row == 2 || indexPath.row == 6 || indexPath.row == 7 {
let subVC = self.storyboard?.instantiateViewController(withIdentifier: "ViewControllerOne") as! ViewControllerOne
subVC.isSubVC = true
return subVC
} else {
return ViewControllerTwo
}
}
}
}