Custom Navigation Title in iOS 12












0















I am trying to implement a custom Navigation Title on an iOS app.



The StoryBoard looks like this:



enter image description here



The place that I want to have the custom Navigation Title is the last view ( the message view ), and because I use an image and text this means that I need to have custom width and height. By needing this if I do in viewDidLoad:



let rect = CGRect(x: 0, y:0, width: 150, height: 88)
titleView = UIView(frame: rect)
......
titleView?.addSubview(imageView)
......
titleView?.addSubview(label)
navigationItem.titleView = titleView


The height of the title is blocked to 44pt.



But how I managed to do it is adding the subViews to the navigation bar:



var navigationBar: MessagesNavigationBar? {
guard let navigationBar = navigationController?.navigationBar as? MessagesNavigationBar else {
return nil
}
return navigationBar
}


And in viewDidLoad



let rect = CGRect(x: 0, y:0, width: 150, height: 88)
titleView = UIView(frame: rect)
......
titleView?.addSubview(imageView)
......
titleView?.addSubview(label)
navigationBar?.addSubview(titleView!)


But the problem is that I have to remove the subviews when I leave the view, otherwise whatever I add there will be present in the table view as well.



override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if navigationBar != nil {
titleView?.removeFromSuperview()
}
}


Which kinda makes me feel that I'm not doing the right thing and I find difficult to add a fade out animation to those subViews when I leave the conversation. (i.e. native messages app on iOS).



So what is the right way of creating a custom Title Navigation Bar in iOS 12?



Scenes



enter image description here










share|improve this question

























  • “By needing this I can't use something like in viewDidLoad” why can’t you? That’s the normal and right thing to do...

    – matt
    Nov 20 '18 at 22:27











  • Sorry, I was ambiguous, and I edited the question. So, if I use navigationItem.titleView = titleView I cannot change the height of the titleView which is by default 44.

    – Sebastian Corneliu Vîrlan
    Nov 20 '18 at 22:31
















0















I am trying to implement a custom Navigation Title on an iOS app.



The StoryBoard looks like this:



enter image description here



The place that I want to have the custom Navigation Title is the last view ( the message view ), and because I use an image and text this means that I need to have custom width and height. By needing this if I do in viewDidLoad:



let rect = CGRect(x: 0, y:0, width: 150, height: 88)
titleView = UIView(frame: rect)
......
titleView?.addSubview(imageView)
......
titleView?.addSubview(label)
navigationItem.titleView = titleView


The height of the title is blocked to 44pt.



But how I managed to do it is adding the subViews to the navigation bar:



var navigationBar: MessagesNavigationBar? {
guard let navigationBar = navigationController?.navigationBar as? MessagesNavigationBar else {
return nil
}
return navigationBar
}


And in viewDidLoad



let rect = CGRect(x: 0, y:0, width: 150, height: 88)
titleView = UIView(frame: rect)
......
titleView?.addSubview(imageView)
......
titleView?.addSubview(label)
navigationBar?.addSubview(titleView!)


But the problem is that I have to remove the subviews when I leave the view, otherwise whatever I add there will be present in the table view as well.



override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if navigationBar != nil {
titleView?.removeFromSuperview()
}
}


Which kinda makes me feel that I'm not doing the right thing and I find difficult to add a fade out animation to those subViews when I leave the conversation. (i.e. native messages app on iOS).



So what is the right way of creating a custom Title Navigation Bar in iOS 12?



Scenes



enter image description here










share|improve this question

























  • “By needing this I can't use something like in viewDidLoad” why can’t you? That’s the normal and right thing to do...

    – matt
    Nov 20 '18 at 22:27











  • Sorry, I was ambiguous, and I edited the question. So, if I use navigationItem.titleView = titleView I cannot change the height of the titleView which is by default 44.

    – Sebastian Corneliu Vîrlan
    Nov 20 '18 at 22:31














0












0








0








I am trying to implement a custom Navigation Title on an iOS app.



The StoryBoard looks like this:



enter image description here



The place that I want to have the custom Navigation Title is the last view ( the message view ), and because I use an image and text this means that I need to have custom width and height. By needing this if I do in viewDidLoad:



