【问题标题】:presenting a modal in viewdidappear with swift用 swift 在 vi​​ewdidappear 中呈现模态
【发布时间】:2014-12-10 22:43:18
【问题描述】:

总的来说,我是 swift 和 ios 编程的新手。我试图在我的应用程序首次加载时显示模式视图。我遇到的问题是我的模态一遍又一遍地出现。不知道哪里出错了。

奖励问题:最终我希望这仅在用户第一次打开应用程序时发生。

class ViewController: UIViewController {

    var introModalDidDisplay = false

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        showIntroModal()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func showIntroModal() {
        if (!introModalDidDisplay) {
            println(introModalDidDisplay)
            introModalDidDisplay = true
            let intro = self.storyboard?.instantiateViewControllerWithIdentifier("introModal") as IntroModalViewController
            intro.modalPresentationStyle = UIModalPresentationStyle.FormSheet
            self.presentViewController(intro, animated: true, completion: nil)
        }
    }
}

【问题讨论】:

  • 只需要在 override func viewDidLoad() { super.viewDidLoad() showIntroModal() } 中定义

标签: ios swift


【解决方案1】:

找到了。我的“介绍”课程正在扩展ViewController 而不是UIViewController...显然这很糟糕。谢谢您的帮助!对不起,大雁追逐。

【讨论】:

    【解决方案2】:

    当您关闭模态视图时,您会再次显示 ViewController 视图,再次触发 viewDidAppear 并进入显示模态视图的无限循环,因为第一个视图总是“出现”

    我建议在viewDidLoad 中执行此操作,因为视图应该只加载一次。尝试并试验这些事件,看看它们何时被触发。

    至于只触发一次,我建议在 localStorage (plist) 中设置一个标志,指示它是否是用户第一次打开应用程序。例如,在第一个视图的 viewDidLoad 中设置一个标志,如果该标志为 false,则显示您的模态视图并将该标志设置为 true。

    这里有一个关于在 Swift 中写 plist 的问题:Save Data to .plist File in Swift

    【讨论】:

    • 感谢您的评论!我首先尝试了 viewDidLoad,但它抛出了一个错误,因为(我认为)视图还没有完成绘制,所以我无法将我的模态添加到它。我在寻找解决方案时发现的 cmets 建议将内容移至 viewDidAppear。
    • 使用我建议的在 localStorage 中使用标志的方法可以很好地解决您的问题,因为它只会触发一次。
    【解决方案3】:

    几个观察:

    1. 您是说您在使用该应用程序时一次又一次地看到这种情况?这表明您已实例化此视图控制器的多个实例。例如,您可能正在继续返回此视图控制器(这将创建新实例),而不是展开/弹出/关闭它(将返回到前一个实例)。

      我建议你在viewDidLoad 中有一个断点或日志语句,并确认你只看到过一次。如果您多次看到它,这意味着您在故事板场景中有一些循环引用(顺便说一句,您正在放弃内存,这是一种泄漏)。

    2. 要在应用程序使用之间仅显示一次,您需要将此introModalDidDisplay 保存在某种形式的持久存储中。通常NSUserDefaults 用于此目的。例如,定义introModalDidDisplay 以在标准用户默认值中查找状态:

      var introModalDidDisplay = NSUserDefaults.standardUserDefaults().boolForKey("introModalDidDisplay")
      

      然后你的 showIntroModal 可以在用户默认值中更新这个设置:

      func showIntroModal() {
          if !introModalDidDisplay {
              introModalDidDisplay = true
              NSUserDefaults.standardUserDefaults().setBool(true, forKey: "introModalDidDisplay")
              NSUserDefaults.standardUserDefaults().synchronize()
      
              let intro = self.storyboard?.instantiateViewControllerWithIdentifier("introModal") as IntroModalViewController
              intro.modalPresentationStyle = UIModalPresentationStyle.FormSheet
              self.presentViewController(intro, animated: true, completion: nil)
          }
      }
      

      显然,您可以使用任何您想要的持久存储技术(plist、归档、用户默认值、Core Data、SQLite),但想法是一样的:从持久存储中检索状态,一旦出现介绍屏幕,相应地更新该持久存储。

      顺便说一句,通过在持久存储中查找它,我们还解决了我在第 1 点中讨论的问题的症状。但是您也确实想解决第一点的根本原因,因为否则您将泄漏内存(当然,如果您确实实例化了 ViewController 类的多个副本)。


    顺便说一句,展望未来,我可能建议也存储一个版本号标识符,而不是只存储一个布尔值。这样,当您发布 2.0 版应用时,您将能够决定 v1.0 用户是否会再次看到更新后的介绍屏幕(或者可能是专注于新功能的自定义屏幕)。

    【讨论】:

    • 你是对的,viewDidLoad 被多次触发,但我不知道为什么。我没有任何segues。好像和这条线有关:self.presentViewController(intro, animated: true, completion: nil)
    • 我猜问题出在其他地方。您必须有 segues 或其他出现的 presentViewController 来呈现此视图控制器的新实例。它应该很容易诊断:添加断点或登录viewDidLoad,然后运行应用程序并确定哪些操作序列会导致生成新实例。一旦确定了新实例的生成位置,就应该很容易查看代码并找出原因/方式。
    • 顺便说一句,我假设“介绍”场景将通过调用 dismissViewControllerAnimated 回到主 ViewController,对吧?
    • 对,我在“介绍”中有这个功能,它在按下按钮时被调用。 @IBAction func closePressed(sender: UIButton) { self.dismissViewControllerAnimated(true, completion: nil) }
    • 这一定很愚蠢。我在这件事上真的没有太多其他代码。如果我注释掉 self.presentViewController(intro, animated: true, completion: nil) 行,它只会触发一次。
    猜你喜欢
    • 1970-01-01
    • 2015-02-04
    • 1970-01-01
    • 2018-02-19
    • 1970-01-01
    • 2019-03-10
    • 2015-11-30
    • 2019-03-10
    • 2014-08-11
    相关资源
    最近更新 更多