Changing value of an object from a different class - ios

I have a ViewController.m with a UIButton and a UIWebView on it.
I've subclassed UIWebView to a class that is now called MyWebView.m.
What is the most efficient way to change the UIButton outlet location value from a method that is inside MyWebView.m
I thought about NSUserDefaults but it feels to me like it's the worst way to go.
Another thought was to copy the next line and also add it inside MyWebView.h:
#property (weak, nonatomic) IBOutlet UIButton *myButton;
and connect it to the button from ViewController.m but I'm also not sure if that's a right thing to do.

What does the button title represent, conceptually? Decide that, and expose it as a string property of your web view and then have your view controller observe the property with key value observing. Or alternatively, extend UIWebViewDelegate with your own protocol, and have the view controller set itself as the web view's delegate. Then have the web view notify its delegate that this value changed.

You can use the app delegate class for persisting the data through the application but this is also not recommended by the good programmers.
One other way is to use Singleton class . This creates only one object per application session so you can use the the value throughout the application also you can modify and access the value. This is the pure approach to go .You can take a look at http://www.galloway.me.uk/tutorials/singleton-classes/

Related

Objective C: Access Variable From View Controller To NSObject

I am started learning objective c again, and I am trying to access a variable from my main view controller in my NSObject class.
How would I do that?
For example I have declared
UITextField *name;
and I want to use it in my NSObject.
The best practise would be implement delegate pattern here. Suppose you want to change the value/content of UITextField, then fire the delegate with the value. And in ViewController class, set the delegate and implement that delegate method. In that delegate method, update value/content of UITextField.
One more thing, Please make sure to update UITextField's content/value in main thread. UI related changes should be always done in main thread.
You can refer to the NSObject class via a method with the plus sign '+' +(type)anyMethod; to get the variable. If I correctly understood what you mean

Adding custom protocol to UITextField

I have some forms for the authentications and signup views and I want that all UITextField inside those forms have a UIButton as an accessory view, just above the keyboard. I want to have the possibility to set the title and the action for this button
Because I want all those text field have one and each will have a title and an action, and to avoid redundancy, I thought about a protocol.
I want something like extending a custom protocol, for example UITextFieldAccessoryViewDelegate and to be conform to some functions like :
-buttonAccessoryView title ... -> String
-didClickOnAccessoryViewButton.. -> ()
My mind is closed. Someone can give me some ideas to do what I want ?
You could use associated objects to solve this problem. This lets you add a property and its synthesized getter/setters.
#interface UITextField(AccessoryButton)
#property(readwrite, strong, nonatomic) UIButton *accessoryButton;
#end
#import<objc/runtime.h>
#implementation UITextField(AccessoryButton)
-(UIButton*) accessoryButton
{
objc_getAssociatedObject(self, #selector(accessoryButton));
}
-(void) setAccessoryButton:(UIButton *)accessoryButton
{
objc_setAssociatedObject(self, #selector(accessoryButton), accessoryButton, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
Include this category into your forms that need the UIButton for the text fields. Then assign action and title to a UIButton like how you normally do.
Considering everything you want to do I think you are better off using a subclass of UITextField rather than an extension.
Extensions can't add instance variables to the objects they extend, but subclasses can. As lead_the_zeppelin points out in his answer, you can use associated objects to simulate adding instance variables with an extension but it seems like you're making it needlessly complicated when a subclass gives you everything you want.

id vs class name when defining delegate properties

I am working on a delegate pattern for authorization in my app.
Most things i've seen before use something like:
#property (weak) id<Delegate> delegate;
Does that make it weaker than say
#property (weak) UIViewController<Delegate> *delegate;
I realize i am asking for any pointer in the first one and in the second I am expecting a typed pointer. But i only want my delegate to be a UIViewController or subclass.
Can anyone explain the differences and pros and cons?
But I only want my delegate to be a UIViewController or subclass.
Then go for the second way - the first one indicates that it can be any object that conforms to the <Delegate> protocol.
There are not real pros or cons. The contract is just different. One says "I don't care what class it is as long as it conforms to that protocol" and the other says "I want a subclass of UIViewController which also conforms to the protocol".
The only thing here is that the idea of the "delegate" pattern in Cocoa is generally to give the client of your API a way to create an object that will customize the behavior of one or several other components.
Since you want this property to be a view controller, the semantic is more than just a delegate so I would not call it a delegate but a xxxViewController with "xxx" being the actual functional relationship between your object and that view controller.

Using Two Views with One UIViewcontroller

I am using one simple UIViewController for my application which is not too complicated. It has two pages. On the first page I enter data in to text boxes to indicate user changeable data which will be handled on the second page.
#property (weak, nonatomic) IBOutlet UITextField *routeText;
When I am running my actions on the second page, I use a command like this to access what was typed in to the text box:
NSString *variable = [[NSString alloc]initWithFormat:#"%#",self.routeLabel.text];
self.consoleView.text = variable;
But the value is always (null). I am using the same TravelViewController.h/.m for all of the code. My question is: Is this not acceptable coding behavior to share it in this way or do I need to define the objects in a different way so the text can be shared between views?
Thanks for any help you could provide.
If it is a different view controller you need to pass the text from parent view controller to child using #property. Declare it in second class and when you are pushing from first screen to second, set this value in #property. After that you can use it in second screen using self.text.

Changing SearchDisplayController Delegate in interface builder

I'm trying to show a search bar above a table with a list of recent searches that will swap to matching search results once someone enters a search term.
I want to set a custom class MySearchViewController to be the delegate for doing the search and managing the display of search results back to the table so that I can separate the code and not have conditional statements in the default controller.
I've found a bunch of examples that describe how to do this in code but I can't figure out how to do it using Interface Builder.
I've tried dragging a new viewcontroller into my xib and setting the custom class to MySearchViewController and then dragging outlets from the SearchDisplayController as hinted at here: http://goo.gl/RgmwG
I've also tried dragging an Object into the objects column and changing this class to MySearchViewController.
But I feeling completely lost and really just trying things randomly. I'm guessing that I also need to create a property/IBOutlet for the SearchDisplayController somewhere but again lost.
If anyone has a reference to how to go about this I'd be so happy!
Like most problems, it seems pretty obvious in retrospect.
Add an 'object' placeholder in interface builder (orange cube).
Change the objects custom class to the class you want to be the delegate - e.g. MySearchViewController
Remove the default outlets from the standard SearchDisplayContoller to connect with the MySearchViewController object (see screenshot)
Make sure that the new delegate has an outlet to a parent view (in my case View)
Make sure that the delegate class is initiated from somewhere
// I did this from the parent ViewConroller, but probably better from the main app delegate?
#property (strong, nonatomic) IBOutlet MSSearchViewController *searchViewController;
Hope this helps someone else who was also stuck!

Resources