let rect = CGRect(x: 0, y:0, width: 150, height: 88)
titleView = UIView(frame: rect)
......
titleView?.addSubview(imageView)
......
titleView?.addSubview(label)
navigationItem.titleView = titleView


The height of the title is blocked to 44pt.



But how I managed to do it is adding the subViews to the navigation bar:



var navigationBar: MessagesNavigationBar? {
guard let navigationBar = navigationController?.navigationBar as? MessagesNavigationBar else {
return nil
}
return navigationBar
}


And in viewDidLoad



let rect = CGRect(x: 0, y:0, width: 150, height: 88)
titleView = UIView(frame: rect)
......
titleView?.addSubview(imageView)
......
titleView?.addSubview(label)
navigationBar?.addSubview(titleView!)


But the problem is that I have to remove the subviews when I leave the view, otherwise whatever I add there will be present in the table view as well.



override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if navigationBar != nil {
titleView?.removeFromSuperview()
}
}


Which kinda makes me feel that I'm not doing the right thing and I find difficult to add a fade out animation to those subViews when I leave the conversation. (i.e. native messages app on iOS).



So what is the right way of creating a custom Title Navigation Bar in iOS 12?



Scenes



enter image description here










share|improve this question
















I am trying to implement a custom Navigation Title on an iOS app.



The StoryBoard looks like this:



enter image description here



The place that I want to have the custom Navigation Title is the last view ( the message view ), and because I use an image and text this means that I need to have custom width and height. By needing this if I do in viewDidLoad:



let rect = CGRect(x: 0, y:0, width: 150, height: 88)
titleView = UIView(frame: rect)
......
titleView?.addSubview(imageView)
......
titleView?.addSubview(label)
navigationItem.titleView = titleView


The height of the title is blocked to 44pt.



But how I managed to do it is adding the subViews to the navigation bar:



var navigationBar: MessagesNavigationBar? {
guard let navigationBar = navigationController?.navigationBar as? MessagesNavigationBar else {
return nil
}
return navigationBar
}


And in viewDidLoad



let rect = CGRect(x: 0, y:0, width: 150, height: 88)
titleView = UIView(frame: rect)
......
titleView?.addSubview(imageView)
......
titleView?.addSubview(label)
navigationBar?.addSubview(titleView!)


But the problem is that I have to remove the subviews when I leave the view, otherwise whatever I add there will be present in the table view as well.



override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if navigationBar != nil {
titleView?.removeFromSuperview()
}
}


Which kinda makes me feel that I'm not doing the right thing and I find difficult to add a fade out animation to those subViews when I leave the conversation. (i.e. native messages app on iOS).



So what is the right way of creating a custom Title Navigation Bar in iOS 12?



Scenes



enter image description here







ios swift xcode uinavigationcontroller uinavigationbar






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 '18 at 22:42







Sebastian Corneliu Vîrlan

















asked Nov 20 '18 at 22:02









Sebastian Corneliu VîrlanSebastian Corneliu Vîrlan

62711128




62711128













  • “By needing this I can't use something like in viewDidLoad” why can’t you? That’s the normal and right thing to do...

    – matt
    Nov 20 '18 at 22:27











  • Sorry, I was ambiguous, and I edited the question. So, if I use navigationItem.titleView = titleView I cannot change the height of the titleView which is by default 44.

    – Sebastian Corneliu Vîrlan
    Nov 20 '18 at 22:31



















  • “By needing this I can't use something like in viewDidLoad” why can’t you? That’s the normal and right thing to do...

    – matt
    Nov 20 '18 at 22:27











  • Sorry, I was ambiguous, and I edited the question. So, if I use navigationItem.titleView = titleView I cannot change the height of the titleView which is by default 44.

    – Sebastian Corneliu Vîrlan
    Nov 20 '18 at 22:31

















“By needing this I can't use something like in viewDidLoad” why can’t you? That’s the normal and right thing to do...

– matt
Nov 20 '18 at 22:27





“By needing this I can't use something like in viewDidLoad” why can’t you? That’s the normal and right thing to do...

– matt
Nov 20 '18 at 22:27













Sorry, I was ambiguous, and I edited the question. So, if I use navigationItem.titleView = titleView I cannot change the height of the titleView which is by default 44.

– Sebastian Corneliu Vîrlan
Nov 20 '18 at 22:31





