iOS:模态视图控制器如何记住它的属性?

Posted

技术标签:

【中文标题】iOS:模态视图控制器如何记住它的属性?【英文标题】:iOS: How can a modal viewController remember its properties? 【发布时间】:2014-09-04 01:33:59 【问题描述】:

问题:在我的应用程序中,我使用 Storyboard 中的模态 segue 呈现 UIViewController。 该 viewController 有一个 UITableView 并且用户可以选择一个单元格。然后我关闭那个 viewController 并返回。我想要做的是当控制器再次出现时,选定的单元格被突出显示。所以我想将选定单元格的 indexPath 保存在一个属性中,并在 viewWillAppear 中设置该单元格突出显示。但是当 viewController 出现时,它的属性是 nil。所以,我的问题是:

模态视图控制器如何记住它的属性?

【问题讨论】:

第二次呈现它时,它是视图控制器的不同实例。呈现控制器可以保存模态控制器,并且每次都重新呈现相同的实例。或者,另一个对象可以记住选择了哪些项目。该对象可以是您的数据模型,或者更简单地说是呈现控制器中的一个属性。您决定如何存储它取决于这些控制器需要在您的应用中重用的位置和方式。 @Aaron Brager thanx man!照你说的做,效果很好!如果您愿意,请回答 【参考方案1】:

基本问题是您混合了模型和视图控制器的职责。

模型有责任记住应用状态。将数据绑定到视图并验证用户输入是视图控制器的职责。

问题是每个人都作弊。当您在视图控制器中发生临时状态更改时,通常不需要将其分解为模型,因为视图控制器和状态数据具有相同的生命周期。

在您的情况下,状态数据的生命周期比视图控制器更长。将数据分解为模型,然后将该模型应用到视图控制器(单例、从持久存储中读取、在 segue 中应用……:有很多方法可以做到)。


根据你提供的这么少的信息,我可以想到如何做到这一点。

有一个包含数组allItemscurrentItemscountries 的模型。拥有currentCountry 属性。覆盖 -setCurrentCountry: 以重建 currentItems

- (void)setCurrentCountry:(MyCountryModel *)currentCountry

    _currentCountry = currentCountry;
    self.currentItems = [self filterAllItemsByCountry:currentCountry];

项目视图控制器将包含模型的一个实例。当国家视图控制器被推送时,模型可以在 segue 中传递。国家视图控制器将使用countries 作为它的数据源。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    cell = …

    MyCountryModel *country = self.model.countries[indexPath.row];

    cell.selected = country == self.model.currentCountry;

    return cell;


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    MyCountryModel *country = self.model.countries[indexPath.row];

    self.model.currentCountry = country;

【讨论】:

我对应用程序中正在发生的事情不太了解。用户选择一个代表一个国家的单元格,该单元格过滤了前一个 ViewController 的 UITableView。这需要在模型中吗?我真的是 ios 新手,我还不了解 MVC!谢谢! 我在回答中添加了一些内容。 @JefferyThomas 我想尽快回答【参考方案2】:

每次呈现模态视图控制器时,它都是一个新实例。如果您希望一个新实例记住您正在保存的属性(例如 indexPath),您可以将其保存到 NSUserDefaults 以便您可以重新访问所有内容,或者您​​可以只显示相同的模态视图控制器。

您应该做的是每次都显示相同的模态视图控制器,以便它记住属性。

使用 NSUSERDEFAULTS:

你有一个属性,叫它_indexPath

NSString *indexPathString = [NSString stringWithFormat: @"%@", _indexPath];
[[NSUserDefaults standardUserDefaults] setObject: indexPathString forKey: @"Index_Path"];

要检索 indexPath,只需这样做:

(在-(void) viewWillAppear

NSString *indexPathString = [[NSUserDefaults standardUserDefaults] objectForKey: @"Index_Path"];
// convert indexPathString to indexPath and save as _indexPath

【讨论】:

感谢您的回答,但我认为 NSUserDefaults 不是存储此类内容的正确位置。正如我所说,我在这里真的很新,所以也许我错了。再次感谢! 我编辑了我的答案。如果您不想使用 NSUserDefaults,您可以每次都显示相同的模态视图控制器。【参考方案3】:

您不能将索引路径保存为用户默认值吗?

    let index = NSIndexPath(index: 35)
    NSUserDefaults.standardUserDefaults().setValue(index, forKey: "savedIndex")


    //Then in your viewwillappear
    if let savedIndex = NSUserDefaults.standardUserDefaults().valueForKey("savedIndex") as? NSIndexPath 
        //set the highlighted cell
    

只是一个想法......

【讨论】:

仅供参考,这个答案在 Swift 中,而问题是针对 Objective-C。 是的,我的错...很好,您复制了我的答案并将其翻译为 Obj-C 以供海报使用。

以上是关于iOS:模态视图控制器如何记住它的属性?的主要内容,如果未能解决你的问题,请参考以下文章

如何正确使用模态视图控制器?

在 iOS 中隐藏模态视图控制器(但将其保存在内存中)

iOS——如何控制模态视图控制器的大小?

IOS/Objective-C:在呈现视图控制器中设置属性

如何在 iOS 中显示小型模态视图控制器?

iOS 7 半透明模态视图控制器