UINavigationBar子类中的自定义后退按钮

时间:2015-04-14 10:53:51

标签: ios objective-c uinavigationbar subclass uinavigationitem

我正在编写UINavigationBar的子类,并希望在其中集成一个默认的backButton。

根据我对文档的理解,我需要观察在item属性中添加新项目的时间,并在其中添加我的自定义后退按钮。

我是在UINavigationBar子类中完成的:

- (void)pushNavigationItem:(UINavigationItem *)item animated:(BOOL)animated {
    [super pushNavigationItem:item animated:animated];

    ActionButton *leftButtom = [[ActionButton alloc] init];
    leftButtom.cancel = NO;

    [item setBackBarButtonItem:[[UIBarButtonItem alloc] initWithCustomView:leftButtom]];
}

- (UINavigationItem *)popNavigationItemAnimated:(BOOL)animated {
    return [super popNavigationItemAnimated:animated];
}

我不明白为什么,但是当我按下后退按钮时会调用popNavigationItemAnimated,但是当我按下一个新的ViewController时,pushNavigationItem没有被调用。

我已经检查过调试器和

po [[self.navigationController navigationBar] items]

正确打印数组上有新项目。

我错过了什么吗?

3 个答案:

答案 0 :(得分:0)

请试试这个,我想这可能会有所帮助

// image for my back button

UIImage *backButtonImage= [UIImage imageNamed:@"Back.png"];
UIButton *leftBarButton = [UIButton buttonWithType: UIButtonTypeCustom];

// Setting the image for the back button

[leftBarButton setBackgroundImage: backButtonImage forState:UIControlStateNormal];  
[leftBarButton addTarget: self action:@selector(backToMenu:) forControlEvents:UIControlEventTouchUpInside];

// setting the frame for the back button

leftBarButton.frame = CGRectMake(0, 0, 65, 32);  

// setting the custom button to navigationbars back button

self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView: leftBarButton];

答案 1 :(得分:0)

UINavigationBar不负责导航堆栈。我假设您需要UINavigationController并在推送到导航控制器的视图控制器中添加导航项。这是组织导航堆栈的常用方法。

答案 2 :(得分:0)

最重要的是,我喜欢您的方法,将更改导航栏的责任放在UINavigationController而不是某些基本的UIViewController类上。那里的孩子似乎不了解这种自然的人类逻辑。这是我最近想出的完整解决方案:

class NavigationControllerLightNavigationBar: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // When we load this Controller we most likely already have at least one
        // view controller to modify. So let's modify some back arrows
        for viewController in viewControllers {
            viewController.navigationItem.backBarButtonItem = createBackButton()
        }
    }

    override func pushViewController(_ viewController: UIViewController, animated: Bool) {
        super.pushViewController(viewController, animated: animated)
        // Modify back arrow for every new view controller
        viewController.navigationItem.backBarButtonItem = createBackButton()
    }

    private func createBackButton() -> UIBarButtonItem {
        // Chose whatever size you like
        let itemHeight = CGFloat(30)
        // Make an UIImageView
        let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: itemHeight, height: itemHeight))
        // Make it to display icons the right way
        imageView.contentMode = .scaleAspectFit
        // Set our icon as image
        imageView.image = #imageLiteral(resourceName: "backArrowIcon")
        // Now let's make a UIBarButton container for our image
        // and put the image inside of it
        let barButton = UIBarButtonItem(customView: imageView)
        // Now set this item's constraints
        barButton.width = itemHeight
        let width = barButton.customView?.widthAnchor.constraint(equalToConstant: itemHeight)
        width?.isActive = true
        let height = barButton.customView?.heightAnchor.constraint(equalToConstant: itemHeight)
        height?.isActive = true
        // Remove title
        barButton.title = nil
        // Dont forget to change your icon's color.
        // If we skip this our icon would be blue no matter what
        barButton.tintColor = UIColor.red
        return barButton
    }
}