1

I have a class called Sentence and I would like to set the text property of my @IBOutlet in my ViewController in one of the methods of Sentence. Is that possible? If not, within the Sentence class method itself, how can I make a call or a function which sets my @IBOutlet text from the class method?

Here is my UILabel

@IBOutlet weak var kleinGrossLabel: UILabel!

JAL
  • 41,701
  • 23
  • 172
  • 300
Thalatta
  • 4,510
  • 10
  • 48
  • 79
  • @MikeG That doesn't address any of the issues presented by this question, such as how to properly set the text from a class that doesn't have direct access to kleinGrossLabel. – Will M. Feb 01 '16 at 18:06
  • @WillM. I misread question, thanks for heads up – MikeG Feb 01 '16 at 18:07

2 Answers2

5

You can't assign an IBOutlet from a UIViewController in a class method of another class. How is that other class (in your case Sentence) supposed to know about the view controller?

You have a few options:

  1. Keep a reference to your view controller in your Sentence object.
  2. Use delegation: set a delegate on your Sentence instance that points back to the view controller, and have one of the protocol methods access the contents of the IBOutlet.
  3. Use NSNotificationCenter to fire a notification from your Sentence object that your view controller is listening to, and can update its IBOutlet directly.
JAL
  • 41,701
  • 23
  • 172
  • 300
  • Thanks JAL. Which of the following three is best practice? Or, if equivalent, which would you personally use? – Thalatta Feb 01 '16 at 18:06
  • 1
    http://stackoverflow.com/questions/1927965/nsnotificationcenter-vs-delegation-using-protocols has good info – Will M. Feb 01 '16 at 18:07
  • "Best practice" questions are generally not good for Stack Overflow, as they are primarily opinion based. It's all about finding which option is best for your application architecture. Delegation is a popular pattern within iOS programming, although notifications are probably the easiest to use. I wouldn't recommend keeping a reference (option 1). – JAL Feb 01 '16 at 18:08
3

Tight coupling would be when a class like Sentence, assumes a responsibility for something outside its concern, such as a view controller's outlet.

These types of changes can difficult to track down, as it is not obvious where the state was changed.

While you can loosely couple Sentence by using delegation or notification, it would still make it more difficult, both for (unit or UI) testing, and for supporting and maintaining your code, when one class (in)directly affects the state of another class.

An alternate way

You can move this responsibility out of Sentence by providing a public method for Sentence which returns the desired property.

By establishing a clear interface boundary like this, it allows your code to be more modular, letting you make changes to either the implementation of Sentence, or to the view controller's outlets, without affecting something in the other class.

It also allows the view controller (from an MVC perspective) to be solely responsible for changing the view's text property.

Now, from the view controller, you can call a sentence instance's public method, then set the view controller's IBOutlet text property based on the returned value. This will make it obvious where and why the text has changed, instead of hiding that change in another (class's) method.

  • 1
    This is the correct way to go if the view controller knows when to pull the updated information from the Sentence class. However, JAL's solution is correct if the view controller needs that information pushed to it. Depends on the situation which is better. – Will M. Feb 01 '16 at 19:00