-
mySettings: A Settings API for the iPhone
Posted on March 20th, 2009 68 commentsNB: Unfortunately I am not able to do any more development on this or any other projects. I am hoping that someone else will take over the project and update it. There is also this similar project.A lot of iPhone apps have their own settings views similar to the ones in the Settings App on the iPhone home screen. But to my surprise I couldn’t find any general API for it. So I made my own and published it here. It uses a plist configuration file like the one used by the Settings App, with some added options (and some removed ones, but they will hopefully be implemented in the near future).
In a nutshell it takes a plist like this:
and turns it into this:

Features
- Text fields, on/off switch button, integers and time intervals (with maximum/minimum values and custom format string for the integers).
More options are needed, obviously, like dates and select lists. Feel free to help out if there are other options you would like to see implemented. - Titles can be indented.
- By default the settings themselves are stored in the standard user defaults object ([NSUserDefaults standardUserDefaults]), but you can use any object that supports key-value coding. This enables you to use your model classes directly in the settings view.
- And if you don’t find blue pyjama stripes exciting, you can of course change the table view background.
And that’s it for the time being. A work in progress, obviously. I would also like to see support for custom table cells and dynamically filling a section with the contents of an array or a dictionary. And localisation. And sliders. And customising fonts and colours. And lots more cool stuff. So if you want to check it out, follow these instructions. And if you make any changes please let me know so I can merge them back into the repository.
67 responses to “mySettings: A Settings API for the iPhone”