Sorry, I was ambiguous, and I edited the question. So, if I use navigationItem.titleView = titleView I cannot change the height of the titleView which is by default 44.

– Sebastian Corneliu Vîrlan
Nov 20 '18 at 22:31












2 Answers
2






active

oldest

votes


















1














Creating your custom titleView and assigning it to navigationItem.titleView is what you want. On older systems (pre iOS 11) you just might need to call sizeToFit() on the titleView.



This way you can create this titleView



override func viewDidLoad() {
super.viewDidLoad()


let imageView = UIImageView()
NSLayoutConstraint.activate([
imageView.heightAnchor.constraint(equalToConstant: 20),
imageView.widthAnchor.constraint(equalToConstant: 20)
])
imageView.backgroundColor = .red

let titleLabel = UILabel()
titleLabel.text = "Custom title"

let hStack = UIStackView(arrangedSubviews: [imageView, titleLabel])
hStack.spacing = 5
hStack.alignment = .center

navigationItem.titleView = hStack
}


title view



You might also need to have the right set of autolayout constraints or use UIStackView.






share|improve this answer


























  • sizeToFit() is not working since iOS 11 as far as I read on other stackoverflow answers, I tried to use that first time as the default height is 44 and I didn't found a way to change it.

    – Sebastian Corneliu Vîrlan
    Nov 20 '18 at 22:32













  • Than probably your constraints don't define size of the titleView.

    – olejnjak
    Nov 20 '18 at 22:36











  • I don't have any constrains as is just a Navigation Controller -> Table Controller -> View Controller + Navigation Bar. I added to the question a print with the Scenes as well. By the way, the sizeToFit method is not even called.

    – Sebastian Corneliu Vîrlan
    Nov 20 '18 at 22:42













  • The titleView inside need constraints...btw. you were right since iOS 11 sizeToFit() is not needed

    – olejnjak
    Nov 20 '18 at 22:44











  • I've edited the original answer so it is a bit clearer

    – olejnjak
    Nov 20 '18 at 22:48



















2














These lines have no effect on the size of a title view:



let rect = CGRect(x: 0, y:0, width: 150, height: 88)
titleView = UIView(frame: rect)


