【问题标题】:Swift -Tabbar item frame is returning questionable value when converting frame to window将框架转换为窗口时,Swift -Tabbar 项目框架返回有问题的值
【发布时间】:2021-03-29 14:01:04
【问题描述】:

我有一个包含 5 个项目的 tabBar。要获取第一个 tabBar 项目的框架并根据该框架设置一些东西,我使用了这个完美的方法:

guard let firstTab = tabBarController?.tabBar.items?[0].value(forKey: "view") as? UIView else { return }
        
guard let window = UIApplication.shared.windows.filter({$0.isKeyWindow}).first else { return }

let windowRect = lastTab.convert(firstTab.frame, to: window)

print(firstTab) // (2.0, 1.0, 79.00000000298023, 48.0)
print(windowRect) // (4.0, 689.0, 79.00000000298023, 48.0)

但是当我尝试上面的代码来获取第 5 个选项卡的框架时,值不正确。设置tabBar.items?[4]时,框架的x坐标在windowRect中的665处远离屏幕:

guard let lastTab = tabBarControlle?.tabBar.items?[4].value(forKey: "view") as? UIView else { return }

guard let window = UIApplication.shared.windows.filter({$0.isKeyWindow}).first else { return }

let windowRect = lastTab.convert(lastTab.frame, to: window)

print(lastTab) // (332.99999999701976, 1.0, 79.00000000298023, 48.0)
print(windowRect) // (665.9999999940395, 689.0, 79.0000000029803, 48.0)

但设置 tabBar.items?[2] 我在 windowRect 中的 336 处得到正确的 x 坐标:

// setting the 2nd item gives me the correct frame for the 4th item
guard let lastTab = tabBarControlle?.tabBar.items?[2].value(forKey: "view") as? UIView else { return }

guard let window = UIApplication.shared.windows.filter({$0.isKeyWindow}).first else { return }

let windowRect = lastTab.convert(lastTab.frame, to: window)

print(lastTab) // (168.00000000596046, 1.0, 77.99999998807907, 48.0)
print(windowRect) // (336.0000000119209, 689.0, 77.99999998807908, 48.0)

为什么tabBar.items?[2] 在窗口的框架中返回tabBar.items?[4] 的值?

【问题讨论】:

  • 与您的问题无关,但为什么不简单地windows.first(where: \.isKeyWindow)
  • 当警告开始出现在 XCode 12/13 中时,我开始使用.filter({..}),因为这是我发现的第一个有效的答案,但我从未切换过。我在另一个答案上看到了\.,但那时我所有的代码都在使用.filter
  • filter 将不必要地迭代整个集合。在这种情况下,它没有任何区别,因为只有几个窗口。确保始终使用first(where:),它会在满足条件时提供提前退出。
  • ohhhhhhh,我从来不知道,每天学习新东西。谢谢你的建议。现在我要把它们全部换掉????如果我要添加一个子句,我不妨使用更短的语法
  • 哦,我明白了,每次出现计数都会增加,一旦达到你打破的最大值。我以为你有另一种方法。我以前用过。不过,我从未将它与 where 子句一起使用。

标签: ios swift uitabbarcontroller uitabbaritem cgrect


【解决方案1】:

你错过了.superview

private func convertTabFrame(for index: Int) -> CGRect? {
    guard let window = UIApplication.shared.windows.first(where: {$0.isKeyWindow}) else { return nil }
    guard let tabView = self.tabBarController?.tabBar.items?[index].value(forKey: "view") as? UIView else { return nil }
    return tabView.superview?.convert(tabView.frame, to: window)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-04
    • 2012-03-06
    • 2016-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-25
    • 1970-01-01
    相关资源
    最近更新 更多