【问题标题】:iOS App - Updating array of strings for each new dayiOS App - 为每个新的一天更新字符串数组
【发布时间】:2020-01-07 19:19:05
【问题描述】:

我一直在用 swift 开发一个附带项目,该项目基本上是当日流行词应用程序。我已经将 30 个单词和内容存储到一个数组中,并且每天都在尝试更新单词。我尝试了一些修复但无济于事。即使我更改手机上的日期,我也只能显示第一个数组。

wordNumber 和 wordOfDay 是否冲突?我怎样才能适应这种情况,以便每天都会弹出一个新词?

let wordList =
[
    Words(word: "aaa", pronounciation: "bbbb", type: "noun", definition:"blah"),
    Words(word: "bbb", pronounciation: "cccc", type: "adjective", definition:"blah")
]

var wordNumber = 0;


class ViewController: UIViewController {

    @IBOutlet weak var wordLabel: UILabel!
    @IBOutlet weak var pronounciationLabel: UILabel!
    @IBOutlet weak var wordTypeLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        updateWord()
    }

    @IBAction func prepareForUnwind (segue: UIStoryboardSegue){}

    func updateWord()
    {
        let date = Date()
        let dateIndex = Int(date.timeIntervalSince1970) / (60*60*24)
        let wordOfDay = wordList[dateIndex % wordList.count]


        wordLabel.text = wordList[wordNumber].word
        pronounciationLabel.text = wordList[wordNumber].pronounciation

    }

}

【问题讨论】:

  • 您希望每天出现随机单词。对吗?
  • 你用正确的数字填充 wordOfDay,然后使用保持为 0 的 wordNumber ...
  • “即使我更改手机上的日期,我也只能显示第一个数组” - 第一个数组是什么意思?
  • 抱歉,我知道这很令人困惑。我只得到数组中的 0 位置。

标签: ios arrays swift iphone


【解决方案1】:

一种简单的方法是从Calendar 获取当天的索引。

由于月份的日期从 1 开始,并且数组索引从零开始,因此您必须减小该值。假设几个月有 31 天。

func updateWord()
{
    let day = Calendar.current.component(.day, from: Date())
    let wordOfDay = wordList[day - 1]

    wordLabel.text = wordList[wordNumber].word
    pronounciationLabel.text = wordList[wordNumber].pronounciation
}

但是,如果您想要每天一次随机单词,则必须将当前日期编号和当前随机索引保存在 UserDefaults 中。将其加载到viewDidLoad 并将日期与当前值进行比较。如果两个值相等,则通过保存的索引获取单词。如果它们不相等,则获取 1 到 31 之间的随机数并保存当前日期编号和索引。

【讨论】:

  • 所以如果我想今天成为数组中的第一个位置,我会 [day - 8]?
【解决方案2】:

我会说在您的数组中存储 31 个值,因为最多可以有 31 天。然后根据当天,显示您当天的话。

func updateWord() {
  let currentDay = Calendar.current.component(.day, from: Date()) // this would return the current day in Int, like today is 8th Jan, so it would return 8
  let wordOfDay = wordList[currentDay-1] // -1 because array index starts from 0 
  wordLabel.text = wordOfDay.word
  pronounciationLabel.text = wordOfDay.pronounciation
}

【讨论】:

  • 谢谢!如果我想要超过 30 天怎么办?
  • 另外 wordOfDay.word 基本上会替换 [wordNumber] 对吗?
  • @jjdthompson 完全正确。上述案件有效期为31天。超过 30 天是什么意思?
【解决方案3】:

我会尝试几件事:

除非您手动计算 dateIndex 有特定原因,否则请使用:

let calendar = Calendar.current
calendar.component(.day, from: Date()) 

calendar.component(.day, from: Date()) 返回 Int 的位置

另外,我看到wordList 只有两个值。您提交的日期索引可能超出了wordList 的范围。要对此进行测试,请尝试如下手动输入。如果数组索引是问题,这应该可以工作。

wordLabel.text = wordList[0].word

最后为了可读性,这样做可能是有意义的:

let firstWord = Words(word: "aaa", pronounciation: "bbbb", type: "noun", definition:"blah")
let secondWord = Words()
let wordList =
[
    firstWord, secondWord, etc.
]

【讨论】:

  • 谢谢!我有 30 个值,有可能增加额外的 30 天或额外的“月”。有没有更有效或更正式的方法来添加所有这些单词,而不是仅仅将它们全部写入代码?甚至可以说一年的内容
  • 1.如果您正在考虑月份,您会考虑“切换大小写”来组织哪个月/日组合应该填充哪个单词。 2. 如果您必须将其硬编码为 swift,您可以使用 for 循环来加快处理速度。但是,这听起来像是您可能希望存储在表中并在通过该表查询后填充的内容,而不是将值作为硬代码放入。话虽如此,我建议您提出一个单独的问题,以便有人可以更详细地回答。希望这会有所帮助!
  • 谢谢!很有帮助!
  • 好的,太好了!请记住将此问题标记为已回答。
  • @jjdthompson 您可以将单词作为 JSON 文件存储在您的应用程序包中,使您的 Word 结构符合 Codable,然后使用 JSONDecoder 以相对简单的方式读取您的数据库单词/信息到一个数组中。
【解决方案4】:

当应用程序运行时,您的代码中没有任何内容会真正告诉视图控制器刷新自身,或者再次检查日期并选择另一个词。

解决此问题的一种方法可能是在 viewDidLoad() 中启动一个计时器,或者以较短的间隔重复,或者从午夜开始每 24 小时重复一次。

另一种方法可能是检查日期并仅在用户打开/激活/切换回应用程序时显示新单词。这可以通过添加观察者来完成,如下所示:

NotificationCenter.default.addObserver(self, selector: #selector(didEnterBackground), name: UIApplication.didBecomeActiveNotification, object: nil)

如果您的应用有UIWindowSceneDelegate,则如下所示:

if #available(iOS 13.0, *) {
    NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name: UIScene.didActivateNotification, object: nil)
} else {
    NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
}

在您的 didBecomeActive 函数(或等效函数)中,您可以检查日期并获取另一个随机单词。

【讨论】:

  • 啊好吧有趣。因此,如果应用程序没有关闭,并且即使明天仍然在后台“运行”,它也不会更新,除非我实施了您建议的方法之一。
  • 是的,可能还有其他方法可以做到这一点 - 要点是您现有的 updateWord 函数只执行一次,除非应用程序在后台运行了很长时间,或者用户将您的应用程序从他们的应用程序切换器。还编辑了我的答案,因为我混淆了一个荒谬的方法名称 didEnterBackground 而不是 didBecomeActive ?
猜你喜欢
  • 2017-03-31
  • 1970-01-01
  • 2015-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-30
  • 1970-01-01
  • 2016-07-31
相关资源
最近更新 更多