#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
}
}
}