(Created a subsection for each cell type with accompanying table if appropriate, reordered keys to appropriate tables and Recipes section, removed dependencies to avoid redundancy, added to-do's, formatted code snippets, rephrased to be more direct) |
m (Link to CepheiPrefs' wiki page instead of docs) |
||
(62 intermediate revisions by 15 users not shown) | |||
Line 1: | Line 1: | ||
This document provides the specification of the | This document provides the specification of the dictionaries that specify the layout of an iOS preference pane. These can be supplied statically via .plist files or dynamically via the <code>_specifiers</code> ivar in a subclass of [[PSViewController]]. | ||
== Root level == | == Root level == | ||
Line 11: | Line 11: | ||
| entry || colspan="2" | dictionary || Specifier-like dictionary. || - | | entry || colspan="2" | dictionary || Specifier-like dictionary. || - | ||
|- | |- | ||
| title || string || localizable string || Title of the preference pane. || | | title || string || localizable string || Title of the preference pane. || ''entry'' ≠ nil | ||
|- | |- | ||
| items || array || ... of specifiers || Array of specifier dictionaries. || - | | items || array || ... of specifiers || Array of specifier dictionaries. || - | ||
|} | |} | ||
The ''title'' key is used only for the root plist, otherwise, the ''label'' value from the specifier that pushed the new pane is used. | |||
== Specifier Keys and Values == | == Specifier Keys and Values == | ||
Line 25: | Line 27: | ||
Must be one of the following: | Must be one of the following: | ||
* PSButtonCell | * [[Preferences_specifier_plist#PSButtonCell|PSButtonCell]] | ||
* PSEditTextCell | * [[Preferences_specifier_plist#PSEditTextCell_.26_PSSecureEditTextCell|PSEditTextCell]] | ||
* PSEditTextViewCell | * [[Preferences_specifier_plist#PSEditTextViewCell|PSEditTextViewCell]] | ||
* | * [[Preferences_specifier_plist#PSGiantCell|PSGiantCell]] | ||
* | * [[Preferences_specifier_plist#PSGiantIconCell|PSGiantIconCell]] | ||
* PSGroupCell | * [[Preferences_specifier_plist#PSGroupCell|PSGroupCell]] | ||
* PSLinkCell | * [[Preferences_specifier_plist#PSLinkCell|PSLinkCell]] | ||
* PSLinkListCell | * [[Preferences_specifier_plist#PSLinkListCell_.26_PSSegmentCell|PSLinkListCell]] | ||
* PSListItemCell | * [[Preferences_specifier_plist#PSListItemCell|PSListItemCell]] | ||
* PSSecureEditTextCell | * [[Preferences_specifier_plist#PSEditTextCell_.26_PSSecureEditTextCell|PSSecureEditTextCell]] | ||
* PSSegmentCell | * [[Preferences_specifier_plist#PSLinkListCell_.26_PSSegmentCell|PSSegmentCell]] | ||
* PSSliderCell | * [[Preferences_specifier_plist#PSSliderCell|PSSliderCell]] | ||
* PSSpinnerCell | * [[Preferences_specifier_plist#PSSpinnerCell|PSSpinnerCell]] | ||
* PSStaticTextCell | * [[Preferences_specifier_plist#PSStaticTextCell|PSStaticTextCell]] | ||
* PSSwitchCell | * [[Preferences_specifier_plist#PSSwitchCell|PSSwitchCell]] | ||
* PSTitleValueCell | * [[Preferences_specifier_plist#PSTitleValueCell|PSTitleValueCell]] | ||
The cell type is determined from the class method {{ObjcCall|PSTableCell|ClassMethod=1|cellTypeFromString:}}. | The cell type is determined from the class method {{ObjcCall|PSTableCell|ClassMethod=1|cellTypeFromString:}}. | ||
Line 54: | Line 56: | ||
| label || string || localizable string || Label of specifier. || - | | label || string || localizable string || Label of specifier. || - | ||
|- | |- | ||
| defaults || string || bundle ID || | | defaults || string || bundle ID || User defaults associated with this specifier. || - | ||
|- | |- | ||
| key || colspan="2" | string || Key of the user defaults. || ''defaults'' ≠ nil | | key || colspan="2" | string || Key of the user defaults. || ''defaults'' ≠ nil | ||
Line 62: | Line 64: | ||
| id || colspan="2" | string || Specifier ID. || - | | id || colspan="2" | string || Specifier ID. || - | ||
|- | |- | ||
| | | hasIcon || colspan="2" | boolean || Whether the specifier will have an icon. || ''bundle'' ≠ nil | ||
|- | |||
| icon || string || filename || File name of the icon to use. Default value is <tt>icon.png</tt>. The height of the icon should be 29px. || ''hasIcon'' = true | |||
|- | |||
| get || string || selector || Getter. || - | |||
|- | |- | ||
| set || string || selector || Setter. | | set || string || selector || Setter. || - | ||
|- | |- | ||
| enabled || colspan="2" | boolean || Whether the control is enabled by default. || - | | enabled || colspan="2" | boolean || Whether the control is enabled by default. || - | ||
|- | |- | ||
| height || colspan="2" | | | height || colspan="2" | real || Height of the cell. || - | ||
|- | |- | ||
| PostNotification || colspan="2" | string || Darwin | | PostNotification || colspan="2" | string || Darwin notification string to be posted when a change happens. || - | ||
|- | |- | ||
| detail || string || class name || [[PSDetailController|Detail controller class]]. || - | | detail || string || class name || [[PSDetailController|Detail controller class]]. || - | ||
Line 80: | Line 86: | ||
| dontIndentOnRemove || colspan="2" | boolean || Prevents the cell from being indented when the table view is in editing mode. || - | | dontIndentOnRemove || colspan="2" | boolean || Prevents the cell from being indented when the table view is in editing mode. || - | ||
|} | |} | ||
''Investigate hasIcon key dependency since all but PSGroupCell display an icon if supplied.'' | |||
Keys apply to all cells unless otherwise stated in their respective subsection. | Keys apply to all cells unless otherwise stated in their respective subsection. | ||
Signature and default methods for the set and get selectors: | |||
* <code>-(void)setPreferenceValue:(id)value forSpecifier:(PSSpecifier*)specifier;</code> | |||
* <code>-(id)readPreferenceValue:(PSSpecifier*)specifier;</code> | |||
=== PSButtonCell === | === PSButtonCell === | ||
Line 136: | Line 148: | ||
|- | |- | ||
| isNumeric || colspan="2" | boolean || Input field intended for entering numbers (Use NumberPad keyboard). || - | | isNumeric || colspan="2" | boolean || Input field intended for entering numbers (Use NumberPad keyboard). || - | ||
|- | |||
| isDecimalPad || colspan="2" | boolean || Input field intended for entering decimal numbers (Use DecimalPad keyboard). || - | |||
|- | |- | ||
| isEmail || colspan="2" | boolean || Input field intended for entering e-mail (Use EmailAddress keyboard). || - | | isEmail || colspan="2" | boolean || Input field intended for entering e-mail (Use EmailAddress keyboard). || - | ||
Line 148: | Line 162: | ||
|} | |} | ||
''To do: Check "prompt", "okTitle" and "cancelTitle" as they appear to not work on iOS 6. Are these in the correct place?<br>Check what "suffix" does. Find "bestGuess" selector signature. Solve the | ''To do: Check "prompt", "okTitle" and "cancelTitle" as they appear to not work on iOS 6. Are these in the correct place?<br>Check what "suffix" does. Find "bestGuess" selector signature. Solve the mystery of "isEmailAddressing".'' | ||
=== PSEditTextViewCell === | === PSEditTextViewCell === | ||
This specifier doesn't show a label so it is recommended to use a previous specifier to indicate what this | This specifier doesn't show a label so it is recommended to use a previous specifier to indicate what this specifier represents. | ||
The text area expands to fit the whole cell, so setting a height key will provide more space to write. | The text area expands to fit the whole cell, so setting a height key will provide more space to write. | ||
Saved value is HTML text, <tt><div></tt> being the root tag block. | |||
=== PSGiantCell === | |||
This specifier doesn't show a label so it is recommended to use a specifier before this one to indicate what this specifier represents. | |||
=== PSGiantIconCell === | === PSGiantIconCell === | ||
This specifier uses the ''label'' key as text content. | |||
The font in this cell is bigger than normal. | The font in this cell is bigger than normal. | ||
''To do: Find out the actual font and icon sizes.'' | ''To do: Find out the actual font and icon sizes.'' | ||
=== PSGroupCell === | === PSGroupCell === | ||
Line 176: | Line 194: | ||
| footerAlignment || integer || 0:left; 1:center; 2:right; defaults to 1. || - | | footerAlignment || integer || 0:left; 1:center; 2:right; defaults to 1. || - | ||
|- | |- | ||
| headerCellClass || | | headerCellClass || string || The class name to use for the header. || - | ||
|- | |- | ||
| footerCellClass || | | footerCellClass || string || The class name to use for the footer. || - | ||
|- | |- | ||
| isStaticText || boolean || Whether the cells in this group | | isStaticText || boolean || Whether the cells in this group have static text. || - | ||
|} | |} | ||
If you want to make a Image Header read [http://cpdigitaldarkroom.com/2014/03/adding-a-image-header-to-your-tweaks-settings-pane this]. Hides the group title (<code>label</code> key). | |||
<code>isStaticText</code> is used in conjunction with PSStaticTextCell. | |||
''To do: Research "isStaticText" interaction with "PSStaticTextCell".'' | ''To do: Research "isStaticText" interaction with "PSStaticTextCell".'' | ||
Line 200: | Line 222: | ||
|- | |- | ||
| pane || string || class name || Edit pane class.<br />If ''bundle'' is absent, the edit pane class is obtained from the current bundle.<br />Default value is [[PSEditingPane]]. || ''detail'' ≠ nil | | pane || string || class name || Edit pane class.<br />If ''bundle'' is absent, the edit pane class is obtained from the current bundle.<br />Default value is [[PSEditingPane]]. || ''detail'' ≠ nil | ||
|- | |- | ||
| customControllerClass || string || class name || Custom controller class to use when the view become visible || - | | customControllerClass || string || class name || Custom controller class to use when the view become visible || - | ||
Line 213: | Line 231: | ||
If none of these keys are specified, the framework will try to load a plist using the label text as name. | If none of these keys are specified, the framework will try to load a plist using the label text as name. | ||
=== PSListItemCell === | |||
This specifier makes use of the <tt>get</tt> key to get the value in the runtime. | |||
=== PSLinkListCell & PSSegmentCell === | === PSLinkListCell & PSSegmentCell === | ||
Line 224: | Line 246: | ||
| validTitles || array || ...of localizable strings || Titles corresponding to the list of values. || - | | validTitles || array || ...of localizable strings || Titles corresponding to the list of values. || - | ||
|- | |- | ||
| shortTitles || array || ...of localizable strings || Short titles. || - | | shortTitles || array || ...of localizable strings || Short titles corresponding to the list of values, displayed in the link cell. || - | ||
|- | |- | ||
| valuesDataSource || string || selector || Selector to call to get the list of values dynamically. || ''validValues'' = nil | | valuesDataSource || string || selector || Selector to call to get the list of values dynamically. || ''validValues'' = nil | ||
Line 230: | Line 252: | ||
| titlesDataSource || string || selector || Selector to call to get the list of titles dynamically. || ''validTitles'' = nil | | titlesDataSource || string || selector || Selector to call to get the list of titles dynamically. || ''validTitles'' = nil | ||
|- | |- | ||
| staticTextMessage || string || localizable string || The message to be added below the cells list of | | staticTextMessage || string || localizable string || The message to be added below the cells list of PSListItemsController. || ''cell'' = "<tt>PSLinkListCell</tt>" | ||
|} | |} | ||
Line 240: | Line 262: | ||
In order to make a PSLinkListCell actually work like a list, you must supply the key-value pair | In order to make a PSLinkListCell actually work like a list, you must supply the key-value pair | ||
detail = PSListItemsController; | detail = PSListItemsController; | ||
=== PSSliderCell === | === PSSliderCell === | ||
Line 249: | Line 269: | ||
! key !! colspan="2" | type !! meaning !! depends | ! key !! colspan="2" | type !! meaning !! depends | ||
|- | |- | ||
| min || colspan="2" | | | min || colspan="2" | real || Minimum value of slider. || - | ||
|- | |- | ||
| max || colspan="2" | | | max || colspan="2" | real || Maximum value of slider. || - | ||
|- | |- | ||
| showValue || colspan="2" | boolean || Show the value. || - | | showValue || colspan="2" | boolean || Show the value. || - | ||
|- | |- | ||
| | | isContinuous || colspan="2" | boolean || Change the value by steps. Possibly deprecated. || - | ||
|- | |||
| isSegmented || colspan="2" | boolean || Change the value by steps. || - | |||
|- | |||
| segmentCount || colspan="2" | integer || Steps count. || - | |||
|- | |- | ||
| leftImage || string || filename || Image displayed next to the slider on the left. || - | | leftImage || string || filename || Image displayed next to the slider on the left. || - | ||
|- | |||
| rightImage || string || filename || Image displayed next to the slider on the right. || - | |||
|} | |} | ||
This specifier doesn't show a label so it is recommended to use a previous specifier to indicate what this specifier represents. | This specifier doesn't show a label so it is recommended to use a previous specifier to indicate what this specifier represents. | ||
Image files must reside in the same directory. They can be symlinks to files elsewhere though. If <code>showValue</code> is set to true it might overlap with the right image. | |||
''To Do: figure out if the step is a constant or a proportion (1/10? 1/16?) of the slider range.'' | |||
=== PSSpinnerCell === | === PSSpinnerCell === | ||
Line 269: | Line 297: | ||
=== PSStaticTextCell === | === PSStaticTextCell === | ||
This specifier uses the ''label'' key as text content. | |||
=== PSSwitchCell === | === PSSwitchCell === | ||
Line 283: | Line 313: | ||
|} | |} | ||
You can dynamically set the UISwitch's state by returning YES or NO in the get method. When the switch's state changes, the set method is called. | |||
See [[Preferences_specifier_plist#PSSwitchCell_2|PSSwitchCell]] in the Recipes section for solving an issue on iOS 7. | |||
=== PSTitleValueCell === | === PSTitleValueCell === | ||
Line 340: | Line 334: | ||
== <tt>PSSpecifier</tt> runtime properties of plist keys == | == <tt>PSSpecifier</tt> runtime properties of plist keys == | ||
The table | The table below only shows the keys recognized by <tt>SpecifiersForPlist</tt> when translating the plist into an array of <tt>PSSpecifier</tt>s. They may correspond to the actual properties of the specifier. If you would like to generate a <tt>PSSpecifier</tt> in runtime, some actions may differ: | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 369: | Line 363: | ||
|- | |- | ||
| confirmation || Create an instance of [[PSConfirmationSpecifier]]. | | confirmation || Create an instance of [[PSConfirmationSpecifier]]. | ||
|- | |||
| enabled || Must be set to YES (as NSNumber) to make the specifier interactive. | |||
|} | |} | ||
== Recipes == | == Recipes == | ||
{{main|PreferenceBundles}} | |||
Use the following snippet to create a PSSpecifier in the runtime: | |||
<source lang="objc"> | |||
PSSpecifier* specifier = [PSSpecifier preferenceSpecifierNamed:@"title" | |||
target:self | |||
set:@selector(setPreferenceValue:specifier:) | |||
get:@selector(readPreferenceValue:) | |||
detail:Nil | |||
cell:<cell type> | |||
edit:Nil]; | |||
[specifier setProperty:@YES forKey:@"enabled"]; | |||
</source> | |||
Using <tt>@selector(setPreferenceValue:specifier:)</tt> as setter and <tt>@selector(readPreferenceValue:)</tt> as getter will ease the load on the work as the specifier will use its properties to make itself work, namely "defaults", "key", "default", "PostNotification". | |||
=== PSButtonCell === | === PSButtonCell === | ||
Line 380: | Line 390: | ||
<source lang="objc"> | <source lang="objc"> | ||
@interface UITableCell : UIView | |||
@end | |||
@interface UIImageAndTextTableCell : UITableCell | |||
-(id)titleTextLabel; | |||
@end | |||
@interface UIPreferencesTableCell : UIImageAndTextTableCell | |||
-(void)setTarget:(id)target; | |||
-(void)setAction:(SEL)action; | |||
@end | |||
@interface UIPreferencesControlTableCell : UIPreferencesTableCell | |||
@end | |||
@interface UIPreferencesDeleteTableCell : UIPreferencesControlTableCell | |||
@end | |||
@interface PSDeleteTableCell : UIPreferencesDeleteTableCell | @interface PSDeleteTableCell : UIPreferencesDeleteTableCell | ||
Line 402: | Line 429: | ||
Note that <code>UIPreferencesDeleteTableCell</code> no longer exists as of iOS 6.0. It appears to be replaced by a boolean on PSButtonCell, <code>isDestructive</code>. | Note that <code>UIPreferencesDeleteTableCell</code> no longer exists as of iOS 6.0. It appears to be replaced by a boolean on PSButtonCell, <code>isDestructive</code>. | ||
=== PSEditTextCell & PSSecureEditTextCell === | |||
To make the <tt>Return</tt> key close the keyboard add the following method to your PSListController subclass: | |||
<source lang="objc"> | |||
- (void)_returnKeyPressed:(NSConcreteNotification *)notification { | |||
[self.view endEditing:YES]; | |||
[super _returnKeyPressed:notification]; | |||
} | |||
</source> | |||
=== PSLinkCell === | === PSLinkCell === | ||
Line 431: | Line 469: | ||
The key thing is when you place MyListController inside your bundle, its bundle property will return your bundle which <tt>My Awesome Pane.plist</tt> can be found. | The key thing is when you place MyListController inside your bundle, its bundle property will return your bundle which <tt>My Awesome Pane.plist</tt> can be found. | ||
=== PSSwitchCell === | |||
Since iOS 7.0 and above the "alternateColors" key does not work. To be able to change the color of a switch, you must subclass PSSwitchTableCell in a [[PreferenceBundles|PreferenceBundle]] as follows: | |||
<source lang="objc"> | |||
@interface PSTableCell : UITableViewCell | |||
@end | |||
@interface PSControlTableCell : PSTableCell | |||
- (UIControl *)control; | |||
@end | |||
@interface PSSwitchTableCell : PSControlTableCell | |||
- (id)initWithStyle:(int)style reuseIdentifier:(id)identifier specifier:(id)specifier; | |||
@end | |||
@interface SRSwitchTableCell : PSSwitchTableCell | |||
@end | |||
@implementation SRSwitchTableCell | |||
-(id)initWithStyle:(int)style reuseIdentifier:(id)identifier specifier:(id)specifier { //init method | |||
self = [super initWithStyle:style reuseIdentifier:identifier specifier:specifier]; //call the super init method | |||
if (self) { | |||
[((UISwitch *)[self control]) setOnTintColor:[UIColor redColor]]; //change the switch color | |||
} | |||
return self; | |||
} | |||
@end | |||
</source> | |||
Then set this key-value pair for the specifier: | |||
cellClass = SRSwitchTableCell; | |||
A detailed tutorial about this has been written on [http://sharedroutine.com/?p=143 sharedroutine.com]. | |||
=== PSTitleValueCell === | === PSTitleValueCell === | ||
Line 457: | Line 531: | ||
<source lang="objc"> | <source lang="objc"> | ||
@interface PSTableCell : UITableViewCell | |||
@end | |||
@protocol PreferencesTableCustomView | |||
- (id)initWithSpecifier:(PSSpecifier *)specifier; | |||
- (CGFloat)preferredHeightForWidth:(CGFloat)width; | |||
@end | |||
@interface CustomCell : PSTableCell <PreferencesTableCustomView> { | @interface CustomCell : PSTableCell <PreferencesTableCustomView> { | ||
UILabel *_label; | UILabel *_label; | ||
Line 466: | Line 548: | ||
self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell" specifier:specifier]; | self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell" specifier:specifier]; | ||
if (self) { | if (self) { | ||
_label = [[UILabel alloc] initWithFrame:[self frame]]; | |||
_label = [[UILabel alloc] initWithFrame:frame]; | |||
[_label setLineBreakMode:UILineBreakModeWordWrap]; | [_label setLineBreakMode:UILineBreakModeWordWrap]; | ||
[_label setNumberOfLines:0]; | [_label setNumberOfLines:0]; | ||
Line 483: | Line 563: | ||
} | } | ||
- ( | - (CGFloat)preferredHeightForWidth:(CGFloat)width { | ||
// Return a custom cell height. | // Return a custom cell height. | ||
return 60.f; | return 60.f; | ||
Line 501: | Line 581: | ||
=== Constructing a PSLinkCell at runtime === | === Constructing a PSLinkCell at runtime === | ||
If you want to dynamically add a specifier for a PSLinkCell | If you want to dynamically add a specifier for a PSLinkCell that lazy-loads a bundle, you can do it like this: | ||
<source lang="objc"> | <source lang="objc"> | ||
Line 511: | Line 591: | ||
cell:PSLinkCell | cell:PSLinkCell | ||
edit:Nil]; | edit:Nil]; | ||
[specifier setProperty: | [specifier setProperty:@"/System/Library/PreferenceBundles/prefs.bundle" forKey:@"lazy-bundle"]; | ||
specifier | [specifier setAction:@selector(lazyLoadBundle:)]; | ||
// | |||
// Now add the specifier to your controller. | |||
</source> | |||
=== Constructing a PSLinkListCell at runtime === | |||
If you want to dynamically add a specifier for a PSLinkListCell you can do it like this: | |||
<source lang="objc"> | |||
PSSpecifier* specifier = [PSSpecifier preferenceSpecifierNamed:@"title" | |||
target:self | |||
set:NULL | |||
get:NULL | |||
detail:NSClassFromString(@"PSListItemsController") | |||
cell:PSLinkListCell | |||
edit:Nil]; | |||
[specifier setProperty:@YES forKey:@"enabled"]; | |||
[specifier setProperty:@"0" forKey:@"default"]; | |||
specifier.values = [NSArray arrayWithObjects:@"0",@"1",@"2",nil]; | |||
specifier.titleDictionary = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"Title 1",@"Title 2",@"Title 3",nil] forKeys:specifier.values]; | |||
specifier.shortTitleDictionary = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"T1",@"T@",@"T3",nil] forKeys:specifier.values]; | |||
[specifier setProperty:@"kListValue" forKey:@"key"]; | |||
// Now add the specifier to your controller. | |||
</source> | </source> | ||
Line 524: | Line 628: | ||
<source lang="objc"> | <source lang="objc"> | ||
@interface MyListController : PSEditableListController | @interface PSViewController : UIViewController | ||
@end | |||
@interface PSListController : PSViewController | |||
@end | |||
@interface PSEditableListController : PSListController | |||
@end | |||
@interface MyListController : PSEditableListController | |||
@end | @end | ||
Line 533: | Line 643: | ||
PSSpecifier* testSpecifier = [PSSpecifier preferenceSpecifierNamed:@"test" | PSSpecifier* testSpecifier = [PSSpecifier preferenceSpecifierNamed:@"test" | ||
target:self | target:self | ||
set: | set:NULL | ||
get: | get:NULL | ||
detail: | detail:Nil | ||
cell:PSTitleValueCell | cell:PSTitleValueCell | ||
edit: | edit:Nil]; | ||
_specifiers = [NSArray arrayWithObjects:testSpecifier, nil]; | _specifiers = [[NSArray arrayWithObjects:testSpecifier, nil] retain]; | ||
} | } | ||
return _specifiers; | return _specifiers; | ||
Line 545: | Line 655: | ||
</source> | </source> | ||
Please note, you will only be able to delete a specifier, if | Please note, you will only be able to delete a specifier, if its class is either <code>PSLinkListCell</code>, <code>PSListItemCell</code> or <code>PSTitleValueCell</code> | ||
However, you can make all specifier's deletable by adding the function | |||
<source lang="objc"> | |||
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { | |||
return UITableViewCellEditingStyleDelete; | |||
} | |||
</source> | |||
To perform a custom action when the specifier gets deleted, you have to implement a method in your PSEditableListController subclass like this: | To perform a custom action when the specifier gets deleted, you have to implement a method in your PSEditableListController subclass like this: | ||
Line 566: | Line 683: | ||
/* | /* | ||
construct the PSSpecifier* testSpecifier | construct the PSSpecifier* testSpecifier | ||
*/ | */ | ||
Line 572: | Line 689: | ||
</source> | </source> | ||
== | === Custom Settings Libraries === | ||
* https://github.com/mlnlover11/SettingsKit/wiki | |||
* [[CepheiPrefs]] | |||
== Plist Only == | |||
''To do: add more difficult recipes, such as using the PSGroupCell properly, and making sub-preferences using the PSLinkCell'' | |||
These will work as an independent plist, when put into "/Library/PreferenceLoader/Preferences". You need no Objective C or anything for these, just the plist file. This can be useful for adding preferences to things like [[Cydget]]s. Other examples from tweaks that use just the plist can be found in that same location. | |||
=== Required Structure === | |||
This is the required outline to add a custom plist to the Preferences app. | |||
<source lang="xml"> | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |||
<plist version="1.0"> | |||
<dict> | |||
<key>entry</key> | |||
<dict> | |||
<key>cell</key> | |||
<string>PSLinkCell</string> | |||
<key>icon</key> | |||
<string>[email protected]</string> | |||
<key>label</key> | |||
<string>Tweak Name</string> | |||
</dict> | |||
<key>items</key> | |||
<array> | |||
</array> | |||
<key>title</key> | |||
<string>Demo</string> | |||
</dict> | |||
</plist> | |||
</source> | |||
The various cells and items are put between the array tags. | |||
=== Example with PSEditTextCell === | |||
Though there is nothing all that special about this cell, it is a good example of how to make other cells. | |||
<source lang="xml"> | |||
<dict> | |||
<key>cell</key> | |||
<string>PSEditTextCell</string> | |||
<key>placeholder</key> | |||
<string>0.2</string> | |||
<key>bestGuess</key> | |||
<string>0.2</string> | |||
<key>defaults</key> | |||
<string>com.yourname.yourtweak</string> | |||
<key>isDecimalPad</key> | |||
<true/> | |||
<key>key</key> | |||
<string>savedName</string> | |||
<key>label</key> | |||
<string>Visible Name:</string> | |||
</dict> | |||
</source> | |||
This would make an input text cell for numbers. Use the keys specified above to change its properties and appearance. This goes for any cell. | |||
== External links == | |||
* https://code.google.com/p/networkpx/wiki/PreferencesSpecifierPlistFormat | |||
[[Category:Preferences]] |
Latest revision as of 13:10, 28 May 2021
This document provides the specification of the dictionaries that specify the layout of an iOS preference pane. These can be supplied statically via .plist files or dynamically via the _specifiers
ivar in a subclass of PSViewController.
Root level
The root level of the plist may contain these keys:
key | type | meaning | depends | |
---|---|---|---|---|
entry | dictionary | Specifier-like dictionary. | - | |
title | string | localizable string | Title of the preference pane. | entry ≠ nil |
items | array | ... of specifiers | Array of specifier dictionaries. | - |
The title key is used only for the root plist, otherwise, the label value from the specifier that pushed the new pane is used.
Specifier Keys and Values
You can use any keys that your controller recognizes in the plist for further customization.
General to-do: Add explanations of each specifier and potentially a screenshot of it (gif for the spinner?).
Cell types
Must be one of the following:
- PSButtonCell
- PSEditTextCell
- PSEditTextViewCell
- PSGiantCell
- PSGiantIconCell
- PSGroupCell
- PSLinkCell
- PSLinkListCell
- PSListItemCell
- PSSecureEditTextCell
- PSSegmentCell
- PSSliderCell
- PSSpinnerCell
- PSStaticTextCell
- PSSwitchCell
- PSTitleValueCell
The cell type is determined from the class method +[PSTableCell cellTypeFromString:].
General keys
key | type | meaning | depends | |
---|---|---|---|---|
cell | string | <cell type> | Specifier cell type. | - |
label | string | localizable string | Label of specifier. | - |
defaults | string | bundle ID | User defaults associated with this specifier. | - |
key | string | Key of the user defaults. | defaults ≠ nil | |
default | any | Default value of control. | - | |
id | string | Specifier ID. | - | |
hasIcon | boolean | Whether the specifier will have an icon. | bundle ≠ nil | |
icon | string | filename | File name of the icon to use. Default value is icon.png. The height of the icon should be 29px. | hasIcon = true |
get | string | selector | Getter. | - |
set | string | selector | Setter. | - |
enabled | boolean | Whether the control is enabled by default. | - | |
height | real | Height of the cell. | - | |
PostNotification | string | Darwin notification string to be posted when a change happens. | - | |
detail | string | class name | Detail controller class. | - |
cellClass | string | class name | Customized cell class | - |
requiredCapabilities | array | ... of <capability>s | Required capabilities of the device such that this specifier can be shown. | - |
dontIndentOnRemove | boolean | Prevents the cell from being indented when the table view is in editing mode. | - |
Investigate hasIcon key dependency since all but PSGroupCell display an icon if supplied.
Keys apply to all cells unless otherwise stated in their respective subsection.
Signature and default methods for the set and get selectors:
-(void)setPreferenceValue:(id)value forSpecifier:(PSSpecifier*)specifier;
-(id)readPreferenceValue:(PSSpecifier*)specifier;
PSButtonCell
key | type | meaning | depends | |
---|---|---|---|---|
action | string | selector | Action. Signature: -(void)speciferPerformedAction:(PSSpecifier*)specifier; or -(void)speciferPerformedAction; |
- |
confirmation | dictionary | <confirmation> | Definitions of the confirmation sheet before action is performed. | - |
isDestructive | boolean | Whether the action to be performed is destructive. The OK button will be in red if true if less than iOS7. | confirmation ≠ nil |
The confirmation value is a dictionary containing the following fields:
key | type | meaning | |
---|---|---|---|
prompt | string | localizable string | Content of confirmation sheet. |
title | string | localizable string | Title of confirmation sheet. |
okTitle | string | localizable string | Title of the OK button. |
cancelTitle | string | localizable string | Title of the cancel button. |
To do: confirm this last table. Tests suggest "prompt" is the title, "title" is the okTitle, "okTitle" is MIA, cancelTitle works as stated. Investigate history of "isDestructive" key.
PSEditTextCell & PSSecureEditTextCell
key | type | meaning | depends | |
---|---|---|---|---|
keyboard | string | {"numbers", "phone"} | Type of keyboard. nil or invalid values uses a normal keyboard. | - |
autoCaps | string | {"sentences", "words", "all"} | Autocapitalization type for cells that requires a keyboard. | keyboard = nil |
placeholder | string | localizable string | Placeholder. | - |
suffix | string | localizable string | Suffix. | - |
bestGuess | string | selector | Initial value of text field. | - |
noAutoCorrect | boolean | Disable auto-correction. | - | |
isIP | boolean | Input field intended for entering IP address (Use Numbers keyboard). | - | |
isURL | boolean | Input field intended for entering URL (Use URL keyboard). | - | |
isNumeric | boolean | Input field intended for entering numbers (Use NumberPad keyboard). | - | |
isDecimalPad | boolean | Input field intended for entering decimal numbers (Use DecimalPad keyboard). | - | |
isEmail | boolean | Input field intended for entering e-mail (Use EmailAddress keyboard). | - | |
isEmailAddressing | boolean | ? | - | |
prompt | string | localizable string | Setup prompt. | - |
okTitle | string | localizable string | Title for OK button in setup prompt. | prompt ≠ nil |
cancelTitle | string | localizable string | Title for cancel button in setup prompt. | prompt ≠ nil |
To do: Check "prompt", "okTitle" and "cancelTitle" as they appear to not work on iOS 6. Are these in the correct place?
Check what "suffix" does. Find "bestGuess" selector signature. Solve the mystery of "isEmailAddressing".
PSEditTextViewCell
This specifier doesn't show a label so it is recommended to use a previous specifier to indicate what this specifier represents.
The text area expands to fit the whole cell, so setting a height key will provide more space to write.
Saved value is HTML text, <div> being the root tag block.
PSGiantCell
This specifier doesn't show a label so it is recommended to use a specifier before this one to indicate what this specifier represents.
PSGiantIconCell
This specifier uses the label key as text content.
The font in this cell is bigger than normal.
To do: Find out the actual font and icon sizes.
PSGroupCell
key | type | meaning | depends |
---|---|---|---|
footerText | string | Text displayed in a small font after this specifier. | - |
footerAlignment | integer | 0:left; 1:center; 2:right; defaults to 1. | - |
headerCellClass | string | The class name to use for the header. | - |
footerCellClass | string | The class name to use for the footer. | - |
isStaticText | boolean | Whether the cells in this group have static text. | - |
If you want to make a Image Header read this. Hides the group title (label
key).
isStaticText
is used in conjunction with PSStaticTextCell.
To do: Research "isStaticText" interaction with "PSStaticTextCell".
PSLinkCell
key | type | meaning | depends | |
---|---|---|---|---|
bundle | string | filename | Bundle file name. This bundle will be loaded for additional resources. | - |
internal | boolean | Directory to search for the bundle. If true, search in /AppleInternal/Library/PreferenceBundles/. If false, search in /System/Library/PreferenceBundles/. |
bundle ≠ nil | |
isController | boolean | Whether the bundle contains a controller class. | bundle ≠ nil | |
overridePrincipalClass | boolean | Overrides the principal class by the detail controller when bundle has a controller. | isController = true | |
pane | string | class name | Edit pane class. If bundle is absent, the edit pane class is obtained from the current bundle. Default value is PSEditingPane. |
detail ≠ nil |
customControllerClass | string | class name | Custom controller class to use when the view become visible | - |
lazy-bundle | NSBundle | A bundle. This bundle will be loaded for additional resources. | - |
This specifier is useful for loading extra resources and custom code.
If none of these keys are specified, the framework will try to load a plist using the label text as name.
PSListItemCell
This specifier makes use of the get key to get the value in the runtime.
PSLinkListCell & PSSegmentCell
key | type | meaning | depends | |
---|---|---|---|---|
validValues | array | ...of strings | List of values to choose from. | - |
validTitles | array | ...of localizable strings | Titles corresponding to the list of values. | - |
shortTitles | array | ...of localizable strings | Short titles corresponding to the list of values, displayed in the link cell. | - |
valuesDataSource | string | selector | Selector to call to get the list of values dynamically. | validValues = nil |
titlesDataSource | string | selector | Selector to call to get the list of titles dynamically. | validTitles = nil |
staticTextMessage | string | localizable string | The message to be added below the cells list of PSListItemsController. | cell = "PSLinkListCell" |
valuesDataSource and titlesDataSource are performed on the target sent from -[PSListController loadSpecifiersFromPlistName:target:]. They must return an NSArray containing the values and (localized) titles respectively. Their signatures should be
-(NSArray*)dataFromTarget:(id)target;
In order to make a PSLinkListCell actually work like a list, you must supply the key-value pair
detail = PSListItemsController;
PSSliderCell
key | type | meaning | depends | |
---|---|---|---|---|
min | real | Minimum value of slider. | - | |
max | real | Maximum value of slider. | - | |
showValue | boolean | Show the value. | - | |
isContinuous | boolean | Change the value by steps. Possibly deprecated. | - | |
isSegmented | boolean | Change the value by steps. | - | |
segmentCount | integer | Steps count. | - | |
leftImage | string | filename | Image displayed next to the slider on the left. | - |
rightImage | string | filename | Image displayed next to the slider on the right. | - |
This specifier doesn't show a label so it is recommended to use a previous specifier to indicate what this specifier represents.
Image files must reside in the same directory. They can be symlinks to files elsewhere though. If showValue
is set to true it might overlap with the right image.
To Do: figure out if the step is a constant or a proportion (1/10? 1/16?) of the slider range.
PSSpinnerCell
PSSpinnerCell is a simple cell with an animating spinner (UIActivityIndicatorView) inside it. Available only in iOS 7 (or higher)[citation needed]. There is no way to start or stop the animation manually, it is always running. Therefore, this cell is meant to be dynamically inserted and deleted from a PSListController subclass.
PSStaticTextCell
This specifier uses the label key as text content.
PSSwitchCell
key | type | meaning | depends |
---|---|---|---|
alternateColors | boolean | Use an orange switch instead of blue. | iOS < 7 |
control-loading | boolean | Show an activity indicator view instead of switch (e.g. VPN cell) | - |
negate | boolean | Invert the value displayed. | - |
You can dynamically set the UISwitch's state by returning YES or NO in the get method. When the switch's state changes, the set method is called.
See PSSwitchCell in the Recipes section for solving an issue on iOS 7.
PSTitleValueCell
This specifier makes use of the get key to get the value in the runtime.
Miscellaneous
key | type | meaning | depends | |
---|---|---|---|---|
alignment | integer | Text alignment. 0:left; 1:center; 2:right; defaults to 1. | cell ∈ {"PSGroupCell", "PSStaticTextCell"} |
To do: check which specifiers support this key.
PSSpecifier runtime properties of plist keys
The table below only shows the keys recognized by SpecifiersForPlist when translating the plist into an array of PSSpecifiers. They may correspond to the actual properties of the specifier. If you would like to generate a PSSpecifier in runtime, some actions may differ:
keys | corresponding action |
---|---|
cell | Use the constructor, or change the cellType ivar. |
label | Use the name declared property. |
get | Use the constructor, or change the getter ivar. |
set | Use the constructor, or change the setter ivar. |
action | Change the action ivar. |
default | Use the value property. |
icon | -[PSSpecifier setProperty:forKey:] Use the iconImage and UIImage as a key and property, or -[PSSpecifier setupIconImageWithPath:] |
autoCaps, keyboard, noAutoCorrect | -[PSSpecifier setKeyboardType:autoCaps:autoCorrection:] |
isIP, isURL, isNumeric, isEmail, isEmailAddressing | Change the textFieldType ivar. |
bestGuess | Change the bestGuess ivar of the PSTextFieldSpecifier class. |
validValues, validTitles, shortTitles | -[PSSpecifier setValues:titles:shortTitles:] |
confirmation | Create an instance of PSConfirmationSpecifier. |
enabled | Must be set to YES (as NSNumber) to make the specifier interactive. |
Recipes
Use the following snippet to create a PSSpecifier in the runtime:
PSSpecifier* specifier = [PSSpecifier preferenceSpecifierNamed:@"title"
target:self
set:@selector(setPreferenceValue:specifier:)
get:@selector(readPreferenceValue:)
detail:Nil
cell:<cell type>
edit:Nil];
[specifier setProperty:@YES forKey:@"enabled"];
Using @selector(setPreferenceValue:specifier:) as setter and @selector(readPreferenceValue:) as getter will ease the load on the work as the specifier will use its properties to make itself work, namely "defaults", "key", "default", "PostNotification".
PSButtonCell
The red delete button in VPN is in fact very easy to implement. All you need to do is add the following code:
@interface UITableCell : UIView
@end
@interface UIImageAndTextTableCell : UITableCell
-(id)titleTextLabel;
@end
@interface UIPreferencesTableCell : UIImageAndTextTableCell
-(void)setTarget:(id)target;
-(void)setAction:(SEL)action;
@end
@interface UIPreferencesControlTableCell : UIPreferencesTableCell
@end
@interface UIPreferencesDeleteTableCell : UIPreferencesControlTableCell
@end
@interface PSDeleteTableCell : UIPreferencesDeleteTableCell
@end
@implementation PSDeleteTableCell
-(void)setValueChangedTarget:(id)target action:(SEL)action userInfo:(NSDictionary*)info {
[self setTarget:target];
[self setAction:action];
}
-(UILabel*)titleTextLabel {
UILabel* res = [super titleTextLabel];
res.textColor = [UIColor whiteColor];
return res;
}
@end
And add the following key-value pair to the button specifier:
cellClass = PSDeleteTableCell;
Note that UIPreferencesDeleteTableCell
no longer exists as of iOS 6.0. It appears to be replaced by a boolean on PSButtonCell, isDestructive
.
PSEditTextCell & PSSecureEditTextCell
To make the Return key close the keyboard add the following method to your PSListController subclass:
- (void)_returnKeyPressed:(NSConcreteNotification *)notification {
[self.view endEditing:YES];
[super _returnKeyPressed:notification];
}
PSLinkCell
PSLinkCell is useful for linking to sub-preference-panes. The simplest example just needs 2 keys:
{ cell = PSLinkCell; label = "Settings-iPhone"; }
The label is the important part. When user clicked on the link cell, iPhoneOS will use the unlocalized label as the file name of the plist for the next pane. In the example above, the main settings screen will appear.
If you use just 2 keys, only plists inside Preferences can be loaded. In order to load your own plist, you must use a custom subclass of PSListController in detail:
{ cell = PSLinkCell; label = "My Awesome Pane"; detail = MyListController; }
MyListController can simply be an empty subclass of PSListController:
@interface MyListController : PSListController {}
@end
@implementation MyListController
@end
The key thing is when you place MyListController inside your bundle, its bundle property will return your bundle which My Awesome Pane.plist can be found.
PSSwitchCell
Since iOS 7.0 and above the "alternateColors" key does not work. To be able to change the color of a switch, you must subclass PSSwitchTableCell in a PreferenceBundle as follows:
@interface PSTableCell : UITableViewCell
@end
@interface PSControlTableCell : PSTableCell
- (UIControl *)control;
@end
@interface PSSwitchTableCell : PSControlTableCell
- (id)initWithStyle:(int)style reuseIdentifier:(id)identifier specifier:(id)specifier;
@end
@interface SRSwitchTableCell : PSSwitchTableCell
@end
@implementation SRSwitchTableCell
-(id)initWithStyle:(int)style reuseIdentifier:(id)identifier specifier:(id)specifier { //init method
self = [super initWithStyle:style reuseIdentifier:identifier specifier:specifier]; //call the super init method
if (self) {
[((UISwitch *)[self control]) setOnTintColor:[UIColor redColor]]; //change the switch color
}
return self;
}
@end
Then set this key-value pair for the specifier:
cellClass = SRSwitchTableCell;
A detailed tutorial about this has been written on sharedroutine.com.
PSTitleValueCell
To display a value like Preferences -> General -> About
, add the cell to your plist:
{ cell = PSTitleValueCell; label = Version; get = "valueForSpecifier:"; }
And add the getter method to your controller:
- (NSString *)valueForSpecifier:(PSSpecifier *)specifier {
return @"1.0";
}
Custom cells
Making a custom cell, header or footer is useful because it allows you to customize the style, add an image, etc.
All you need to do is make a class that looks like:
@interface PSTableCell : UITableViewCell
@end
@protocol PreferencesTableCustomView
- (id)initWithSpecifier:(PSSpecifier *)specifier;
- (CGFloat)preferredHeightForWidth:(CGFloat)width;
@end
@interface CustomCell : PSTableCell <PreferencesTableCustomView> {
UILabel *_label;
}
@end
@implementation CustomCell
- (id)initWithSpecifier:(PSSpecifier *)specifier {
self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell" specifier:specifier];
if (self) {
_label = [[UILabel alloc] initWithFrame:[self frame]];
[_label setLineBreakMode:UILineBreakModeWordWrap];
[_label setNumberOfLines:0];
[_label setText:@"You can use attributed text to make this prettier."];
[_label setBackgroundColor:[UIColor clearColor]];
[_label setShadowColor:[UIColor whiteColor]];
[_label setShadowOffset:CGSizeMake(0,1)];
[_label setTextAlignment:UITextAlignmentCenter];
[self addSubview:_label];
[_label release];
}
return self;
}
- (CGFloat)preferredHeightForWidth:(CGFloat)width {
// Return a custom cell height.
return 60.f;
}
@end
Then, set the cellClass
, headerCellClass
or footerCellClass
in your specifier. For example:
... { cell = PSGroupCell; footerCellClass = CustomCell; }, ...
A cell
doesn't have to be specified for custom cells.
Constructing a PSLinkCell at runtime
If you want to dynamically add a specifier for a PSLinkCell that lazy-loads a bundle, you can do it like this:
PSSpecifier* specifier = [PSSpecifier preferenceSpecifierNamed:@"title"
target:self
set:NULL
get:NULL
detail:Nil
cell:PSLinkCell
edit:Nil];
[specifier setProperty:@"/System/Library/PreferenceBundles/prefs.bundle" forKey:@"lazy-bundle"];
[specifier setAction:@selector(lazyLoadBundle:)];
// Now add the specifier to your controller.
Constructing a PSLinkListCell at runtime
If you want to dynamically add a specifier for a PSLinkListCell you can do it like this:
PSSpecifier* specifier = [PSSpecifier preferenceSpecifierNamed:@"title"
target:self
set:NULL
get:NULL
detail:NSClassFromString(@"PSListItemsController")
cell:PSLinkListCell
edit:Nil];
[specifier setProperty:@YES forKey:@"enabled"];
[specifier setProperty:@"0" forKey:@"default"];
specifier.values = [NSArray arrayWithObjects:@"0",@"1",@"2",nil];
specifier.titleDictionary = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"Title 1",@"Title 2",@"Title 3",nil] forKeys:specifier.values];
specifier.shortTitleDictionary = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"T1",@"T@",@"T3",nil] forKeys:specifier.values];
[specifier setProperty:@"kListValue" forKey:@"key"];
// Now add the specifier to your controller.
Making an editable PSListController
With this you can perform a "swipe-to-delete" on the rows.
You just have to use a subclass of PSEditableListController
(which is a subclass of PSListController
) for your List Controller. For example:
@interface PSViewController : UIViewController
@end
@interface PSListController : PSViewController
@end
@interface PSEditableListController : PSListController
@end
@interface MyListController : PSEditableListController
@end
@implementation MyListController
- (id)specifiers {
if (!_specifiers) {
//add a sample specifier to the list
PSSpecifier* testSpecifier = [PSSpecifier preferenceSpecifierNamed:@"test"
target:self
set:NULL
get:NULL
detail:Nil
cell:PSTitleValueCell
edit:Nil];
_specifiers = [[NSArray arrayWithObjects:testSpecifier, nil] retain];
}
return _specifiers;
}
@end
Please note, you will only be able to delete a specifier, if its class is either PSLinkListCell
, PSListItemCell
or PSTitleValueCell
However, you can make all specifier's deletable by adding the function
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
To perform a custom action when the specifier gets deleted, you have to implement a method in your PSEditableListController subclass like this:
-(void)removedSpecifier:(PSSpecifier*)specifier{
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Removing specifier: "
message:[specifier name]
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
and set the deletionAction Key of the specifier:
extern NSString* PSDeletionActionKey;
/*
construct the PSSpecifier* testSpecifier
*/
[testSpecifier setProperty:NSStringFromSelector(@selector(removedSpecifier:)) forKey:PSDeletionActionKey];
Custom Settings Libraries
Plist Only
To do: add more difficult recipes, such as using the PSGroupCell properly, and making sub-preferences using the PSLinkCell
These will work as an independent plist, when put into "/Library/PreferenceLoader/Preferences". You need no Objective C or anything for these, just the plist file. This can be useful for adding preferences to things like Cydgets. Other examples from tweaks that use just the plist can be found in that same location.
Required Structure
This is the required outline to add a custom plist to the Preferences app.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>entry</key>
<dict>
<key>cell</key>
<string>PSLinkCell</string>
<key>icon</key>
<string>[email protected]</string>
<key>label</key>
<string>Tweak Name</string>
</dict>
<key>items</key>
<array>
</array>
<key>title</key>
<string>Demo</string>
</dict>
</plist>
The various cells and items are put between the array tags.
Example with PSEditTextCell
Though there is nothing all that special about this cell, it is a good example of how to make other cells.
<dict>
<key>cell</key>
<string>PSEditTextCell</string>
<key>placeholder</key>
<string>0.2</string>
<key>bestGuess</key>
<string>0.2</string>
<key>defaults</key>
<string>com.yourname.yourtweak</string>
<key>isDecimalPad</key>
<true/>
<key>key</key>
<string>savedName</string>
<key>label</key>
<string>Visible Name:</string>
</dict>
This would make an input text cell for numbers. Use the keys specified above to change its properties and appearance. This goes for any cell.