Swift 4 - 标签栏项目上的按钮
Swift 4 - Button over Tab Bar Item
我正在尝试将自定义按钮放置在我的标签栏的一项上。
func setupMiddleButton() {
let numberOfItems = CGFloat(tabBar.items!.count)
let tabBarItemSize = CGSize(width: tabBar.frame.width / numberOfItems, height: tabBar.frame.height)
let menuButton = UIButton(frame: CGRect(x: 0, y: 0, width: tabBarItemSize.width, height: self.tabBar.frame.size.height))
var menuButtonFrame = menuButton.frame
menuButtonFrame.origin.y = self.view.bounds.height - menuButtonFrame.height
menuButtonFrame.origin.x = self.view.bounds.width/2 - menuButtonFrame.size.width/2
menuButton.frame = menuButtonFrame
menuButton.backgroundColor = UIColor.white
self.view.addSubview(menuButton)
self.view.layoutIfNeeded()
我的问题是,在之前的代码中,按钮没有完全位于栏项上方(见图):
有什么建议吗?我真的不知道还能怎么尝试。
谢谢!
我注意到这张截图是 iPhone X 模拟器的截图,它在屏幕底部有不同的布局。
您的代码适用于任何其他 iPhone。在 iOS 11 中,他们介绍了所谓的 "Safe area"。当您计算按钮的大小和原点时,您必须考虑到这一点。
当您计算 buttonFrame 的 origin.y
时,您必须减去底部安全区域的高度,如下所示:
menuButtonFrame.origin.y = self.view.bounds.height - menuButtonFrame.height - self.view.safeAreaInsets.bottom
但这不会解决您的问题,因为您的代码可能在 viewDidLoad
中运行,这发生在视图知道它应该显示在具有安全区域的 iPhone X 上之前。
您可以为此覆盖 viewDidLayoutSubviews
,并在每次调用时为您的按钮设置正确的框架。
这将解决您的问题:
class CustomTabBarViewController: UITabBarController {
let menuButton = UIButton(frame: CGRect.zero)
override func viewDidLoad() {
super.viewDidLoad()
setupMiddleButton()
}
func setupMiddleButton() {
let numberOfItems = CGFloat(tabBar.items!.count)
let tabBarItemSize = CGSize(width: tabBar.frame.width / numberOfItems, height: tabBar.frame.height)
menuButton.frame = CGRect(x: 0, y: 0, width: tabBarItemSize.width, height: tabBar.frame.size.height)
var menuButtonFrame = menuButton.frame
menuButtonFrame.origin.y = self.view.bounds.height - menuButtonFrame.height - self.view.safeAreaInsets.bottom
menuButtonFrame.origin.x = self.view.bounds.width/2 - menuButtonFrame.size.width/2
menuButton.frame = menuButtonFrame
menuButton.backgroundColor = UIColor.green
self.view.addSubview(menuButton)
self.view.layoutIfNeeded()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
menuButton.frame.origin.y = self.view.bounds.height - menuButton.frame.height - self.view.safeAreaInsets.bottom
}
}
我知道从 viewDidLayoutSubviews
内部简单地调用 setupMiddleButton
很诱人,但不要那样做。 viewDidLayoutSubviews
不应用于创建按钮等,它只应用于将它们相应地移动到视图的其余部分。您可能希望将 menuButton
的整个框架设置在 viewDidLayoutSubviews
内,而不是像我那样只设置 origin.y
,尤其是当您需要支持 rotation/landscape-mode 时。在这个非常简单的示例中,更新 origin.y
就足够了。
我正在尝试将自定义按钮放置在我的标签栏的一项上。
func setupMiddleButton() {
let numberOfItems = CGFloat(tabBar.items!.count)
let tabBarItemSize = CGSize(width: tabBar.frame.width / numberOfItems, height: tabBar.frame.height)
let menuButton = UIButton(frame: CGRect(x: 0, y: 0, width: tabBarItemSize.width, height: self.tabBar.frame.size.height))
var menuButtonFrame = menuButton.frame
menuButtonFrame.origin.y = self.view.bounds.height - menuButtonFrame.height
menuButtonFrame.origin.x = self.view.bounds.width/2 - menuButtonFrame.size.width/2
menuButton.frame = menuButtonFrame
menuButton.backgroundColor = UIColor.white
self.view.addSubview(menuButton)
self.view.layoutIfNeeded()
我的问题是,在之前的代码中,按钮没有完全位于栏项上方(见图):
有什么建议吗?我真的不知道还能怎么尝试。
谢谢!
我注意到这张截图是 iPhone X 模拟器的截图,它在屏幕底部有不同的布局。 您的代码适用于任何其他 iPhone。在 iOS 11 中,他们介绍了所谓的 "Safe area"。当您计算按钮的大小和原点时,您必须考虑到这一点。
当您计算 buttonFrame 的 origin.y
时,您必须减去底部安全区域的高度,如下所示:
menuButtonFrame.origin.y = self.view.bounds.height - menuButtonFrame.height - self.view.safeAreaInsets.bottom
但这不会解决您的问题,因为您的代码可能在 viewDidLoad
中运行,这发生在视图知道它应该显示在具有安全区域的 iPhone X 上之前。
您可以为此覆盖 viewDidLayoutSubviews
,并在每次调用时为您的按钮设置正确的框架。
这将解决您的问题:
class CustomTabBarViewController: UITabBarController {
let menuButton = UIButton(frame: CGRect.zero)
override func viewDidLoad() {
super.viewDidLoad()
setupMiddleButton()
}
func setupMiddleButton() {
let numberOfItems = CGFloat(tabBar.items!.count)
let tabBarItemSize = CGSize(width: tabBar.frame.width / numberOfItems, height: tabBar.frame.height)
menuButton.frame = CGRect(x: 0, y: 0, width: tabBarItemSize.width, height: tabBar.frame.size.height)
var menuButtonFrame = menuButton.frame
menuButtonFrame.origin.y = self.view.bounds.height - menuButtonFrame.height - self.view.safeAreaInsets.bottom
menuButtonFrame.origin.x = self.view.bounds.width/2 - menuButtonFrame.size.width/2
menuButton.frame = menuButtonFrame
menuButton.backgroundColor = UIColor.green
self.view.addSubview(menuButton)
self.view.layoutIfNeeded()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
menuButton.frame.origin.y = self.view.bounds.height - menuButton.frame.height - self.view.safeAreaInsets.bottom
}
}
我知道从 viewDidLayoutSubviews
内部简单地调用 setupMiddleButton
很诱人,但不要那样做。 viewDidLayoutSubviews
不应用于创建按钮等,它只应用于将它们相应地移动到视图的其余部分。您可能希望将 menuButton
的整个框架设置在 viewDidLayoutSubviews
内,而不是像我那样只设置 origin.y
,尤其是当您需要支持 rotation/landscape-mode 时。在这个非常简单的示例中,更新 origin.y
就足够了。