菜鸟教程小白 发表于 2022-12-12 15:56:27

ios - 将按钮添加到 UINavigationBar 的子类


                                            <p><p>我正在继承 <code>UINavigationBar</code>。在我的导航栏中,我想添加一个后退按钮。最终我想要一个自定义按钮的标题和 uicollectionview 看起来像这样:</p>

<p> <a href="/image/OC3mm.png" rel="noreferrer noopener nofollow"><img src="/image/OC3mm.png" alt="enter image description here"/></a> </p>

<p>我在 <code>UINavigationBar</code></p> 的子类中添加按钮时遇到问题

<p>AppDelegate:</p>

<pre><code> NFVDContentTableViewController *contentTVC = [ initWithNibName:nil bundle:nil];
UINavigationController *contentNavCtr = [ initWithNavigationBarClass: toolbarClass:];
contentNavCtr.viewControllers = @;
</code></pre>

<p>在我的子类 UINavigation 头文件中:</p>

<pre><code>@interface NFVDContentNavigationBar : UINavigationBar &lt;UINavigationBarDelegate&gt;

@end
</code></pre>

<p>在我的子类 UINavigationBar 实现文件中:</p>

<pre><code>@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 = ;
    if (self) {

    }
    return self;
}

- (void)awakeFromNib {

    ;

    UINavigationItem* ni = [ init];
    UIButton *leftButton = [ initWithFrame:CGRectMake(0, 0, 38.0f, 29.0f)];
    forState:UIControlStateNormal];
    ;
    ;
    ;
    UIBarButtonItem *b =[ initWithCustomView:leftButton];

    ni.leftBarButtonItem = b;
    self.items = @;

}

- (CGSize)sizeThatFits:(CGSize)size{

    CGSize newSize = ;

    DLog(@&#34;NewSize: %@&#34;, NSStringFromCGSize(newSize));

    CGRect mainScreen = .bounds;

    if( == ViewOrientationPortrait){

      return CGSizeMake(newSize.width, 100);

    }else if( == ViewOrientationLandscape){

      return CGSizeMake(newSize.width, 44);

    }

    return CGSizeZero;

}

- (void)layoutSubviews {
    ;
}

@end
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>这很难做到,因为 UIViewController 带有自己的 UINavigationItems,请参阅 UIViewController 头文件中的文档:</p>

<pre><code>NS_CLASS_AVAILABLE_IOS(2_0) @interface UIViewController : UIResponder &lt;NSCoding, UIAppearanceContainer, UITraitEnvironment, UIContentContainer&gt; {
    @package
    UIView         *_view;
    UITabBarItem   *_tabBarItem;
    UINavigationItem *_navigationItem;
</code></pre>

<p>您必须重写 UIViewController 的此功能,但这是可能的,但需要您将 UIViewController 子类化,然后强制应用程序中的所有 ViewController 成为子类 ViewController 的子类,所以这是一个艰难的方法,我会展示它的代码,但它有点紧张和很多代码,但这就是我的做法。无论如何,更好的选择是在 UIViewController 的 ViewDidLoad 中执行此操作:</p>

<pre><code>- (void)viewDidLoad
{
    ;
    UIBarButtonItem * tester = [ initWithImage: style:UIBarButtonItemStylePlain target:self action:@selector(menuItemPressed:)];
    [ setRightBarButtonItem:tester];
}
</code></pre>

<p>您仍然可以将 UINavigationBar 子类化,但不要将其用作子类来尝试覆盖已经挂接到 UIViewController 的 barbuttonitems,该 UIViewController 是 UIKit 的默认设置,如果您想对此有所了解,那么这里是开始关于如何子类化 UIViewController,代码很多:</p>

<pre><code>- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = ;

    if (self == nil)
      return nil;

    if (self) {
      _showsNotifications = false;
      _showsAddFriends = false;
    }
    _notificationsBarButtonItem = [ initWithImage: height:27] style:UIBarButtonItemStylePlain target:nil action:nil];
    _addFriendsBarButtonItem = [ initWithImage: style:UIBarButtonItemStylePlain target:self action:@selector(addFriendsPressed)];
}
</code></pre>

<p>你看,你添加到你的自定义 ViewControllerBool 属性,这些属性会改变 UIViewController 中 UINavigationItems 的内部结构。然后,使用此方法需要您在 ViewController 的 INIT 中调用并设置这些 bool 值,这些 ViewController 是此自定义 ViewController 的子类,如下所示:</p>

<pre><code>- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = ;
    if (self)
    {
      ;
      ;
    }
    return self;
}
</code></pre>

<p>然后在子类 UIViewController 中,使 bool 开关能够实际切换。</p>

<pre><code>- (void)viewWillAppear:(BOOL)animated
{
    ;

    if (_showsNotifications) {
      [ setRightBarButtonItem:_notificationsBarButtonItem];
    }
    if (_showsAddFriends) {
      [ setRightBarButtonItem:_addFriendsBarButtonItem];
    }
}
</code></pre>

