我正在使用包含2个标签的应用(以及2 ViewControllers
):
HomescreenVC
)UITableView
组成的日历,通过@IBOutlet
与此标签ViewController
(我们称之为CalendarVC
)@IBOutlet weak var calendarTableView: UITableView!
相关联。此日历可用于查看输入数据的历史记录。当用户在第一个标签(HomescreenVC
)上保存输入时,我希望日历更新其数据。为此,我使用委托方法告诉CalendarVC
重新加载它的日历:
在HomescreenVC
:
calendarDelegate = tabBarController?.viewControllers?[1] as? CalendarViewController
calendarDelegate?.updateCalendar()
在CalendarVC
:
func updateCalendar() {
calendarTableView.reloadData()
}
问题在于,除非用户之前使用日历打开了标签(因此调用其viewDidLoad()
方法),否则其tableView出口将返回nil
,导致应用程序在调用委托方法时崩溃。当然,一个简单的解决方案是在启动时出现日历第一个标签,但这将面临用户体验的逻辑。
我还尝试使用故事板ID实例化CalendarVC:
calendarDelegate = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "CalendarVC") as! CalendarViewController
但它对实例化出口没有影响。
所以我的问题是如何在ViewController
被调用之前从另一个viewDidLoad()
加载tableView?
答案 0 :(得分:0)
试试这个
calendarDelegate = tabBarController?.viewControllers?[1] as? CalendarViewController
if(calendarDelegate != nil)
{
calendarDelegate?.updateCalendar()
}
此外,如果尚未调用此updateCalendar,请不要担心在首次启动时更新该数据,如果您正确分享数据,则显示的数据将是最新的
答案 1 :(得分:0)
我没有使用尚未加载的委托,而是向模型结构中引入了一个静态切换变量:
static var calendarNeedsUpdate = false
当用户提交新数据时,此变量切换为true
。然后,当打开日历标签时,我使用viewWillAppear()
的{{1}}方法:
CalendarVC
答案 2 :(得分:0)
我会通过略微更改设计来提出略有不同的方法。
如果可以用其他方式更改TabBar控制器,则可以在嵌入第二个视图控制器的第一个选项卡(视图控制器)上创建UIContainerView,并将其隐藏在第一个选项卡viewWillAppear()上。
当需要显示第二个选项卡时,您只需更改第二个选项卡的isHidden = false或做任何您想要的漂亮动画即可。
回到您的目标,当您需要访问第二个标签视图控制器时,它已被实例化,并且所有IBOutlet都已链接。
此方法的瓶颈是您需要自己创建标签栏图标栏。