Instead (or in addition) give your title view a width constraint and a height constraint. That is how the runtime knows what size you want.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53402257%2fcustom-navigation-title-in-ios-12%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    Creating your custom titleView and assigning it to navigationItem.titleView is what you want. On older systems (pre iOS 11) you just might need to call sizeToFit() on the titleView.



    This way you can create this titleView



    override func viewDidLoad() {
    super.viewDidLoad()


    let imageView = UIImageView()
    NSLayoutConstraint.activate([
    imageView.heightAnchor.constraint(equalToConstant: 20),
    imageView.widthAnchor.constraint(equalToConstant: 20)
    ])
    imageView.backgroundColor = .red

    let titleLabel = UILabel()
    titleLabel.text = "Custom title"

    let hStack = UIStackView(arrangedSubviews: [imageView, titleLabel])
    hStack.spacing = 5
    hStack.alignment = .center

    navigationItem.titleView = hStack
    }


    title view



    You might also need to have the right set of autolayout constraints or use UIStackView.






    share|improve this answer


























    • sizeToFit() is not working since iOS 11 as far as I read on other stackoverflow answers, I tried to use that first time as the default height is 44 and I didn't found a way to change it.

      – Sebastian Corneliu Vîrlan
      Nov 20 '18 at 22:32













    • Than probably your constraints don't define size of the titleView.

      – olejnjak
      Nov 20 '18 at 22:36











    • I don't have any constrains as is just a Navigation Controller -> Table Controller -> View Controller + Navigation Bar. I added to the question a print with the Scenes as well. By the way, the sizeToFit method is not even called.

      – Sebastian Corneliu Vîrlan
      Nov 20 '18 at 22:42













    • The titleView inside need constraints...btw. you were right since iOS 11 sizeToFit() is not needed

      – olejnjak
      Nov 20 '18 at 22:44











    • I've edited the original answer so it is a bit clearer

      – olejnjak
      Nov 20 '18 at 22:48
















    1














    Creating your custom titleView and assigning it to navigationItem.titleView is what you want. On older systems (pre iOS 11) you just might need to call sizeToFit() on the titleView.



    This way you can create this titleView



    override func viewDidLoad() {
    super.viewDidLoad()


    let imageView = UIImageView()
    NSLayoutConstraint.activate([
    imageView.heightAnchor.constraint(equalToConstant: 20),
    imageView.widthAnchor.constraint(equalToConstant: 20)
    ])
    imageView.backgroundColor = .red

    let titleLabel = UILabel()
    titleLabel.text = "Custom title"

    let hStack = UIStackView(arrangedSubviews: [imageView, titleLabel])
    hStack.spacing = 5
    hStack.alignment = .center

    navigationItem.titleView = hStack
    }


    title view



    You might also need to have the right set of autolayout constraints or use UIStackView.






    share|improve this answer


























    • sizeToFit() is not working since iOS 11 as far as I read on other stackoverflow answers, I tried to use that first time as the default height is 44 and I didn't found a way to change it.

      – Sebastian Corneliu Vîrlan
      Nov 20 '18 at 22:32













    • Than probably your constraints don't define size of the titleView.

      – olejnjak
      Nov 20 '18 at 22:36











    • I don't have any constrains as is just a Navigation Controller -> Table Controller -> View Controller + Navigation Bar. I added to the question a print with the Scenes as well. By the way, the sizeToFit method is not even called.

      – Sebastian Corneliu Vîrlan
      Nov 20 '18 at 22:42













    • The titleView inside need constraints...btw. you were right since iOS 11 sizeToFit() is not needed

      – olejnjak
      Nov 20 '18 at 22:44











    • I've edited the original answer so it is a bit clearer

      – olejnjak
      Nov 20 '18 at 22:48














    1












    1








    1







    Creating your custom titleView and assigning it to navigationItem.titleView is what you want. On older systems (pre iOS 11) you just might need to call sizeToFit() on the titleView.



    This way you can create this titleView



    override func viewDidLoad() {
    super.viewDidLoad()


    let imageView = UIImageView()
    NSLayoutConstraint.activate([
    imageView.heightAnchor.constraint(equalToConstant: 20),
    imageView.widthAnchor.constraint(equalToConstant: 20)
    ])
    imageView.backgroundColor = .red

    let titleLabel = UILabel()
    titleLabel.text = "Custom title"

    let hStack = UIStackView(arrangedSubviews: [imageView, titleLabel])
    hStack.spacing = 5
    hStack.alignment = .center

    navigationItem.titleView = hStack
    }


    title view



    You might also need to have the right set of autolayout constraints or use UIStackView.






    share|improve this answer















    Creating your custom titleView and assigning it to navigationItem.titleView is what you want. On older systems (pre iOS 11) you just might need to call sizeToFit() on the titleView.



    This way you can create this titleView



    override func viewDidLoad() {
    super.viewDidLoad()


    let imageView = UIImageView()
    NSLayoutConstraint.activate([
    imageView.heightAnchor.constraint(equalToConstant: 20),
    imageView.widthAnchor.constraint(equalToConstant: 20)
    ])
    imageView.backgroundColor = .red

    let titleLabel = UILabel()
    titleLabel.text = "Custom title"

    let hStack = UIStackView(arrangedSubviews: [imageView, titleLabel])
    hStack.spacing = 5
    hStack.alignment = .center

    navigationItem.titleView = hStack
    }


    title view



    You might also need to have the right set of autolayout constraints or use UIStackView.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 20 '18 at 22:47

























    answered Nov 20 '18 at 22:31









    olejnjakolejnjak

    468312




    468312













    • sizeToFit() is not working since iOS 11 as far as I read on other stackoverflow answers, I tried to use that first time as the default height is 44 and I didn't found a way to change it.

      – Sebastian Corneliu Vîrlan
      Nov 20 '18 at 22:32













    • Than probably your constraints don't define size of the titleView.

      – olejnjak
      Nov 20 '18 at 22:36











    • I don't have any constrains as is just a Navigation Controller -> Table Controller -> View Controller + Navigation Bar. I added to the question a print with the Scenes as well. By the way, the sizeToFit method is not even called.

      – Sebastian Corneliu Vîrlan
      Nov 20 '18 at 22:42













    • The titleView inside need constraints...btw. you were right since iOS 11 sizeToFit() is not needed

      – olejnjak
      Nov 20 '18 at 22:44











    • I've edited the original answer so it is a bit clearer

      – olejnjak
      Nov 20 '18 at 22:48



















    • sizeToFit() is not working since iOS 11 as far as I read on other stackoverflow answers, I tried to use that first time as the default height is 44 and I didn't found a way to change it.

      – Sebastian Corneliu Vîrlan
      Nov 20 '18 at 22:32













    • Than probably your constraints don't define size of the titleView.

      – olejnjak
      Nov 20 '18 at 22:36











    • I don't have any constrains as is just a Navigation Controller -> Table Controller -> View Controller + Navigation Bar. I added to the question a print with the Scenes as well. By the way, the sizeToFit method is not even called.

      – Sebastian Corneliu Vîrlan
      Nov 20 '18 at 22:42













    • The titleView inside need constraints...btw. you were right since iOS 11 sizeToFit() is not needed

      – olejnjak
      Nov 20 '18 at 22:44











    • I've edited the original answer so it is a bit clearer

      – olejnjak
      Nov 20 '18 at 22:48

















    sizeToFit() is not working since iOS 11 as far as I read on other stackoverflow answers, I tried to use that first time as the default height is 44 and I didn't found a way to change it.

    – Sebastian Corneliu Vîrlan
    Nov 20 '18 at 22:32







    sizeToFit() is not working since iOS 11 as far as I read on other stackoverflow answers, I tried to use that first time as the default height is 44 and I didn't found a way to change it.

    – Sebastian Corneliu Vîrlan
    Nov 20 '18 at 22:32















    Than probably your constraints don't define size of the titleView.

    – olejnjak
    Nov 20 '18 at 22:36





    Than probably your constraints don't define size of the titleView.

    – olejnjak
    Nov 20 '18 at 22:36













    I don't have any constrains as is just a Navigation Controller -> Table Controller -> View Controller + Navigation Bar. I added to the question a print with the Scenes as well. By the way, the sizeToFit method is not even called.

    – Sebastian Corneliu Vîrlan
    Nov 20 '18 at 22:42







    I don't have any constrains as is just a Navigation Controller -> Table Controller -> View Controller + Navigation Bar. I added to the question a print with the Scenes as well. By the way, the sizeToFit method is not even called.

    – Sebastian Corneliu Vîrlan
    Nov 20 '18 at 22:42















    The titleView inside need constraints...btw. you were right since iOS 11 sizeToFit() is not needed

    – olejnjak
    Nov 20 '18 at 22:44





    The titleView inside need constraints...btw. you were right since iOS 11 sizeToFit() is not needed

    – olejnjak
    Nov 20 '18 at 22:44













    I've edited the original answer so it is a bit clearer

    – olejnjak
    Nov 20 '18 at 22:48





    I've edited the original answer so it is a bit clearer

    – olejnjak
    Nov 20 '18 at 22:48













    2














    These lines have no effect on the size of a title view:



    let rect = CGRect(x: 0, y:0, width: 150, height: 88)
    titleView = UIView(frame: rect)


    Instead (or in addition) give your title view a width constraint and a height constraint. That is how the runtime knows what size you want.






    share|improve this answer




























      2














      These lines have no effect on the size of a title view:



      let rect = CGRect(x: 0, y:0, width: 150, height: 88)
      titleView = UIView(frame: rect)


      Instead (or in addition) give your title view a width constraint and a height constraint. That is how the runtime knows what size you want.






      share|improve this answer


























        2












        2








        2







        These lines have no effect on the size of a title view:



        let rect = CGRect(x: 0, y:0, width: 150, height: 88)
        titleView = UIView(frame: rect)


        Instead (or in addition) give your title view a width constraint and a height constraint. That is how the runtime knows what size you want.






        share|improve this answer













        These lines have no effect on the size of a title view:



        let rect = CGRect(x: 0, y:0, width: 150, height: 88)
        titleView = UIView(frame: rect)


        Instead (or in addition) give your title view a width constraint and a height constraint. That is how the runtime knows what size you want.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 20 '18 at 22:45









        mattmatt

        329k46534732




        329k46534732






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53402257%2fcustom-navigation-title-in-ios-12%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

            ComboBox Display Member on multiple fields

            Is it possible to collect Nectar points via Trainline?