将 UITabBar 定位在顶部
Positioning UITabBar at the top
我是 iOS 开发的初学者。我的问题是:是否可以将 UITabBar 放在顶部以及如何放置?
我无法将我的 UITabBar 放在视图的顶部。
您可以自己制作自定义标签栏,但 Apple 强烈反对模仿系统控件来实现其原本不打算执行的功能。
再次,我不鼓励你这样做,因为它违反了你的应用程序和系统应用程序的一致性。但既然我在做,我们就开始吧:
对于自定义标签栏,您需要创建一个包含多个按钮的视图。您还需要一个容器视图 below UITabBar
(因为您希望 UITabBar
位于顶部)。按下按钮时,您会更改容器内的 UIViewController
。
很简单,当然,强烈不推荐。
可能吗?当然可以,但它违反了人机界面指南。
截图:
代码:
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
如果您想要像 UITabBar 这样的东西放在顶部,那么您如何创建一个自定义 UIView 并在其中添加任意数量的 UIButton。然后 link 一些 ViewControllers 与每个按钮通过 Segue。完毕!
您不需要自定义 UITabBar。正如aviatorken89之前所说,这违反了人机界面指南。
这是 aviatorken89 代码的工作 swift3 示例。
- 首先创建一个新文件。
- Select来源cocoa触摸class.
- 指定子class of: UITabBarController
- 命名 class "CustomTabBarController" 或任何你喜欢的名字。
将以下代码添加到class。
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
var tabFrame:CGRect = self.tabBar.frame
tabFrame.origin.y = self.view.frame.origin.y
self.tabBar.frame = tabFrame
}
如果您使用故事板,请确保通过 "Identity inspector".
[= 将标签栏 class 更改为您的自定义 class 24=]
Swift3: 我通过为 UITabBarController
创建自定义 class 来实现此目的:
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)
}
别忘了将自定义 Class 设置为 TabBarController
结果是这样的:
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)
}
}
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 和 iOS < 13
更新到 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)
}
我是 iOS 开发的初学者。我的问题是:是否可以将 UITabBar 放在顶部以及如何放置? 我无法将我的 UITabBar 放在视图的顶部。
您可以自己制作自定义标签栏,但 Apple 强烈反对模仿系统控件来实现其原本不打算执行的功能。
再次,我不鼓励你这样做,因为它违反了你的应用程序和系统应用程序的一致性。但既然我在做,我们就开始吧:
对于自定义标签栏,您需要创建一个包含多个按钮的视图。您还需要一个容器视图 below UITabBar
(因为您希望 UITabBar
位于顶部)。按下按钮时,您会更改容器内的 UIViewController
。
很简单,当然,强烈不推荐。
可能吗?当然可以,但它违反了人机界面指南。
截图:
代码:
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
如果您想要像 UITabBar 这样的东西放在顶部,那么您如何创建一个自定义 UIView 并在其中添加任意数量的 UIButton。然后 link 一些 ViewControllers 与每个按钮通过 Segue。完毕!
您不需要自定义 UITabBar。正如aviatorken89之前所说,这违反了人机界面指南。
这是 aviatorken89 代码的工作 swift3 示例。
- 首先创建一个新文件。
- Select来源cocoa触摸class.
- 指定子class of: UITabBarController
- 命名 class "CustomTabBarController" 或任何你喜欢的名字。
将以下代码添加到class。
override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() var tabFrame:CGRect = self.tabBar.frame tabFrame.origin.y = self.view.frame.origin.y self.tabBar.frame = tabFrame }
如果您使用故事板,请确保通过 "Identity inspector".
[= 将标签栏 class 更改为您的自定义 class 24=]
Swift3: 我通过为 UITabBarController
创建自定义 class 来实现此目的:
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)
}
别忘了将自定义 Class 设置为 TabBarController
结果是这样的:
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)
}
}
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 和 iOS < 13
更新到 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)
}