我是UINavigationBar
的子类。在我的导航栏中,我想添加一个后退按钮。最终我想要一个标题自定义按钮和uicollectionview看起来像这样:
我在UINavigationBar
的AppDelegate:
NFVDContentTableViewController *contentTVC = [[NFVDContentTableViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *contentNavCtr = [[UINavigationController alloc] initWithNavigationBarClass:[NFVDContentNavigationBar class] toolbarClass:[UIToolbar class]];
contentNavCtr.viewControllers = @[contentTVC];
在我的子类UINavigation标头文件中:
@interface NFVDContentNavigationBar : UINavigationBar <UINavigationBarDelegate>
@end
在我的子类UINavigationBar实现文件中:
@implementation NFVDContentNavigationBar
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
- (void)awakeFromNib {
[super awakeFromNib];
UINavigationItem* ni = [[UINavigationItem alloc] init];
UIButton *leftButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 38.0f, 29.0f)];
[leftButton setImage:[UIImage imageNamed:@"reveal-icon"] forState:UIControlStateNormal];
[leftButton addTarget:nil action:@selector(menuItemPressed:) forControlEvents:UIControlEventTouchUpInside];
[leftButton setContentMode:UIViewContentModeScaleAspectFit];
[leftButton setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin];
UIBarButtonItem *b =[[UIBarButtonItem alloc] initWithCustomView:leftButton];
ni.leftBarButtonItem = b;
self.items = @[ni];
}
- (CGSize)sizeThatFits:(CGSize)size{
CGSize newSize = [super sizeThatFits:size];
DLog(@"NewSize: %@", NSStringFromCGSize(newSize));
CGRect mainScreen = [UIScreen mainScreen].bounds;
if([UIView viewOrientationForSize:mainScreen.size] == ViewOrientationPortrait){
return CGSizeMake(newSize.width, 100);
}else if([UIView viewOrientationForSize:mainScreen.size] == ViewOrientationLandscape){
return CGSizeMake(newSize.width, 44);
}
return CGSizeZero;
}
- (void)layoutSubviews {
[super layoutSubviews];
}
@end
答案 0 :(得分:2)
这很难做到,因为UIViewController带有自己的UINavigationItems,请参阅UIViewController头文件中的文档:
NS_CLASS_AVAILABLE_IOS(2_0) @interface UIViewController : UIResponder <NSCoding, UIAppearanceContainer, UITraitEnvironment, UIContentContainer> {
@package
UIView *_view;
UITabBarItem *_tabBarItem;
UINavigationItem *_navigationItem;
您必须覆盖UIViewController的这个功能,这是可能的,但要求您继承UIViewController,然后强制app中的所有视图控制器成为子类视图控制器的子类,这样就很难了方式,我会显示它的代码,但它有点强烈和很多代码,但这就是我这样做的方式。无论如何,更好的选择是在你的UIViewController的ViewDidLoad中执行此操作:
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem * tester = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"reveal-icon"] style:UIBarButtonItemStylePlain target:self action:@selector(menuItemPressed:)];
[[self navigationItem] setRightBarButtonItem:tester];
}
你仍然可以继承UINavigationBar的子类,但是不要将它作为子类来尝试覆盖已经挂钩到UIKit默认的UIViewController的barbuttonitems,如果你想对此有所了解,那么这里& #39;是你如何继承UIViewController的开始,它有很多代码:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self == nil)
return nil;
if (self) {
_showsNotifications = false;
_showsAddFriends = false;
}
_notificationsBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage resizeImage:[UIImage imageNamed:@"YOUR IMAGE NAME"] height:27] style:UIBarButtonItemStylePlain target:nil action:nil];
_addFriendsBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"YOUR IMAGE NAME"] style:UIBarButtonItemStylePlain target:self action:@selector(addFriendsPressed)];
}
您会看到,您添加到自定义视图控制器Bool属性,这些属性会更改UIViewController中UINavigationItem的内部结构。使用此方法然后需要您在作为此自定义viewcontroller的子类的viewcontrollers的INIT中调用和设置这些bool值,如下所示:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
[self setShowsAddFriends:false];
[self setShowsNotifications:false];
}
return self;
}
然后在子类UIViewController中,使bool开关能够实际切换。
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (_showsNotifications) {
[[self navigationItem] setRightBarButtonItem:_notificationsBarButtonItem];
}
if (_showsAddFriends) {
[[self navigationItem] setRightBarButtonItem:_addFriendsBarButtonItem];
}
}
完成并完成,复杂吗?排序,但这是你如何使用尽可能多的自定义导航项目按钮模板项目,完整的代码大约是1k行代码,但这是它的内核,子类UIViewController,在头文件中设置bool属性,设置这些您的子类中的bool属性,以便使用此子类作为其父类的UIViewControllers可以在&#34; init&#34;中调用这些bool setter属性,然后您将能够切换并选择您喜欢的任何导航项。此外,为了确保视图控制器维护您设置的项目,请确保在视图控制器中的viewWillAppear中声明这些项目设置,这些视图控制器使用UIViewController的自定义子类作为父视图。祝你好运,祝你有个美好的一天。
事实上,我只会告诉你代码,为什么?因为我很无聊,下周有两个应用程序发布太多了。所以,这里是您需要查看的文件,请记住这些文件非常简化:
CCUSTViewController.m
//******CCUSTViewController.m****
//this is the implementation file for the subclass of UIViewController
#import "CCUSTViewController.h"
#import "CCUSTFriendsViewController.h"
#import "CCUSTActivitiesViewController.h"
@interface CCUSTViewController ()
@end
@implementation CCUSTViewController
{
UIBarButtonItem * _notificationsBarButtonItem;
UIBarButtonItem * _addFriendsBarButtonItem;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self == nil)
return nil;
if (self) {
_showsNotifications = false;
_showsAddFriends = false;
}
_notificationsBarButtonItem = [[UIBarButtonItem alloc] initWithImage::[UIImage imageNamed:@"your imate"] style:UIBarButtonItemStylePlain target:self action:@selector(showNotificationsPressed)];
_addFriendsBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"your imate"] style:UIBarButtonItemStylePlain target:self action:@selector(addFriendsPressed)];
return self;
}
- (void)showNotificationsPressed
{
CCUSTActivitiesViewController * tobePushed = [CCUSTActivitiesViewController new];
[self navigationController] pushViewController:tobePushed animated:true];
}
- (void)addFriendsPressed
{
CCUSTFriendsViewController * tobePushed = [CCUSTFriendsViewController new];
[self navigationController] pushViewController:tobePushed animated:true];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (_showsNotifications) {
[[self navigationItem] setRightBarButtonItem:_notificationsBarButtonItem];
}
if (_showsAddFriends) {
[[self navigationItem] setRightBarButtonItem:_addFriendsBarButtonItem];
}
}
@end
CCUSTViewController.h
#import <UIKit/UIKit.h>
@interface CCUSTViewController : UIViewController
@property (nonatomic) BOOL showsNotifications;
@property (nonatomic) BOOL showsAddFriends;
@end
然后,这是使用新导航栏项目切换器的子类View控制器的示例:
CCCUSTHomeViewController.h
#import "CCUSTViewController.h"
@interface CCCUSTHomeViewController : CCUSTViewController
@end
CCCUSTHomeViewController.m
// CCCUSTHomeViewController.m
#import "CCCUSTHomeViewController.h"
#import "CCCUSTHomeView.h"
@interface CCCUSTHomeViewController ()
@end
@implementation CCCUSTHomeViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
[self setShowsAddFriends:TRUE];
[self setShowsNotifications:TRUE];
}
return self;
}
-(void)loadView
{
[self setView:[CCCUSTHomeView new]];
}
-(CCCUSTHomeView*)contentView
{
return (id)[self view];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self setTitle:@"HOME"];
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self setShowsAddFriends:TRUE];
[self setShowsNotifications:TRUE];
}
@end
哦,是的,您需要将相同的代码从init添加到ViewWillAppear,因为当您在堆栈上弹出推送的视图控制器时,您甚至需要在CCCUSTHomeViewController中拦截它,以便UINavigationItems重新出现,因为它们是应该给出位于堆栈顶部的viewcontroller。您也可以使用相同的方法将UICollectionViewController和UITableViewController中的所有内容子类化,这意味着使用此结构作为模板,您可以在Xcode中添加一个空项目,并添加所有这些子类,然后您可以更好地控制所有视图控制器。你可以用更多的方法来实现这种方法,但有些事情,我必须保守秘密,但足以说明,许多大型应用程序使用相同的技术和你赢得的其他先进技术#39; t在野外看到。巧妙的是,你不必委托,而且你不会操纵任何东西。祝你好运,祝你有个美好的一天。
GISTS因为我关心:
https://gist.github.com/anonymous/993e457561001cf8e77b
https://gist.github.com/anonymous/bc6095575038c36de77b