How can I use IBInspectable to control a property of a subview?









up vote
1
down vote

favorite












I am writing a custom view that has two labels as subviews - titleLabel and subtitleLabel.



I added two @IBInspectable properties called titleText and subtitleText so that I can set the texts of the labels very easily in the storyboard.



class MyView : UIView 
var titleLabel: UILabel!
var subtitleLabel: UILabel!

@IBInspectable
var titleText: String?
get return titleLabel.text
set
titleLabel.text = newValue
let fontSize = // calculates appropriate font size for the text...
titleLabel.font = font.withSize(fontSize)



@IBInspectable
var subtitleText: String?
get return subtitleLabel.text
set
subtitleLabel.text = newValue
let fontSize = // calculates appropriate font size for the text...
subtitleLabel.font = font.withSize(fontSize)



override func draw(_ rect: CGRect)
// here I make the view look prettier, irrelevant to the question




Now I need to initialise those two labels and add them as MyView's subviews. I thought I could do this in awakeFromNib:



override func awakeFromNib() 
titleLabel = UILabel(frame: CGRect(
x: ...,
y: ...,
width: ...,
height: ...))
self.addSubview(titleLabel)
subtitleLabel = UILabel(frame: CGRect(
x: ...,
y: ...,
width: ...,
height: ...))
self.addSubview(subtitleLabel)




So I added a MyView to the storyboard and set its properties with the properties inspector and I ran the app. It crashed.



Apparently, the IBInspectable properties are set before awakeFromNib so the labels have not been initialised by then.



This means that I need to initialise the labels in a method that is called before the IBInspectable properties are set.



What is a method that is called before IBInspectable properties are set that I can override to initialise the subviews?