-
Great idea.
If you host the source on a place like github you might get more feedback / contributions back.
-
How do you get a text editing cell to scroll up from behind the keyboard? Mine stay right where they are when the keyboard slides up, but yours do the right thing even when the cell being edited is at the bottom of the table. And I can’t see where on earth it is you’re making that happen
-
Thanks. That’s rather inconvenient if your table is mixed in with other views
But scrolling the target cell to table bottom and moving table bottom to the keyboard top works nicely it seems.
-
Do you have an example of scrolling a text field up when a field is under the keyboard?
Thanks for this. Would you consider writing it up as a recipe for http://www.iphonerecipesbook.com ? We would love to include it in our book.
-
-
I’ve added support for IsSecure:
- (void) setConfiguration:(NSDictionary *)config {
if ([[config objectForKey:@"IsSecure"]boolValue] == YES) {
valuetextfield.secureTextEntry = YES;
}
[super setConfiguration:config];
} -
JJade June 12th, 2009 at 16:59
First, I would like to say that this is a very nice code for generating a settings menu.
I am, however, having one small issue. I am trying to use this within a tab in a tab bar. When i click on a cell that pushes a view with a picker on it, the bottom of the picker is cut off by the tab bar. How can i reposition the PickerView??
-
Hey! You did a good job and saved me a lot of time although it would be good to have some _useful_ documentation. Nevertheless I managed to make it work for me like I need.
Here are the differences I noticed from the native Settings:
1. Highlighted color is not white.
2. You can select Toggle cells and it will give you a pesky blue blink.Here are the steps to make your Settings screen really authentic (I’m too busy to get myself deeply into that open-source collaboration):
1. Go to SettingsCell.m and set highlightedTextColor to [UIColor whiteColor] where appropriate.
2. Go to ToggleCell.m and set selectionStyle to *None.
Now nobody will ever find a difference. Hopefully this applies to Eclipse license since I’ve shared my changes.
Thanks again,
– Alex -
Jason Booth August 5th, 2009 at 05:15
Hey, this is awesome. Thanks for posting it, I was looking for something like this, as it’s such a pain to hook up these types of UI’s by hand. That said, a few things:
I added support for sliders, I can submit the code back if you’d like.
I got this working in my current app, but I’d like to use it for more than just NSDefaults. In fact, I’d like to have several different UI’s constructed in this manner, each with their own object holding the current data. I noticed you can pass in a settings object which has to be KVO complient, but I’m not really sure how I go about creating such a thing. Any help is appreciated!
-
Jason Booth August 6th, 2009 at 13:12
Ok, quick update on the slider. My default implementation works just fine, but if you have a bunch of sliders on the page with different labels, they all end up with different sizes. So I think I’m going to add an option to specify the size you require in the plist file. The default behavior will be to use the maximum size available. I’ll send you the files tonight, most likely..
Also, I was wondering if you had some thoughts on making the system a little more general. As an example, one of my current UI’s features a table view of sliders inside a view with additional UI elements. Using mySettings has a few issues here that I’d like to fix, mainly:
1. It doesn’t respect size correctly (it always thinks the view your in is the full screen).
2. I’d like a way to get a callback when any value is changed in the UI, since my UI needs live updating. Is there a good central place to add this? It would be nice if SettingEditorViewController got a ‘valueChanged’ call with the key name when any value is changed. Then I could simply subclass the SettingsEditorViewController and do whatever updating I need when a value is changed..
3. I also want to add a button control. The cell side of this is no problem, but I’ll need a way to call a selector as stored in the plist. I’m thinking the SettingsEditorViewController could also have a ‘OnButtonPressed’ function which gets the key name to make that easy..
Thoughts? Do these seem like changes you’d be interested in having in the trunk, or more of my own branch? As you can see, I’m trying to use this for more than just settings UIs – and it’s almost there. I want to turn this into a more generic property editor for class data.
-
Jason Booth August 6th, 2009 at 16:35
Oh yeah, one more thing. I’m going to want to be able to push a new KVO object into the UI and have the controls update to the new values without removing and re-creating the UI.
-
Jason Booth August 6th, 2009 at 23:02
Yes, I mean SettingsViewController.
That said, I’m not sure I totally follow. Right now I’m constructing SettingsViewController with a plist and NSMutableDictionary and adding it to a view in my scene (which is loaded from a nib).
How would I have the ViewController create the SettingsViewController?
On the second point, is there a function that always gets called when a value is edited in SettingsMetadataSource (which I assume is what you mean by SettingsMetadataController)? It didn’t look like there was. Wouldn’t I have to call it from the valueChanged functions of the cells?
The third one was just what I was thinking as well.
-
Jason Booth August 7th, 2009 at 04:14
ok, so what I’ve done is to add a UIViewController pointer to SettingsCell, and after a cell is created it gets set to be the UIViewController which is stored by the SettingsMetadataSource. Slider and Toggle both have an valueChanged function, so I’m simply calling the UIViewController’s onValueChanged function there for now.
However, this will always produce a compiler warning because UIViewController doesn’t necessarily have that function on it. Can I get rid of this warning by creating a @protocol that my ViewController implements (with this function in it)? I’m not extremely familiar with the objective C side of things yet.
Now, for controls without the valueChanged function (basically, everything else), it would be nice to prevent them from triggering a message every time you scroll and cells get reused. Any ideas on that front?
-
Jason Booth August 7th, 2009 at 05:14
Spoke too soon. I got the warning to go away by adding a new delegate class SettingsViewControllerDelegate. This will have the onValueChanged and onButtonPressed functions for you to implement in your controller class if you need that functionality. Both of these functions receive the key so you know which property was changed. Hmm, should I send the new value as well? Might be handy..
Oh, the slider now has a FixedSize key on it which allows you to set the exact size of the slider, so if you have several in a row they can line up nicely. If not specified, it auto sizes.
I also got the button working in a remedial way. There are a lot of options on a button, but I think I’ll restrict it to just rounded or custom buttons. I’ll allow you to specify images and text for all of the states, and allow a fixed or automatic sizing for text based buttons. Image based ones will attempt to use the image size.
I haven’t started on refreshing the data when it changes outside of the controller, but it sounds like that will be pretty straight forward.
Hopefully I’ll finish this up tomorrow and be able to drop you some code. Then we can talk about any changes it needs before being final.
BTW, I have a color picker class we could integrate into this if we want color editing support. It’s a real color picker, with spectrum and HSL selection, etc. It needs some more love to be final, but it might be a nice thing to integrate down the line.
-
Great work on this! It’s an excellent idea and has great execution.
I wanted to suggest adding this little bit to SettingsViewController.m:
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super initWithCoder:decoder]) {
settingsdatasource = [[SettingsMetadataSource alloc] initWithConfigFile:[[NSBundle mainBundle] pathForResource:@”Root” ofType:@”plist”]];
[self setup];
}
return self;
}This allows you to instantiate the view controller using only Interface Builder – just throw a UIViewController in and give it a class of SettingsViewController. This bit of code would just use “root.plist”… it would be great to have an interface builder field to enter in custom plists, but getting into IB plugins is a bit beyond my present desires
-
Hi,
Thanks for posting this library. Can someone advise me on how I can use the mysettings to get the ns default settings to display within a UITableView contained in a FlipsideView instead of of the view in your sample code? Any help would be appreciated.
Thanks
-
Can you share some sample code to do what you mentioned? I’m a little confused.
In my FlipSideViewController.h I have defined:
UITableView *tvSettings;In viewDidLoad of FlipSideViewController.m,
tvSettings = [[UITableView alloc] initWithFrame:CGRectMake(0,44,self.view.bounds.size.width,self.view.bounds.size.height-44)];
tvSettings.delegate = settingsdatasource;
tvSettings.dataSource = settingsdatasource;[self.view addSubview:tvSettings];
-
Do you support the slider control (PSSliderSpecifier plist type) in your mysettings api? If so, how can I read and render it in a UITableView?
-
-
I finally got my settings for my app to show. One problem I’m seeing now if I select a multi-value field by clicking on the > button, it just highlights the row, but it doesn’t display them. Any advice on how I can get this working?
-
Hi ZAP,
can you share your solution for a FlipSideViewController please?
Regards
Alex -
pwrmongr November 11th, 2009 at 06:26
How did you solve the problem to selecting a multi-value field by clicking on the > button, and it just highlighting the row????
-
pwrmongr November 12th, 2009 at 05:36
FlipsideViewController.m
#import “FlipsideViewController.h”
#import “SettingsViewController.h”
@implementation FlipsideViewController
@synthesize delegate;
@synthesize settingsViewController;- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];
NSString *plist = [[NSBundle mainBundle] pathForResource:@”Root” ofType:@”plist”];
myTableOfSettings = [[UITableView alloc] initWithFrame:CGRectMake(0,44,self.view.bounds.size.width,self.view.bounds.size.height-55)];
myTableOfSettings.delegate = settingsdatasource;
myTableOfSettings.dataSource = settingsdatasource;[self.view addSubview:myTableOfSettings];
}This shows my settings and allows for items like ‘PSToggleSwitchSpecifier’ to work. However, items with ‘PSMultiValueSpecifier’ only highlight and do not go to the selector screen.
-
-
Jason Booth August 19th, 2009 at 16:59
I submitted some classes to add sliders and buttons to mysettings a little while back. Not sure if it’s made it into the trunk yet though..
-
Hi Kare, great little library – much appreciated.
FYI… I’ve made a small change locally so that the settings are saved in [SettingsViewController viewWillDisappear] rather than [SettingsViewController viewDidDisappear].
The problem was my view, which appears when the settings are closed, looks different depending on the save settings. So having the save done *after* the settings view has disappeared (and my view is displayed) was too late.
Keep up the great work.
Cheers, Sheldon.
-
>>>>This is a good idea, but requiring that it use root.plist is too limiting. To enter the name of the plist in Interface builder would definitely be the best option, but IB plug-ins is beyond my present desires and skills as well I’m afraid. Hopefully someone with more experience in Interface builder can help us out here.
Unfortunately that is not possible. I’m using Settings.plist for my purpose though.
-
Please, replace SettingsMetadataSource::dealloc with the following code:
- (void) dealloc {
[sections release];
[sectiontitles release];
[changedsettings release];
[settings release];
[super dealloc];
}Making [super dealloc] first lead to EXC_BAD_ACCESS, when used separately.
-
Updated. Now see that it is already there. Cool. However I cannot get one thing working. I have a BOOL key, that can be changed in Settings and in some other screens. The screen doesn’t update itself when this value changes, also when I’m trying to regenerate the SettingsMetadataSource in viewWillAppear, I’m starting to get odd exceptions about “not KVO object”, “cannot find key Key”, and so on. Can you help how to implement that? I’m using a custom Settings controller, but for now it fully copies your SettingsViewController.
-
Ok, after some experiments finally found how to make it update.
This construction in SettingsViewController will help:
- (void)viewWillAppear:(BOOL)animated {
[super viewDidLoad];
[self.tableView reloadData];
}Now can go to sleep safely.
-
-
I know this could be a dumb question, but I have very little experience in Xcode.
I followed the instructions on how to add mySettings to my project, but how do I use SettingsViewController? I can’t just import it using #import “SettingsViewController.h”…
-
Kare,
It was very odd for me to find out that SettingsEditorViewController lost its striped background. Had to get it back. Doesn’t it make sense to leave it stripe to comply with native Settings? -
Was latest on the 14th September. I don’t like to update because I have my customizations and each new update breaks them.
-
I already repaired.
Found the place where you set the background of the table to [UIColor clearColor] and removed that line. -
Do you think it is a good idea to foreward all files and class with some abbreviation, say, PS*? We should have an easy way to differentiate classes from different packages. SettingsViewController is a very common name for example. If I do it myself, I won’t be able to update easily anymore.
-
Done. Now my code is fully incompatible with your code. Sorry.
-
-
Then it will be even a better idea to base your changes on my current revision.
It’s your latest revision + PS* prefix + keyboard type // capitalization type for text-fields + certain types of cells are not selectable imitating native Settings (text-field and toggle-switch for example). Please, tell me where I can send sources to. Or better drop me a mail to my box, I’ll reply with a ZIP with sources. -
Hi, great project!
I’ve run into an issue – I have my Root.plist file inside a Settings.bundle. mySettings only works if I copy the Root.plist outside the bundle, but I’d prefer to not have to maintain it in two places. Is there something I can modify to tell it to search a different path? thanks-
There is an easy way to fix this. It’s not a good idea to have both external and internal settings. Once you fix your app design your question will be eliminated.
-
-
Thanks for the excellent code!
Has there been a button cell submitted yet or a sample anywhere of this functionality? It seems like someone could extend your custom cell with a label to respond to touches, or some other simple solution for this. Thanks! Jake -
I’ve writing an email to Kate.
In this email i’ve inculded a FlipView sample.
The sample are avaiable in http://office.azero.it/download/mySettingFlip.zipPlease Kate, help the community. Your job is very appreciate and good.
p -
John Blanco November 24th, 2009 at 18:09
I’m having an issue. When I have a setting that uses a MultiValue table, when I go there and select something other than the default and hit back, the row still shows the old value.
On top of that, if I scroll down, then scroll back, when that row is about to come into view the screen suddenly transitions to the multi value selection for it again. This issue I see the problem in the code (setSelected does this, but should not — it should only be handled on didSelect)
I have spent a day debugging this. What I’ve found is changedsettings is null when the MultiValue cell is supposed to be setting the new value. So it never gets set.
Anyone else seeing this?
-
John Blanco November 24th, 2009 at 20:34
Found the issue. This needs to be added to SettingsEditorViewController#initWithCell:andDelegate:
cell.changedsettings = originalcell.changedsettings;
Also, I had to use a UINavigationControllerDelegate to make sure the SettingsViewController is refreshed when navigated to for changing values like this.
Very weird, in the default project, this worked. But it doesn’t work in my project. Any clue as to why?
-
-
I love this product–or at least, I think I do–but I have to say the lack of documentation is a real killer. It’s nearly impossible to figure out what is and what is not possible.
(I’m not missing anything, am I? I haven’t run across anything that really specs out the features and how to use them.)
My recommendation: take a break from adding features and write some docs/tutorials. At this point, it’s the biggest stumbling block to adoption.
-
embedded February 24th, 2010 at 22:14
Hi
thanks for the great kit.
Has anyone managed to get UITableViewStyleGrouped tableview when loading the SettingsViiewController from IB?
Thanks
-
Very nice, this saved a bunch of time.
I added a “StepValue” to the IntegerPickerView so that if min = 100 and max = 150 and step = 10, the picker would display 100, 110, 120, 130, 140, and 150. Very easy, but I am not sure how to ensure the default value of StepValue is 1.
1 Trackbacks / Pingbacks
-
mySettings: A Settings API for the iPhone…
You’ve been kicked (a good thing) – Trackback from iPhoneKicks.com – iPhone SDK links, community driven…
Leave a reply
- Text fields, on/off switch button, integers and time intervals (with maximum/minimum values and custom format string for the integers).



Kare March 25th, 2009 at 23:52