<p>完成并完成,复杂吗?有点,但这就是你如何使用尽可能多的自定义导航项按钮来模板项目,完整的代码大约是 1k 行代码,但这是它的核心,子类 UIViewController,在标题中设置 bool 属性,设置这些子类中的 bool 属性,以便使用该子类作为其父类的 UIViewController 可以在“init”中调用这些 bool setter 属性,然后您将能够切换和选择您喜欢的任何导航项。此外,为了确保您的 ViewController 维护您为其设置的项目,请确保您还在 ViewController 中的 viewWillAppear 中声明这些项目设置,这些 ViewController 使用您的 UIViewController 的自定义子类作为您的父 View 。祝你好运,祝你有美好的一天。</p>

<p>事实上,我只是给你看代码,为什么?因为我很无聊,而且下周要发布两个应用程序有太多事情要做。因此,以下是您需要查看的文件,请记住,这些文件非常简化:</p>

<p>CCUSTViewController.m</p>

<pre><code>//******CCUSTViewController.m****
//this is the implementation file for the subclass of UIViewController

#import &#34;CCUSTViewController.h&#34;
#import &#34;CCUSTFriendsViewController.h&#34;
#import &#34;CCUSTActivitiesViewController.h&#34;

@interface CCUSTViewController ()
@end

@implementation CCUSTViewController
{
    UIBarButtonItem * _notificationsBarButtonItem;
    UIBarButtonItem * _addFriendsBarButtonItem;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = ;
    if (self == nil)
      return nil;
    if (self) {
      _showsNotifications = false;
      _showsAddFriends = false;
    }
    _notificationsBarButtonItem = [ initWithImage:: style:UIBarButtonItemStylePlain target:self action:@selector(showNotificationsPressed)];
    _addFriendsBarButtonItem = [ initWithImage: style:UIBarButtonItemStylePlain target:self action:@selector(addFriendsPressed)];
    return self;
}
- (void)showNotificationsPressed
{
    CCUSTActivitiesViewController * tobePushed = ;
    pushViewController:tobePushed animated:true];
}

- (void)addFriendsPressed
{
    CCUSTFriendsViewController * tobePushed = ;
    pushViewController:tobePushed animated:true];
}

- (void)viewWillAppear:(BOOL)animated
{
    ;
    if (_showsNotifications) {
      [ setRightBarButtonItem:_notificationsBarButtonItem];
    }
    if (_showsAddFriends) {
      [ setRightBarButtonItem:_addFriendsBarButtonItem];
    }
}

@end
</code></pre>

<p>CCUSTViewController.h</p>

<pre><code>#import &lt;UIKit/UIKit.h&gt;

@interface CCUSTViewController : UIViewController

@property (nonatomic) BOOL showsNotifications;
@property (nonatomic) BOOL showsAddFriends;

@end
</code></pre>

<p>然后,这是一个使用新导航栏项目切换器的子类 ViewController 的示例:</p>

<p>CCCUSTHomeViewController.h</p>

<pre><code>#import &#34;CCUSTViewController.h&#34;

@interface CCCUSTHomeViewController : CCUSTViewController
@end
</code></pre>

<p>CCCUSTHomeViewController.m</p>

<pre><code>// CCCUSTHomeViewController.m
#import &#34;CCCUSTHomeViewController.h&#34;
#import &#34;CCCUSTHomeView.h&#34;

@interface CCCUSTHomeViewController ()
@end

@implementation CCCUSTHomeViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = ;
    if (self)
    {
      ;
      ;
    }
    return self;
}

-(void)loadView
{
    ];
}

-(CCCUSTHomeView*)contentView
{
    return (id);
}

- (void)viewDidLoad
{
    ;
    ;
}

-(void)viewWillAppear:(BOOL)animated
{
    ;
    ;
    ;
}
@end
</code></pre>

<p>哦,是的,您需要将相同的代码从 init 添加到 ViewWillAppear,因为当您将推送的 ViewController 弹出堆栈时,即使在 CCCUSTHomeViewController 中,您也需要拦截它,以便 UINavigationItems 重新出现应该给位于堆栈顶部的 ViewController 。你还可以继承 UICollectionViewController 和 UITableViewController 的所有内容,使用相同的方法,这意味着使用这个结构作为模板,你可以在 Xcode 中创建一个空项目,并添加所有这些子类,然后你可以更好地控制你的所有 ViewController 。实现这个方法你可以做的还有很多,但有些事情,我必须保密,但我只想说,很多大型应用程序都使用相同的技术以及你看不到的其他高级技术在野外。巧妙的是,您不必委派,也无需操纵任何东西。祝你好运,祝你有美好的一天。</p>

<p>GISTS 因为我在乎:</p>

<p> <a href="https://gist.github.com/anonymous/993e457561001cf8e77b" rel="noreferrer noopener nofollow">https://gist.github.com/anonymous/993e457561001cf8e77b</a> </p>

<p> <a href="https://gist.github.com/anonymous/bc6095575038c36de77b" rel="noreferrer noopener nofollow">https://gist.github.com/anonymous/bc6095575038c36de77b</a> </p>

<p> <a href="https://gist.github.com/anonymous/78b450d2a805781ab8a4" rel="noreferrer noopener nofollow">https://gist.github.com/anonymous/78b450d2a805781ab8a4</a> </p>

<p> <a href="https://gist.github.com/anonymous/a0757179c17dd7078bb2" rel="noreferrer noopener nofollow">https://gist.github.com/anonymous/a0757179c17dd7078bb2</a> </p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 将按钮添加到 UINavigationBar 的子类,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/31897581/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/31897581/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 将按钮添加到 UINavigationBar 的子类