share|improve this question

























    up vote
    1
    down vote

    favorite












    I am writing a custom view that has two labels as subviews - titleLabel and subtitleLabel.



    I added two @IBInspectable properties called titleText and subtitleText so that I can set the texts of the labels very easily in the storyboard.



    class MyView : UIView 
    var titleLabel: UILabel!
    var subtitleLabel: UILabel!

    @IBInspectable
    var titleText: String?
    get return titleLabel.text
    set
    titleLabel.text = newValue
    let fontSize = // calculates appropriate font size for the text...
    titleLabel.font = font.withSize(fontSize)



    @IBInspectable
    var subtitleText: String?
    get return subtitleLabel.text
    set
    subtitleLabel.text = newValue
    let fontSize = // calculates appropriate font size for the text...
    subtitleLabel.font = font.withSize(fontSize)



    override func draw(_ rect: CGRect)
    // here I make the view look prettier, irrelevant to the question




    Now I need to initialise those two labels and add them as MyView's subviews. I thought I could do this in awakeFromNib:



    override func awakeFromNib() 
    titleLabel = UILabel(frame: CGRect(
    x: ...,
    y: ...,
    width: ...,
    height: ...))
    self.addSubview(titleLabel)
    subtitleLabel = UILabel(frame: CGRect(
    x: ...,
    y: ...,
    width: ...,
    height: ...))
    self.addSubview(subtitleLabel)




    So I added a MyView to the storyboard and set its properties with the properties inspector and I ran the app. It crashed.



    Apparently, the IBInspectable properties are set before awakeFromNib so the labels have not been initialised by then.



    This means that I need to initialise the labels in a method that is called before the IBInspectable properties are set.



    What is a method that is called before IBInspectable properties are set that I can override to initialise the subviews?










    share|improve this question























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I am writing a custom view that has two labels as subviews - titleLabel and subtitleLabel.



      I added two @IBInspectable properties called titleText and subtitleText so that I can set the texts of the labels very easily in the storyboard.



      class MyView : UIView 
      var titleLabel: UILabel!
      var subtitleLabel: UILabel!

      @IBInspectable
      var titleText: String?
      get return titleLabel.text
      set
      titleLabel.text = newValue
      let fontSize = // calculates appropriate font size for the text...
      titleLabel.font = font.withSize(fontSize)



      @IBInspectable
      var subtitleText: String?
      get return subtitleLabel.text
      set
      subtitleLabel.text = newValue
      let fontSize = // calculates appropriate font size for the text...
      subtitleLabel.font = font.withSize(fontSize)



      override func draw(_ rect: CGRect)
      // here I make the view look prettier, irrelevant to the question




      Now I need to initialise those two labels and add them as MyView's subviews. I thought I could do this in awakeFromNib:



      override func awakeFromNib() 
      titleLabel = UILabel(frame: CGRect(
      x: ...,
      y: ...,
      width: ...,
      height: ...))
      self.addSubview(titleLabel)
      subtitleLabel = UILabel(frame: CGRect(
      x: ...,
      y: ...,
      width: ...,
      height: ...))
      self.addSubview(subtitleLabel)




      So I added a MyView to the storyboard and set its properties with the properties inspector and I ran the app. It crashed.



      Apparently, the IBInspectable properties are set before awakeFromNib so the labels have not been initialised by then.



      This means that I need to initialise the labels in a method that is called before the IBInspectable properties are set.



      What is a method that is called before IBInspectable properties are set that I can override to initialise the subviews?










      share|improve this question













      I am writing a custom view that has two labels as subviews - titleLabel and subtitleLabel.



      I added two @IBInspectable properties called titleText and subtitleText so that I can set the texts of the labels very easily in the storyboard.



      class MyView : UIView 
      var titleLabel: UILabel!
      var subtitleLabel: UILabel!

      @IBInspectable
      var titleText: String?
      get return titleLabel.text
      set
      titleLabel.text = newValue
      let fontSize = // calculates appropriate font size for the text...
      titleLabel.font = font.withSize(fontSize)



      @IBInspectable
      var subtitleText: String?
      get return subtitleLabel.text
      set
      subtitleLabel.text = newValue
      let fontSize = // calculates appropriate font size for the text...
      subtitleLabel.font = font.withSize(fontSize)



      override func draw(_ rect: CGRect)
      // here I make the view look prettier, irrelevant to the question




      Now I need to initialise those two labels and add them as MyView's subviews. I thought I could do this in awakeFromNib:



      override func awakeFromNib() 
      titleLabel = UILabel(frame: CGRect(
      x: ...,
      y: ...,
      width: ...,
      height: ...))
      self.addSubview(titleLabel)
      subtitleLabel = UILabel(frame: CGRect(
      x: ...,
      y: ...,
      width: ...,
      height: ...))
      self.addSubview(subtitleLabel)




      So I added a MyView to the storyboard and set its properties with the properties inspector and I ran the app. It crashed.



      Apparently, the IBInspectable properties are set before awakeFromNib so the labels have not been initialised by then.



      This means that I need to initialise the labels in a method that is called before the IBInspectable properties are set.



      What is a method that is called before IBInspectable properties are set that I can override to initialise the subviews?







      ios swift uiview






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 10 at 10:40









      Sweeper

      60k967134




      60k967134






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote



          accepted










          This might be obvious but the correct method to put such things into is the initializer.



          // called when initialized from code
          override init(frame: CGRect)
          super.init(frame: frame)
          commonInit()


          // called when initialized from storyboard/xib
          required init?(coder: NSCoder)
          super.init(coder: coder)
          commonInit()


          private func commonInit()
          // add subviews



          Also, there is no real reason for optionals in your specific case:



          let titleLabel: UILabel = UILabel()


          You can add the labels as subviews and update frames later.






          share|improve this answer




















          • It worked! I had always thought I need to initialise my properties in init(from aDecoder)! That's why I never thought of using init.
            – Sweeper
            Nov 10 at 10:59










          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',
          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%2f53238118%2fhow-can-i-use-ibinspectable-to-control-a-property-of-a-subview%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          2
          down vote



          accepted










          This might be obvious but the correct method to put such things into is the initializer.



          // called when initialized from code
          override init(frame: CGRect)
          super.init(frame: frame)
          commonInit()


          // called when initialized from storyboard/xib
          required init?(coder: NSCoder)
          super.init(coder: coder)
          commonInit()


          private func commonInit()
          // add subviews



          Also, there is no real reason for optionals in your specific case:



          let titleLabel: UILabel = UILabel()


          You can add the labels as subviews and update frames later.






          share|improve this answer




















          • It worked! I had always thought I need to initialise my properties in init(from aDecoder)! That's why I never thought of using init.
            – Sweeper
            Nov 10 at 10:59














          up vote
          2
          down vote



          accepted










          This might be obvious but the correct method to put such things into is the initializer.



          // called when initialized from code
          override init(frame: CGRect)
          super.init(frame: frame)
          commonInit()


          // called when initialized from storyboard/xib
          required init?(coder: NSCoder)
          super.init(coder: coder)
          commonInit()


          private func commonInit()
          // add subviews



          Also, there is no real reason for optionals in your specific case:



          let titleLabel: UILabel = UILabel()


          You can add the labels as subviews and update frames later.






          share|improve this answer




















          • It worked! I had always thought I need to initialise my properties in init(from aDecoder)! That's why I never thought of using init.
            – Sweeper
            Nov 10 at 10:59












          up vote
          2
          down vote



          accepted







          up vote
          2
          down vote



          accepted






          This might be obvious but the correct method to put such things into is the initializer.



          // called when initialized from code
          override init(frame: CGRect)
          super.init(frame: frame)
          commonInit()


          // called when initialized from storyboard/xib
          required init?(coder: NSCoder)
          super.init(coder: coder)
          commonInit()


          private func commonInit()
          // add subviews



          Also, there is no real reason for optionals in your specific case:



          let titleLabel: UILabel = UILabel()


          You can add the labels as subviews and update frames later.






          share|improve this answer












          This might be obvious but the correct method to put such things into is the initializer.



          // called when initialized from code
          override init(frame: CGRect)
          super.init(frame: frame)
          commonInit()


          // called when initialized from storyboard/xib
          required init?(coder: NSCoder)
          super.init(coder: coder)
          commonInit()


          private func commonInit()
          // add subviews



          Also, there is no real reason for optionals in your specific case:



          let titleLabel: UILabel = UILabel()


          You can add the labels as subviews and update frames later.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 10 at 10:49









          Sulthan

          92.2k16148196




          92.2k16148196











          • It worked! I had always thought I need to initialise my properties in init(from aDecoder)! That's why I never thought of using init.
            – Sweeper
            Nov 10 at 10:59
















          • It worked! I had always thought I need to initialise my properties in init(from aDecoder)! That's why I never thought of using init.
            – Sweeper
            Nov 10 at 10:59















          It worked! I had always thought I need to initialise my properties in init(from aDecoder)! That's why I never thought of using init.
          – Sweeper
          Nov 10 at 10:59




          It worked! I had always thought I need to initialise my properties in init(from aDecoder)! That's why I never thought of using init.
          – Sweeper
          Nov 10 at 10:59

















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53238118%2fhow-can-i-use-ibinspectable-to-control-a-property-of-a-subview%23new-answer', 'question_page');

          );

          Post as a guest














































































          這個網誌中的熱門文章

          How to read a connectionString WITH PROVIDER in .NET Core?

          In R, how to develop a multiplot heatmap.2 figure showing key labels successfully

          Museum of Modern and Contemporary Art of Trento and Rovereto