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

      62.4k1068135




      62.4k1068135
























          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















          Required, but never shown

























          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

          93.4k16151196




          93.4k16151196












          • 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




















































          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.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • 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%2f53238118%2fhow-can-i-use-ibinspectable-to-control-a-property-of-a-subview%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

          Schultheiß

          Verwaltungsgliederung Dänemarks

          Liste der Kulturdenkmale in Wilsdruff