Skinning and caching user preferences - iphone

I have an application which allows customizing attributes such as background color, buttons, text (ie, titles), etc. In its current incarnation, viewDidLoad set the appropriate property on a UI widget by calling into a LookAndFeel class. LookAndFeel reads the user preferences.
Should each view perform a call into LookAndFeel, or should the Application fetch an attribute once and use the fetched value in all views? Is it OK to call getTitleColor once, hold it in the app delegate, and use it in every view?

That depends on how expensive your getTitleColor method is. If it's expensive, it should definitely be cached.
(Note: reading from a file or from NSUserDefaults could be considered expensive)

Related

Need of Delegation in iPhone Development or Objective C

What is the need of delegation in iphone/ipad development or objective C?
I read so many articles on it. All were telling how to implement the concept, but no one was telling why we need to implement that, in which case we should implement it.
Suppose you want to implement Login functionality in your app ... now you won't show Login screen every time you run your app.. only when it is first started and you don't have a login and password...
So in this case..
Your app starts :
View 1 loads (default view )
You check no Login name is there..
You load a new view..(Login View ) .
User enter his details..you get your login and password...
now you want to go back to default view and load the main app with
the names the user entered in Login View....
Now you will use delegate to pass these information(login details) back to default View..so that it knows..its details. now there are many different ways to do these things...like notification and singleton classes.. but when you want to sent more than 3-4 sets of data.. it is best to use delegates
Think of all the components that iOS and Cocoa provide you with. TableViews, TextFields, PopOvers...etc.
When the developers wrote these components, they couldn't possibly know all the various implementations that us developers were going to create using these components. But we need somehow to communicate with them in a generic way.
These components use delegates. The delegate is an implementation independent way of describing some behaviour that your component can conform to.
When UITableView need to find out what is the height of the rows, the UITableView only needs to know about UITableViewDelegate. It doesn't need to know about MyTableViewController, JohnsTableViewController, BobsTableViewController... etc.
So the delegate is decoupling the component from the implementation and the type.
Decoupling is a good thing. It makes maintaing and changing code a lot easier, and makes code reusable.
Delegation is a simple and powerful pattern in which one object in a
program acts on behalf of, or in coordination with, another object.
The delegating object keeps a reference to the other object—the
delegate—and at the appropriate time sends a message to it. The
message informs the delegate of an event that the delegating object is
about to handle or has just handled. The delegate may respond to the
message by updating the appearance or state of itself or other objects
in the application, and in some cases it can return a value that
affects how an impending event is handled. The main value of
delegation is that it allows you to easily customize the behavior of
several objects in one central object.
SOURCE
Use a delegate if you want to talk to only one object. For example, a
tableView has a delegate - only one object should be responsible for
dealing with it.
Use notifications if you want to tell everyone that something has
happened. For example in low memory situations a notification is sent
telling your app that there has been a memory warning. Because lots of
objects in your app might want to lower their memory usage it's a
notification.
this was an answer posted to my question here
There are two key benefits of delegation: customizing objects without subclassing, and improving encapsulation.
Customization without subclassing is a benefit you get from many of the Cocoa and Cocoa-Touch APIs using the delegate pattern. If they didn't do so, you might have to subclass a UITableView every time you wanted to change its behavior by using different types of cells or a different data source. Instead, you just set the table view's delegate and data source to customize its behavior.
As for encapsulation, the delegate pattern helps you keep the different components of your code separate. For example, if your custom View needs to have some data, it would be bad practice to simply give it access to your Model, or even full access to your Controller. Instead, you'd probably set up some kind of delegate protocol for your View that your Controller would implement. That way your classes know no more about each other than they need to, so that changes in one part would be less likely to break others.

Block UITabBarController while contents of a view controller not been charged

