我是iOS开发的初学者。我的问题是:是否可以将UITabBar放置在顶部,如何实现?
我无法将UITabBar定位在视图的顶部。
可以吗?当然可以,但这违反了人类界面指南。
TabController.h:
#import <UIKit/UIKit.h>
@interface TabController : UITabBarController <UITabBarControllerDelegate>
@end
TabController.m:
#import "TabController.h"
@interface TabController ()
@end
@implementation TabController
- (void)viewDidLoad
{
[super viewDidLoad];
self.delegate = self;
}
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[self.tabBar invalidateIntrinsicContentSize];
CGFloat tabSize = 44.0;
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (UIInterfaceOrientationIsLandscape(orientation))
{
tabSize = 32.0;
}
CGRect tabFrame = self.tabBar.frame;
tabFrame.size.height = tabSize;
tabFrame.origin.y = self.view.frame.origin.y;
self.tabBar.frame = tabFrame;
// Set the translucent property to NO then back to YES to
// force the UITabBar to reblur, otherwise part of the
// new frame will be completely transparent if we rotate
// from a landscape orientation to a portrait orientation.
self.tabBar.translucent = NO;
self.tabBar.translucent = YES;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
@end
Swift3: 我通过创建一个自定义类来实现这个功能,该类针对 UITabBarController
进行了优化:
class CustomTabBarController: UITabBarController {
@IBOutlet weak var financialTabBar: UITabBar!
override func viewDidLoad() {
super.viewDidLoad()
// I've added this line to viewDidLoad
UIApplication.shared.statusBarFrame.size.height
financialTabBar.frame = CGRect(x: 0, y: financialTabBar.frame.size.height, width: financialTabBar.frame.size.width, height: financialTabBar.frame.size.height)
}
TabBarController
Swift 5
将以下代码添加到您的UITabBarViewController中:
override func viewDidLayoutSubviews() {
let height = navigationController?.navigationBar.frame.maxY
tabBar.frame = CGRect(x: 0, y: height ?? 0, width: tabBar.frame.size.width, height: tabBar.frame.size.height)
super.viewDidLayoutSubviews()
}
此功能适用于 iOS 版本大于13和小于13的设备。
下面是一个能够运行的 Swift 3 示例,展示了 aviatorken89 的代码。
Add the following code to the class.
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
var tabFrame:CGRect = self.tabBar.frame
tabFrame.origin.y = self.view.frame.origin.y
self.tabBar.frame = tabFrame
}
If you are using storyboard make sure to change the tab bar class to your custom class via the "Identity inspector".
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
tabBar.frame = CGRect(x: 0, y: 0, width: tabBar.frame.size.width, height: tabBar.frame.size.height)
}
IOS 11问题更新
以上代码在iOS 11上无效。下面是我找到的解决方法。
override func viewDidLayoutSubviews() {
tabBar.frame = CGRect(x: 0, y: 0, width: tabBar.frame.size.width, height: tabBar.frame.size.height)
super.viewDidLayoutSubviews()
}
TabbarController的子视图会隐藏Tabbar的后面部分。 为了解决这个问题,使用以下代码:
class CustomTabBarController: UITabBarController ,UITabBarControllerDelegate{
override func viewDidLayoutSubviews() {
tabBar.frame = CGRect(x: 0, y: 0, width: tabBar.frame.size.width, height: tabBar.frame.size.height)
super.viewDidLayoutSubviews()
delegate = self
selectedViewController?.view.frame.origin = CGPoint(x: 0, y: tabBar.frame.size.height)
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
selectedViewController?.view.frame.origin = CGPoint(x: 0, y: tabBar.frame.size.height)
}
}
升级到xCode 11.5后,在我的控制器中添加了这段代码。适用于iOS 13。
override func viewWillLayoutSubviews() {
renderTabPosition()
super.viewWillLayoutSubviews()
}
private func renderTabPosition() {
tabBar.frame = CGRect(x: 0, y: 0, width: tabBar.frame.size.width, height: tabBar.frame.size.height + 5)
}