Кэширование и восстановление порядка элементов TabBarItem

#swift

#swift

Вопрос:

Есть ли простой способ сделать это для UITabBarController после того, как пользователь изменил исходный порядок? Я получил следующий код для работы, но он кажется немного неуклюжим.

 class TabBarViewController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.restoreItemOrder()
    }

    override func tabBar(_ tabBar: UITabBar, didEndCustomizing items: [UITabBarItem], changed: Bool) {

        if changed {
            self.cacheItemOrder(items: items)
        }
    }
}
  

Расширения для кэширования / восстановления порядка после редактирования.

 extension UITabBarController {

    private static let cacheKey = "tabBarIndex"

    public func cacheItemOrder(items: [UITabBarItem]) {
        var index = [String: Int]()
        var i = 0

        for item in items {
            if let title = item.title {
                index[title] = i
            }

            i  = 1
        }

        UserDefaults.standard.set(index, forKey: UITabBarController.cacheKey)
    }

    public func restoreItemOrder() {
        if let dict = UserDefaults.standard.dictionary(forKey: UITabBarController.cacheKey) as? [String: Int] {

            if let vcs = self.viewControllers {

                self.viewControllers = vcs.sorted() {
                    var idx0 = 99
                    var idx1 = 99

                    if let t0 = $0.tabBarItem.title, let idx = dict[t0] {
                        idx0 = idx
                    }
                    if let t1 = $1.tabBarItem.title, let idx = dict[t1] {
                        idx1 = idx
                    }

                    return idx0 < idx1
                }  
            }
        }
    }
}
  

Заранее спасибо.

Ответ №1:

Вы можете выразить все более кратко с помощью функциональных идиом:

 extension UITabBarController {

    private static let cacheKey = "tabBarIndex"

    public func cacheItemOrder(items: [UITabBarItem]) {
        UserDefaults.standard.set(
            [String: Int](uniqueKeysWithValues: items.enumerated().map { ($1.title ?? "", $0)}),
            forKey: UITabBarController.cacheKey
        )
    }

    public func restoreItemOrder() {
        guard let order = UserDefaults.standard.dictionary(forKey: UITabBarController.cacheKey) as? [String: Int] else {
            return
        }
        viewControllers?.sort { left, right in
            guard let leftIndex = left.title.flatMap({order[$0]}),
                  let rightIndex = right.title.flatMap({order[$0]}) else {
                return false
            }
            return leftIndex < rightIndex
        }
    }
}