I'm doing an app that uses a TabBarController and each Tab uses its own navigation controller.
The app has dynamic content and I use viewDidDisappear viewDidAppear methods to create or destroy the objects that I need each time I enter or exit into the ViewController.
My problem is when I start to sail very fast and I don't give time to load the Threads that I use for uploading content such as XML peta app or destroy objects when I leave the ViewController.
How I could control the tabs of the navigationbar or tabbarviewcontroller for not respond until the viewcontroller has loaded all contents?
Excuse me if I'm not well expressed. Thanks!
No matter you use synchronous request or asynchronous request, just show an UIAlertView while loading the data. This will both serve as a notification to the user that something is being loaded, and the it will block the interactions with all the other views on the screen.
As others have suggested in comments, I believe that what you want to do is rearrange the order in which things are triggered. Perhaps something like this:
On viewWillAppear:, clear (or disable or whatever is appropriate) your objects that are no longer valid and begin the load-new-content thread. Perhaps display a UIActivityIndicator or similar.
On viewWillDisappear:, tell the load-new-content thread that it can stop, its results are no longer needed. If you put up an activity indicator, take it down.
At the end of the load-new-content thread, take down any activity indicator, update the UI with the new contents and activate.
I don't really see any way around this -- if the UI is not valid until the new content is loaded, then you have to wait for it.
Another solution might be to cache the contents from the previous fetch, and always display those on viewDidLoad. Then, at the end of your new-content-thread, cache the new contents, and update the UI.

Saving the state of a view after action executes

I was wondering how you would save the state of a view after it runs an action that leaves for another view then comes back?
Please Help
Store state variables in NSUserDefaults or use NSArchive / sqlite database. Depends on what kind of state information you wish to store. Always assume your previous view will 'unload' if a new view is loaded (using presentModalView or the UINavigationController). This way you're always prepared for the worst. Under low memory conditions the view currently not visible gets its 'view' unloaded and thus you must recover your previous state yourself (you could even simply use class variables if the first view isn't destroyed).

Custom Delegates

I've read in a number of places that using the AppDelegate as the heart of the application is bad (apart from the actual UIApplication delegates themselves).
Would it be wise to create custom delegate classes to keep code modularized.
For example if I need to format various text inputs, create a Formatter delegate class and set the delegate on any text input object that needs to be formatted?
Does that make sense?
The point of the articles you've read is 'Do not keep all application logic in app delegate'. Responsibility of app delegate is to handle important events in app lifecycle in lightweight way by notifying appropriate parts of application, not to manage views or data flows or network calls. For example in application:didFinishLaunchingWithOptions: delegate usually adding root controller's view into window, makes this window active and leaves everything else to controller.

access UISwitch setting from a different view?

k, I'm new to this so apologies all around, generally.
I'm trying to access the UISwitch value (on or off) from a different view and class and can't make it work.
It's a simple 2 view app. Main view and the second is a preference menu.
trying to write an if/else method to play sound when the switch (on the other view) is on and not when its off.
I cant seem to make it work. Any thoughts or some syntax examples would really help me out.
Thanks.
As Matt Wilding said "it's not good form to access UI components of one view controller from another...".
Instead of accessing the view object, when the switch state is changed by the user you save the status into NSUserDefaults as preference value. Whenever you want, you can access the switch status value through the preferences.
I'm going to take what I think you're trying to accomplish here and suggest an alternative approach. You want to have a preference in your app (assumed from "preferences menu") that allows the user to set something like whether or not you app plays background music. (May not be exact, this is just for clarification).
Typically, in a well designed app, the flow is driven by the data, with the UI reflecting the state of the data model and the controllers coordinating the two layers. What you are suggesting is to have your application play music based on the state of the UI, which is not backed by any data model. This cuts out the model level, and as you noticed, can lead to awkward attempts at communicating between the UI of different controllers for information.
Things like application preferences are typically stored in a nifty .plist file that is managed through the NSUserDefaults class. This would be a great place for the data level tracking of your preference. In this situation, the UISwitch would represent the state of the flag in the settings file, and changing the value of the switch would change the value in the file. Anywhere else in your application that you need to know if the play-sound-flag is set, you reference the data model info instead of the UI. This decouples the view controllers from each other, which is a good thing.
For this purpose add selector for swith and make NSInteger property in app delegate.Like the followed
[
yourSwitch addTarget:self action:#selector(switched:) forControlEvents:UIControlEventValueChanged];
-(IBAction) switched: (id)sender
{
int state=0;
if(yourSwitch.on)
state=1;
else
state=0;
objAppDelegate.switchState=state;
}
then you need to access this appDelegate property in second view where you are playing sound
then according to this value you can do what you want and for making object of appDelegate class you need this line
YourAppDelegateClass *objAppDelegate=(YourAppDelegateClass *)[[UIApplication sharedApplication] delegate];
ok if you have any other doubt then you can ask.