自定义 UINavigationItem 类 - 标题取决于 Active UIStoryboard

Posted

技术标签:

【中文标题】自定义 UINavigationItem 类 - 标题取决于 Active UIStoryboard【英文标题】:Custom UINavigationItem class - Title dependent on Active UIStoryboard 【发布时间】:2017-07-27 10:29:59 【问题描述】:

我创建了一个包含三个故事板的应用程序。 (和多个 VC) 我正在创建一个全局 NavigationItem 类,我可以在情节提要中输入它,因此每个视图控制器都继承相同的信息,我只需编写一个页面而不是复制和粘贴到每个 VC 中。

我想以编程方式设置标题。标题可以根据激活的情节提要和手机的尺寸而改变。即在 iPhone SE 上显示的完整标题或简写。

我不能使用。 UIStoryboard 作为布尔值,因为它不符合要求。我怎样才能知道我在哪个故事板中,所以它可以在 if 语句中设置标题?我写的代码是错误的,对故事板不起作用。

到目前为止,我的 NavigationItemCustom 类的代码设置如下我发现很难找到我所在的情节提要?谁能把我推向正确的方向,拜托。我的代码如下:

import UIKit
class NavigationBarSetUp: UINavigationItem 

    override func awakeFromNib() 
        super.awakeFromNib()


        let currentstoryboard = UIStoryboard()
        let screenWidth = UIScreen.main.bounds.width

        let storyboard1 = UIStoryboard(name: "First", bundle: nil)
        //let storyboard2 = UIStoryboard(name: "Second", bundle: nil)
        //let storyboard3 = UIStoryboard(name: "Third", bundle: nil)

        //Current title
        self.title = nil

        if currentstoryboard == storyboard1 && (screenWidth == 320) 

            self.title = " diet 1"
            print ("called short title")

         else if currentstoryboard == storyboard1 && (screenWidth > 320) 

            // rest of screen sizes
            self.title = " Welcome to diet 1"
            print ("called full title")
        

        // Repeat if statement for storyboards 2 & 3 with different titles.


        // Rest of Class code - Bar Button Item Setup
        self.hidesBackButton = false
        self.leftItemsSupplementBackButton = true

        // Left Side Button Setup

        let buttonView = UIToolbar()
            buttonView.frame = .init(x: 0, y:-7, width: 30, height: 30)

        // Setting UIToolbar Transparency of the toolbar 
            buttonView.setBackgroundImage(UIImage(),
                                        forToolbarPosition: .any,
                                        barMetrics: .default)
            buttonView.setShadowImage(UIImage(), forToolbarPosition: .any)


        // This is a UIView the Toolbar will sit inside which will then be placed into the Navigationbar.
        let navigationContainer = UIView()
        navigationContainer.frame = .init(x: 0, y:0, width: 30, height: 30)

        // ButtonBarItems Set Up

        let ModalButton = UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(NotesButtonClicked))

        let negativeSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.fixedSpace, target: self, action: nil)
        negativeSpace.width = -10

        //Add ButtonBarItems into the UIToolbar ButtonView
            buttonView.setItems([negativeSpace, ModalButton], animated: false)

        // Add UItoolbar into UIView
            navigationContainer.addSubview(buttonView)

        //Icon Size to fit
            buttonView.sizeToFit()

        //Convert UIView into Barbutton Item to set in the Navigation Bar
        let topLeft = UIBarButtonItem()
        topLeft.customView = navigationContainer

        self.setLeftBarButton(topLeft, animated: false)


        // Setup of the Right Handside Menu Button

        let BurgerButton = UIButton()
            BurgerButton.frame = .init(x: -1, y: 0.5, width: 62, height: 25)
            BurgerButton.setBackgroundImage(UIImage(named: "BurgerButton1.pdf"), for: .normal)


            BurgerButton.addTarget(self, action: #selector(MenuClicked), for: .touchUpInside)

        let topRight = UIBarButtonItem()
        topRight.customView = BurgerButton

        self.setRightBarButton(topRight, animated: true)

    

        // Calls the Left Button Action. 

        func NotesButtonClicked(_ sender: UIBarButtonItem) 

            print("Notes Modal Is Called")

            //Code here

    

        // Calls the Right Button Action. 

        func MenuClicked(_ sender: UIButton) 

            print("Menu is Opened - Rightside")

            //Code here

    

【问题讨论】:

【参考方案1】:

嗯,你正在做一些不起作用的事情:

    let currentstoryboard = UIStoryboard()

您刚刚创建了一个(空)UIStoryBoard 对象的实例...

    let storyboard1 = UIStoryboard(name: "First", bundle: nil)

您刚刚创建了一个UIStoryBoard 对象的NEW 实例,引用了名为“First”的情节提要(假设它存在于您的应用中)。

这两个实例可能永远相等。

UIViewController 有一个.storyboard 属性,即“视图控制器源自的情节提要”。

但是,即使您尝试过:

    let currentstoryboard = self.storyboard
    let storyboard1 = UIStoryboard(name: "First", bundle: nil)
    if currentstoryboard == storyboard1  ... 

他们将仍然永远不会相等,因为storyboard1是一个实例。

可以试试:

    let sbName = self.storyboard?.value(forKey: "name") as? String
    if sbName == "First"  ... 

不幸的是,Apple 似乎没有记录这一点,并且很可能会导致您的应用被拒绝

我认为您最好使用自己的变量/属性来跟踪是什么。

【讨论】:

感谢您指出我的错误并解释它非常有用!我不想做任何可能让应用程序被拒绝的事情,如果它没有直接从类初始化此代码的方法。大声思考也许我可以在视图中每个故事板的每个初始 VC 中添加一个带有 NSnotificationcentre 的观察者。然后在课堂上听这个并相应地更改标题。或者也许我会放弃并在每个视图控制器中设置标题,并在需要的地方使用单独的 if 语句来设置标题长度。虽然这会有点重复! 您是否在每个 Storyboard 中使用相同的 VC 类? 我在每个 VC 故事板中使用了几个不同的类。但是你给了我一个想法,我当然可以制作三个不同的 UINavigationItem 类,每个类都有一个相应的标题更改,并简单地为每个故事板中的每个导航栏分配一个。这比在 VC 中重复代码要快得多。它不像使用一个类那么优雅,但用更少的代码更快。 我应该将您的答案标记为正确吗?我认为这对于希望未来的人们知道试图找到一个活跃的故事板可能意味着你的应用程序被拒绝会有所帮助? 我相信它不会有任何伤害...我想说我们的 cmets 中已经足够清晰了。

以上是关于自定义 UINavigationItem 类 - 标题取决于 Active UIStoryboard的主要内容,如果未能解决你的问题,请参考以下文章

您如何确定自定义 UINavigationItem.titleView 的大小/框架?

iOS开发:关于UINavigationItem和tintColor的沉思

UINavigationItem 标题视图的框架

如何基于 nib 文件创建 UINavigationItem.TitleView?

设置 uinavigationitem 的后退按钮不起作用

UINavigationItem.titleView 能否成为FirstResponder?