the whole game
This commit is contained in:
@@ -0,0 +1,850 @@
|
||||
//
|
||||
// IASKAppSettingsViewController.m
|
||||
// http://www.inappsettingskit.com
|
||||
//
|
||||
// Copyright (c) 2009-2010:
|
||||
// Luc Vandal, Edovia Inc., http://www.edovia.com
|
||||
// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com
|
||||
// All rights reserved.
|
||||
//
|
||||
// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz,
|
||||
// as the original authors of this code. You can give credit in a blog post, a tweet or on
|
||||
// a info page of your app. Also, the original authors appreciate letting them know if you use this code.
|
||||
//
|
||||
// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php
|
||||
//
|
||||
|
||||
|
||||
#import "IASKAppSettingsViewController.h"
|
||||
#import "IASKSettingsReader.h"
|
||||
#import "IASKSettingsStoreUserDefaults.h"
|
||||
#import "IASKPSToggleSwitchSpecifierViewCell.h"
|
||||
#import "IASKPSSliderSpecifierViewCell.h"
|
||||
#import "IASKPSTextFieldSpecifierViewCell.h"
|
||||
#import "IASKPSTitleValueSpecifierViewCell.h"
|
||||
#import "IASKSwitch.h"
|
||||
#import "IASKSlider.h"
|
||||
#import "IASKSpecifier.h"
|
||||
#import "IASKSpecifierValuesViewController.h"
|
||||
#import "IASKTextField.h"
|
||||
|
||||
static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
|
||||
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
|
||||
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
|
||||
|
||||
static NSString *kIASKCredits = @"Powered by InAppSettingsKit"; // Leave this as-is!!!
|
||||
|
||||
#define kIASKSpecifierValuesViewControllerIndex 0
|
||||
#define kIASKSpecifierChildViewControllerIndex 1
|
||||
|
||||
#define kIASKCreditsViewWidth 285
|
||||
|
||||
CGRect IASKCGRectSwap(CGRect rect);
|
||||
|
||||
@interface IASKAppSettingsViewController ()
|
||||
@property (nonatomic, retain) NSMutableArray *viewList;
|
||||
@property (nonatomic, retain) NSIndexPath *currentIndexPath;
|
||||
@property (nonatomic, retain) id currentFirstResponder;
|
||||
|
||||
- (void)_textChanged:(id)sender;
|
||||
- (void)synchronizeSettings;
|
||||
- (void)reload;
|
||||
@end
|
||||
|
||||
@implementation IASKAppSettingsViewController
|
||||
|
||||
@synthesize delegate = _delegate;
|
||||
@synthesize viewList = _viewList;
|
||||
@synthesize currentIndexPath = _currentIndexPath;
|
||||
@synthesize settingsReader = _settingsReader;
|
||||
@synthesize file = _file;
|
||||
@synthesize currentFirstResponder = _currentFirstResponder;
|
||||
@synthesize showCreditsFooter = _showCreditsFooter;
|
||||
@synthesize showDoneButton = _showDoneButton;
|
||||
@synthesize settingsStore = _settingsStore;
|
||||
|
||||
#pragma mark accessors
|
||||
- (IASKSettingsReader*)settingsReader {
|
||||
if (!_settingsReader) {
|
||||
_settingsReader = [[IASKSettingsReader alloc] initWithFile:self.file];
|
||||
}
|
||||
return _settingsReader;
|
||||
}
|
||||
|
||||
- (id<IASKSettingsStore>)settingsStore {
|
||||
if (!_settingsStore) {
|
||||
_settingsStore = [[IASKSettingsStoreUserDefaults alloc] init];
|
||||
}
|
||||
return _settingsStore;
|
||||
}
|
||||
|
||||
- (NSString*)file {
|
||||
if (!_file) {
|
||||
return @"Root";
|
||||
}
|
||||
return [[_file retain] autorelease];
|
||||
}
|
||||
|
||||
- (void)setFile:(NSString *)file {
|
||||
if (file != _file) {
|
||||
|
||||
[_file release];
|
||||
_file = [file copy];
|
||||
}
|
||||
|
||||
self.tableView.contentOffset = CGPointMake(0, 0);
|
||||
self.settingsReader = nil; // automatically initializes itself
|
||||
}
|
||||
|
||||
- (BOOL)isPad {
|
||||
BOOL isPad = NO;
|
||||
#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200)
|
||||
isPad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
|
||||
#endif
|
||||
return isPad;
|
||||
}
|
||||
|
||||
#pragma mark standard view controller methods
|
||||
- (id)init {
|
||||
return [self initWithNibName:@"IASKAppSettingsView" bundle:nil];
|
||||
}
|
||||
|
||||
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
|
||||
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
|
||||
// If set to YES, will display credits for InAppSettingsKit creators
|
||||
_showCreditsFooter = YES;
|
||||
|
||||
// If set to YES, will add a DONE button at the right of the navigation bar
|
||||
_showDoneButton = YES;
|
||||
|
||||
_cells = [[NSMutableDictionary alloc] init];
|
||||
|
||||
if ([self isPad]) {
|
||||
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLineEtched;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)awakeFromNib {
|
||||
// If set to YES, will display credits for InAppSettingsKit creators
|
||||
_showCreditsFooter = YES;
|
||||
|
||||
// If set to YES, will add a DONE button at the right of the navigation bar
|
||||
// if loaded via NIB, it's likely we sit in a TabBar- or NavigationController
|
||||
// and thus don't need the Done button
|
||||
_showDoneButton = NO;
|
||||
|
||||
if ([self isPad]) {
|
||||
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLineEtched;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSMutableArray *)viewList {
|
||||
if (!_viewList) {
|
||||
_viewList = [[NSMutableArray alloc] init];
|
||||
[_viewList addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"IASKSpecifierValuesView", @"ViewName",nil]];
|
||||
[_viewList addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"IASKAppSettingsView", @"ViewName",nil]];
|
||||
}
|
||||
return _viewList;
|
||||
}
|
||||
|
||||
- (void)viewDidUnload {
|
||||
// Release any retained subviews of the main view.
|
||||
// e.g. self.myOutlet = nil;
|
||||
self.view = nil;
|
||||
self.viewList = nil;
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
[self.tableView reloadData];
|
||||
|
||||
self.navigationItem.rightBarButtonItem = nil;
|
||||
self.navigationController.delegate = self;
|
||||
if (_showDoneButton) {
|
||||
UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
|
||||
target:self
|
||||
action:@selector(dismiss:)];
|
||||
self.navigationItem.rightBarButtonItem = buttonItem;
|
||||
[buttonItem release];
|
||||
}
|
||||
if (!self.title) {
|
||||
self.title = NSLocalizedString(@"Settings", @"");
|
||||
}
|
||||
|
||||
if (self.currentIndexPath) {
|
||||
if (animated) {
|
||||
// animate deselection of previously selected row
|
||||
[self.tableView selectRowAtIndexPath:self.currentIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
|
||||
[self.tableView deselectRowAtIndexPath:self.currentIndexPath animated:YES];
|
||||
}
|
||||
self.currentIndexPath = nil;
|
||||
}
|
||||
|
||||
[super viewWillAppear:animated];
|
||||
}
|
||||
|
||||
- (CGSize)contentSizeForViewInPopover {
|
||||
return [[self view] sizeThatFits:CGSizeMake(320, 2000)];
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated {
|
||||
[super viewDidAppear:animated];
|
||||
|
||||
NSNotificationCenter *dc = [NSNotificationCenter defaultCenter];
|
||||
IASK_IF_IOS4_OR_GREATER([dc addObserver:self selector:@selector(synchronizeSettings) name:UIApplicationDidEnterBackgroundNotification object:[UIApplication sharedApplication]];);
|
||||
IASK_IF_IOS4_OR_GREATER([dc addObserver:self selector:@selector(reload) name:UIApplicationWillEnterForegroundNotification object:[UIApplication sharedApplication]];);
|
||||
[dc addObserver:self selector:@selector(synchronizeSettings) name:UIApplicationWillTerminateNotification object:[UIApplication sharedApplication]];
|
||||
|
||||
//NSLog(@"I have loaded shitzlets now!\n");
|
||||
|
||||
for( NSString *key in _cells )
|
||||
{
|
||||
id value = [_cells objectForKey:key];
|
||||
if ([value respondsToSelector:@selector(toggle)]) {
|
||||
//NSLog(@"Responds to Toggle: %@!\n", key);
|
||||
[self toggledValue:[value toggle]];
|
||||
//[value toggle].on = [value toggle].on;
|
||||
}
|
||||
// do something
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated {
|
||||
[NSObject cancelPreviousPerformRequestsWithTarget:self];
|
||||
[super viewWillDisappear:animated];
|
||||
}
|
||||
|
||||
- (void)viewDidDisappear:(BOOL)animated {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
if (!self.navigationController.delegate) {
|
||||
// hide the keyboard when we're popping from the navigation controller
|
||||
[self.currentFirstResponder resignFirstResponder];
|
||||
}
|
||||
|
||||
[super viewDidDisappear:animated];
|
||||
}
|
||||
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
// Releases the view if it doesn't have a superview.
|
||||
[super didReceiveMemoryWarning];
|
||||
|
||||
// Release any cached data, images, etc that aren't in use.
|
||||
}
|
||||
|
||||
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
|
||||
if (![viewController isKindOfClass:[IASKAppSettingsViewController class]] && ![viewController isKindOfClass:[IASKSpecifierValuesViewController class]]) {
|
||||
[self dismiss:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
[_viewList release], _viewList = nil;
|
||||
[_currentIndexPath release], _currentIndexPath = nil;
|
||||
[_file release], _file = nil;
|
||||
[_currentFirstResponder release], _currentFirstResponder = nil;
|
||||
[_settingsReader release], _settingsReader = nil;
|
||||
[_settingsStore release], _settingsStore = nil;
|
||||
[_cells release]; _cells = nil;
|
||||
|
||||
_delegate = nil;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Actions
|
||||
|
||||
- (IBAction)dismiss:(id)sender {
|
||||
[self.settingsStore synchronize];
|
||||
self.navigationController.delegate = nil;
|
||||
|
||||
if (self.delegate && [self.delegate conformsToProtocol:@protocol(IASKSettingsDelegate)]) {
|
||||
[self.delegate settingsViewControllerDidEnd:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)toggledValue:(id)sender {
|
||||
IASKSwitch *toggle = (IASKSwitch*)sender;
|
||||
IASKSpecifier *spec = [_settingsReader specifierForKey:[toggle key]];
|
||||
|
||||
if ([toggle isOn]) {
|
||||
if ([spec trueValue] != nil) {
|
||||
[self.settingsStore setObject:[spec trueValue] forKey:[toggle key]];
|
||||
}
|
||||
else {
|
||||
[self.settingsStore setBool:YES forKey:[toggle key]];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ([spec falseValue] != nil) {
|
||||
[self.settingsStore setObject:[spec falseValue] forKey:[toggle key]];
|
||||
}
|
||||
else {
|
||||
[self.settingsStore setBool:NO forKey:[toggle key]];
|
||||
}
|
||||
}
|
||||
//NSLog(@"Toggled: %@\n", [toggle key]);
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kIASKAppSettingChanged
|
||||
object:[toggle key]
|
||||
userInfo:[NSDictionary dictionaryWithObject:[self.settingsStore objectForKey:[toggle key]]
|
||||
forKey:[toggle key]]];
|
||||
}
|
||||
|
||||
- (void)sliderChangedValue:(id)sender {
|
||||
IASKSlider *slider = (IASKSlider*)sender;
|
||||
[self.settingsStore setFloat:[slider value] forKey:[slider key]];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kIASKAppSettingChanged
|
||||
object:[slider key]
|
||||
userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:[slider value]]
|
||||
forKey:[slider key]]];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark UITableView Functions
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
return [self.settingsReader numberOfSections];
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
return [self.settingsReader numberOfRowsForSection:section];
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
IASKSpecifier *specifier = [self.settingsReader specifierForIndexPath:indexPath];
|
||||
if ([[specifier type] isEqualToString:kIASKCustomViewSpecifier]) {
|
||||
if ([self.delegate respondsToSelector:@selector(tableView:heightForSpecifier:)]) {
|
||||
return [self.delegate tableView:tableView heightForSpecifier:specifier];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return tableView.rowHeight;
|
||||
}
|
||||
|
||||
- (NSString *)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section {
|
||||
NSString *header = [self.settingsReader titleForSection:section];
|
||||
if (0 == header.length) {
|
||||
return nil;
|
||||
}
|
||||
return header;
|
||||
}
|
||||
|
||||
- (UIView *)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section {
|
||||
NSString *key = [self.settingsReader keyForSection:section];
|
||||
if ([self.delegate respondsToSelector:@selector(tableView:viewForHeaderForKey:)]) {
|
||||
return [self.delegate tableView:tableView viewForHeaderForKey:key];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger)section {
|
||||
NSString *key = [self.settingsReader keyForSection:section];
|
||||
if ([self tableView:tableView viewForHeaderInSection:section] && [self.delegate respondsToSelector:@selector(tableView:heightForHeaderForKey:)]) {
|
||||
CGFloat result;
|
||||
if ((result = [self.delegate tableView:tableView heightForHeaderForKey:key])) {
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
NSString *title;
|
||||
if ((title = [self tableView:tableView titleForHeaderInSection:section])) {
|
||||
CGSize size = [title sizeWithFont:[UIFont boldSystemFontOfSize:[UIFont labelFontSize]]
|
||||
constrainedToSize:CGSizeMake(tableView.frame.size.width - 2*kIASKHorizontalPaddingGroupTitles, INFINITY)
|
||||
lineBreakMode:UILineBreakModeWordWrap];
|
||||
return size.height+kIASKVerticalPaddingGroupTitles;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
|
||||
{
|
||||
NSString *footerText = [self.settingsReader footerTextForSection:section];
|
||||
if (_showCreditsFooter && (section == [self.settingsReader numberOfSections]-1)) {
|
||||
// show credits since this is the last section
|
||||
if ((footerText == nil) || ([footerText length] == 0)) {
|
||||
// show the credits on their own
|
||||
return kIASKCredits;
|
||||
} else {
|
||||
// show the credits below the app's FooterText
|
||||
return [NSString stringWithFormat:@"%@\n\n%@", footerText, kIASKCredits];
|
||||
}
|
||||
} else {
|
||||
if ([footerText length] == 0) {
|
||||
return nil;
|
||||
}
|
||||
return [self.settingsReader footerTextForSection:section];
|
||||
}
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
//NSLog(@"CELL FOR ROW: %@\n", indexPath);
|
||||
IASKSpecifier *specifier = [self.settingsReader specifierForIndexPath:indexPath];
|
||||
NSString *key = [specifier key];
|
||||
|
||||
if ([[specifier type] isEqualToString:kIASKCustomViewSpecifier] && [self.delegate respondsToSelector:@selector(tableView:cellForSpecifier:)]) {
|
||||
return [self.delegate tableView:tableView cellForSpecifier:specifier];
|
||||
}
|
||||
|
||||
//NSString *reuseId = [specifier key];
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
|
||||
|
||||
if ([[specifier type] isEqualToString:kIASKPSToggleSwitchSpecifier]) {
|
||||
if (!cell) {
|
||||
cell = (IASKPSToggleSwitchSpecifierViewCell*) [[[NSBundle mainBundle] loadNibNamed:@"IASKPSToggleSwitchSpecifierViewCell"
|
||||
owner:self
|
||||
options:nil] objectAtIndex:0];
|
||||
}
|
||||
((IASKPSToggleSwitchSpecifierViewCell*)cell).label.text = [specifier title];
|
||||
|
||||
id currentValue = [self.settingsStore objectForKey:key];
|
||||
BOOL toggleState;
|
||||
if (currentValue) {
|
||||
if ([currentValue isEqual:[specifier trueValue]]) {
|
||||
toggleState = YES;
|
||||
} else if ([currentValue isEqual:[specifier falseValue]]) {
|
||||
toggleState = NO;
|
||||
} else {
|
||||
toggleState = [currentValue boolValue];
|
||||
}
|
||||
} else {
|
||||
toggleState = [specifier defaultBoolValue];
|
||||
}
|
||||
|
||||
((IASKPSToggleSwitchSpecifierViewCell*)cell).toggle.on = toggleState;
|
||||
[((IASKPSToggleSwitchSpecifierViewCell*)cell).toggle addTarget:self action:@selector(toggledValue:) forControlEvents:UIControlEventValueChanged];
|
||||
[((IASKPSToggleSwitchSpecifierViewCell*)cell).toggle setKey:key];
|
||||
// [((IASKPSToggleSwitchSpecifierViewCell*)cell).toggle
|
||||
[_cells setObject:cell forKey:key];
|
||||
|
||||
//NSLog(@"Setting cell: %@ : %p == %p?\n", key, cell, [_cells objectForKey:key]);
|
||||
//[((IASKPSToggleSwitchSpecifierViewCell*)cell).toggle setEnabled:NO]; // @iaskattn
|
||||
return cell;
|
||||
}
|
||||
else if ([[specifier type] isEqualToString:kIASKPSMultiValueSpecifier]) {
|
||||
if (!cell) {
|
||||
cell = [[[IASKPSTitleValueSpecifierViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:[specifier type]] autorelease];
|
||||
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
|
||||
cell.backgroundColor = [UIColor whiteColor];
|
||||
}
|
||||
[[cell textLabel] setText:[specifier title]];
|
||||
[[cell detailTextLabel] setText:[[specifier titleForCurrentValue:[self.settingsStore objectForKey:key] != nil ?
|
||||
[self.settingsStore objectForKey:key] : [specifier defaultValue]] description]];
|
||||
[_cells setValue:cell forKey:key];
|
||||
return cell;
|
||||
}
|
||||
else if ([[specifier type] isEqualToString:kIASKPSTitleValueSpecifier]) {
|
||||
if (!cell) {
|
||||
cell = [[[IASKPSTitleValueSpecifierViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:[specifier type]] autorelease];
|
||||
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||
cell.backgroundColor = [UIColor whiteColor];
|
||||
}
|
||||
|
||||
cell.textLabel.text = [specifier title];
|
||||
id value = [self.settingsStore objectForKey:key] ? : [specifier defaultValue];
|
||||
|
||||
NSString *stringValue;
|
||||
if ([specifier multipleValues] || [specifier multipleTitles]) {
|
||||
stringValue = [specifier titleForCurrentValue:value];
|
||||
} else {
|
||||
stringValue = [value description];
|
||||
}
|
||||
|
||||
cell.detailTextLabel.text = stringValue;
|
||||
[cell setUserInteractionEnabled:NO];
|
||||
|
||||
[_cells setValue:cell forKey:key];
|
||||
return cell;
|
||||
}
|
||||
else if ([[specifier type] isEqualToString:kIASKPSTextFieldSpecifier]) {
|
||||
if (!cell) {
|
||||
cell = (IASKPSTextFieldSpecifierViewCell*) [[[NSBundle mainBundle] loadNibNamed:@"IASKPSTextFieldSpecifierViewCell"
|
||||
owner:self
|
||||
options:nil] objectAtIndex:0];
|
||||
|
||||
((IASKPSTextFieldSpecifierViewCell*)cell).textField.textAlignment = UITextAlignmentLeft;
|
||||
((IASKPSTextFieldSpecifierViewCell*)cell).textField.returnKeyType = UIReturnKeyDone;
|
||||
((IASKPSTextFieldSpecifierViewCell*)cell)->stringIfEmpty = [specifier stringIfEmpty];
|
||||
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||
}
|
||||
|
||||
((IASKPSTextFieldSpecifierViewCell*)cell).label.text = [specifier title];
|
||||
|
||||
NSString *textValue = [self.settingsStore objectForKey:key] != nil ? [self.settingsStore objectForKey:key] : [specifier defaultStringValue];
|
||||
if (textValue && ![textValue isMemberOfClass:[NSString class]]) {
|
||||
textValue = [NSString stringWithFormat:@"%@", textValue];
|
||||
}
|
||||
IASKTextField *textField = ((IASKPSTextFieldSpecifierViewCell*)cell).textField;
|
||||
textField. text = textValue;
|
||||
textField.key = key;
|
||||
textField.delegate = self;
|
||||
textField.secureTextEntry = [specifier isSecure];
|
||||
textField.keyboardType = [specifier keyboardType];
|
||||
textField.autocapitalizationType = [specifier autocapitalizationType];
|
||||
[textField addTarget:self action:@selector(_textChanged:) forControlEvents:UIControlEventEditingChanged];
|
||||
if([specifier isSecure]){
|
||||
textField.autocorrectionType = UITextAutocorrectionTypeNo;
|
||||
} else {
|
||||
textField.autocorrectionType = [specifier autoCorrectionType];
|
||||
}
|
||||
[cell setNeedsLayout];
|
||||
[_cells setValue:cell forKey:key];
|
||||
return cell;
|
||||
}
|
||||
else if ([[specifier type] isEqualToString:kIASKPSSliderSpecifier]) {
|
||||
if (!cell) {
|
||||
cell = (IASKPSSliderSpecifierViewCell*) [[[NSBundle mainBundle] loadNibNamed:@"IASKPSSliderSpecifierViewCell"
|
||||
owner:self
|
||||
options:nil] objectAtIndex:0];
|
||||
[(IASKPSSliderSpecifierViewCell*)cell initDefaults];
|
||||
}
|
||||
if ([specifier hasSpecified:kIASKTextOffsetPixels]) {
|
||||
((IASKPSSliderSpecifierViewCell*)cell)->textOffsetPixels = [specifier textOffsetPixels];
|
||||
}
|
||||
if ([[specifier minimumValueImage] length] > 0) {
|
||||
((IASKPSSliderSpecifierViewCell*)cell).minImage.image = [UIImage imageWithContentsOfFile:[_settingsReader pathForImageNamed:[specifier minimumValueImage]]];
|
||||
}
|
||||
|
||||
if ([[specifier maximumValueImage] length] > 0) {
|
||||
((IASKPSSliderSpecifierViewCell*)cell).maxImage.image = [UIImage imageWithContentsOfFile:[_settingsReader pathForImageNamed:[specifier minimumValueImage]]];
|
||||
}
|
||||
if ([[specifier title] length] > 0) {
|
||||
((IASKPSSliderSpecifierViewCell*)cell).label.text = [specifier title];
|
||||
}
|
||||
|
||||
IASKSlider *slider = ((IASKPSSliderSpecifierViewCell*)cell).slider;
|
||||
slider.minimumValue = [specifier minimumValue];
|
||||
slider.maximumValue = [specifier maximumValue];
|
||||
slider.value = [self.settingsStore objectForKey:key] != nil ? [[self.settingsStore objectForKey:key] floatValue] : [[specifier defaultValue] floatValue];
|
||||
[slider addTarget:self action:@selector(sliderChangedValue:) forControlEvents:UIControlEventValueChanged];
|
||||
slider.key = key;
|
||||
[cell setNeedsLayout];
|
||||
[_cells setValue:cell forKey:key];
|
||||
return cell;
|
||||
}
|
||||
else if ([[specifier type] isEqualToString:kIASKPSChildPaneSpecifier]) {
|
||||
if (!cell) {
|
||||
cell = [[[IASKPSTitleValueSpecifierViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:[specifier type]] autorelease];
|
||||
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
|
||||
cell.backgroundColor = [UIColor whiteColor];
|
||||
}
|
||||
|
||||
[[cell textLabel] setText:[specifier title]];
|
||||
[_cells setValue:cell forKey:key];
|
||||
return cell;
|
||||
} else if ([[specifier type] isEqualToString:kIASKOpenURLSpecifier]) {
|
||||
if (!cell) {
|
||||
cell = [[[IASKPSTitleValueSpecifierViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:[specifier type]] autorelease];
|
||||
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
|
||||
cell.backgroundColor = [UIColor whiteColor];
|
||||
}
|
||||
|
||||
cell.textLabel.text = [specifier title];
|
||||
cell.detailTextLabel.text = [[specifier defaultValue] description];
|
||||
[_cells setValue:cell forKey:key];
|
||||
return cell;
|
||||
} else if ([[specifier type] isEqualToString:kIASKButtonSpecifier]) {
|
||||
if (!cell) {
|
||||
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[specifier type]] autorelease];
|
||||
cell.backgroundColor = [UIColor whiteColor];
|
||||
}
|
||||
cell.textLabel.text = [specifier title];
|
||||
cell.textLabel.textAlignment = UITextAlignmentCenter;
|
||||
[_cells setValue:cell forKey:key];
|
||||
return cell;
|
||||
} else if ([[specifier type] isEqualToString:kIASKMailComposeSpecifier]) {
|
||||
if (!cell) {
|
||||
cell = [[[IASKPSTitleValueSpecifierViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:[specifier type]] autorelease];
|
||||
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
|
||||
cell.backgroundColor = [UIColor whiteColor];
|
||||
}
|
||||
|
||||
cell.textLabel.text = [specifier title];
|
||||
cell.detailTextLabel.text = [[specifier defaultValue] description];
|
||||
[_cells setValue:cell forKey:key];
|
||||
return cell;
|
||||
} else {
|
||||
if (!cell) {
|
||||
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[specifier type]] autorelease];
|
||||
cell.backgroundColor = [UIColor whiteColor];
|
||||
}
|
||||
[[cell textLabel] setText:[specifier title]];
|
||||
[_cells setValue:cell forKey:key];
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
|
||||
- (IASKSwitch*) getSwitch:(NSString*) key {
|
||||
return [[_cells objectForKey:key] toggle];
|
||||
}
|
||||
|
||||
- (IASKPSToggleSwitchSpecifierViewCell*) getSwitchView:(NSString*) key {
|
||||
return [_cells objectForKey:key];
|
||||
}
|
||||
|
||||
- (void)setEnabled:(BOOL)status forKey:(NSString*)key {
|
||||
id value = [_cells objectForKey:key];
|
||||
|
||||
//NSLog(@"key: %@, value: %p\n (toggle: %p)\n", key, value, [value toggle]);
|
||||
|
||||
if (value == nil) return;
|
||||
|
||||
[[value label] setEnabled:status];
|
||||
|
||||
// This is lazy town! Try to handle it as a toggle, slider or textfield
|
||||
if ([value respondsToSelector:@selector(toggle)]) [[value toggle] setEnabled:status];
|
||||
if ([value respondsToSelector:@selector(slider)]) [[value slider] setEnabled:status];
|
||||
if ([value respondsToSelector:@selector(textField)])[[value textField] setEnabled:status];
|
||||
}
|
||||
|
||||
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
IASKSpecifier *specifier = [self.settingsReader specifierForIndexPath:indexPath];
|
||||
|
||||
if ([[specifier type] isEqualToString:kIASKPSToggleSwitchSpecifier]) {
|
||||
return nil;
|
||||
} else {
|
||||
return indexPath;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
IASKSpecifier *specifier = [self.settingsReader specifierForIndexPath:indexPath];
|
||||
|
||||
if ([[specifier type] isEqualToString:kIASKPSToggleSwitchSpecifier]) {
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:NO];
|
||||
}
|
||||
else if ([[specifier type] isEqualToString:kIASKPSMultiValueSpecifier]) {
|
||||
IASKSpecifierValuesViewController *targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierValuesViewControllerIndex] objectForKey:@"viewController"];
|
||||
|
||||
if (targetViewController == nil) {
|
||||
// the view controller has not been created yet, create it and set it to our viewList array
|
||||
// create a new dictionary with the new view controller
|
||||
NSMutableDictionary *newItemDict = [NSMutableDictionary dictionaryWithCapacity:3];
|
||||
[newItemDict addEntriesFromDictionary: [self.viewList objectAtIndex:kIASKSpecifierValuesViewControllerIndex]]; // copy the title and explain strings
|
||||
|
||||
targetViewController = [[IASKSpecifierValuesViewController alloc] initWithNibName:@"IASKSpecifierValuesView" bundle:nil];
|
||||
// add the new view controller to the dictionary and then to the 'viewList' array
|
||||
[newItemDict setObject:targetViewController forKey:@"viewController"];
|
||||
[self.viewList replaceObjectAtIndex:kIASKSpecifierValuesViewControllerIndex withObject:newItemDict];
|
||||
[targetViewController release];
|
||||
|
||||
// load the view controll back in to push it
|
||||
targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierValuesViewControllerIndex] objectForKey:@"viewController"];
|
||||
}
|
||||
self.currentIndexPath = indexPath;
|
||||
[targetViewController setCurrentSpecifier:specifier];
|
||||
targetViewController.settingsReader = self.settingsReader;
|
||||
targetViewController.settingsStore = self.settingsStore;
|
||||
[[self navigationController] pushViewController:targetViewController animated:YES];
|
||||
}
|
||||
else if ([[specifier type] isEqualToString:kIASKPSSliderSpecifier]) {
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:NO];
|
||||
}
|
||||
else if ([[specifier type] isEqualToString:kIASKPSTextFieldSpecifier]) {
|
||||
IASKPSTextFieldSpecifierViewCell *textFieldCell = (id)[tableView cellForRowAtIndexPath:indexPath];
|
||||
[textFieldCell.textField becomeFirstResponder];
|
||||
}
|
||||
else if ([[specifier type] isEqualToString:kIASKPSChildPaneSpecifier]) {
|
||||
|
||||
|
||||
Class vcClass = [specifier viewControllerClass];
|
||||
if (vcClass) {
|
||||
SEL initSelector = [specifier viewControllerSelector];
|
||||
if (!initSelector) {
|
||||
initSelector = @selector(init);
|
||||
}
|
||||
UIViewController * vc = [vcClass performSelector:@selector(alloc)];
|
||||
[vc performSelector:initSelector withObject:[specifier file] withObject:[specifier key]];
|
||||
if ([vc respondsToSelector:@selector(setDelegate:)]) {
|
||||
[vc performSelector:@selector(setDelegate:) withObject:self.delegate];
|
||||
}
|
||||
if ([vc respondsToSelector:@selector(setSettingsStore:)]) {
|
||||
[vc performSelector:@selector(setSettingsStore:) withObject:self.settingsStore];
|
||||
}
|
||||
self.navigationController.delegate = nil;
|
||||
[self.navigationController pushViewController:vc animated:YES];
|
||||
[vc performSelector:@selector(release)];
|
||||
return;
|
||||
}
|
||||
|
||||
if (nil == [specifier file]) {
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
return;
|
||||
}
|
||||
|
||||
IASKAppSettingsViewController *targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierChildViewControllerIndex] objectForKey:@"viewController"];
|
||||
|
||||
if (targetViewController == nil) {
|
||||
// the view controller has not been created yet, create it and set it to our viewList array
|
||||
// create a new dictionary with the new view controller
|
||||
NSMutableDictionary *newItemDict = [NSMutableDictionary dictionaryWithCapacity:3];
|
||||
[newItemDict addEntriesFromDictionary: [self.viewList objectAtIndex:kIASKSpecifierChildViewControllerIndex]]; // copy the title and explain strings
|
||||
|
||||
targetViewController = [[[self class] alloc] initWithNibName:@"IASKAppSettingsView" bundle:nil];
|
||||
targetViewController.showDoneButton = NO;
|
||||
targetViewController.settingsStore = self.settingsStore;
|
||||
targetViewController.delegate = self.delegate;
|
||||
|
||||
// add the new view controller to the dictionary and then to the 'viewList' array
|
||||
[newItemDict setObject:targetViewController forKey:@"viewController"];
|
||||
[self.viewList replaceObjectAtIndex:kIASKSpecifierChildViewControllerIndex withObject:newItemDict];
|
||||
[targetViewController release];
|
||||
|
||||
// load the view controll back in to push it
|
||||
targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierChildViewControllerIndex] objectForKey:@"viewController"];
|
||||
}
|
||||
self.currentIndexPath = indexPath;
|
||||
targetViewController.file = specifier.file;
|
||||
targetViewController.title = specifier.title;
|
||||
targetViewController.showCreditsFooter = NO;
|
||||
[[self navigationController] pushViewController:targetViewController animated:YES];
|
||||
} else if ([[specifier type] isEqualToString:kIASKOpenURLSpecifier]) {
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:specifier.file]];
|
||||
} else if ([[specifier type] isEqualToString:kIASKButtonSpecifier]) {
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
if ([self.delegate respondsToSelector:@selector(settingsViewController:buttonTappedForKey:)]) {
|
||||
[self.delegate settingsViewController:self buttonTappedForKey:[specifier key]];
|
||||
} else {
|
||||
// legacy code, provided for backward compatibility
|
||||
// the delegate mechanism above is much cleaner and doesn't leak
|
||||
Class buttonClass = [specifier buttonClass];
|
||||
SEL buttonAction = [specifier buttonAction];
|
||||
if ([buttonClass respondsToSelector:buttonAction]) {
|
||||
[buttonClass performSelector:buttonAction withObject:self withObject:[specifier key]];
|
||||
NSLog(@"InAppSettingsKit Warning: Using IASKButtonSpecifier without implementing the delegate method is deprecated");
|
||||
}
|
||||
}
|
||||
} /*else if ([[specifier type] isEqualToString:kIASKMailComposeSpecifier]) { //@iaskmail
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
if ([MFMailComposeViewController canSendMail]) {
|
||||
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
|
||||
mailViewController.navigationBar.barStyle = self.navigationController.navigationBar.barStyle;
|
||||
mailViewController.navigationBar.tintColor = self.navigationController.navigationBar.tintColor;
|
||||
|
||||
if ([specifier localizedObjectForKey:kIASKMailComposeSubject]) {
|
||||
[mailViewController setSubject:[specifier localizedObjectForKey:kIASKMailComposeSubject]];
|
||||
}
|
||||
if ([[specifier specifierDict] objectForKey:kIASKMailComposeToRecipents]) {
|
||||
[mailViewController setToRecipients:[[specifier specifierDict] objectForKey:kIASKMailComposeToRecipents]];
|
||||
}
|
||||
if ([[specifier specifierDict] objectForKey:kIASKMailComposeCcRecipents]) {
|
||||
[mailViewController setCcRecipients:[[specifier specifierDict] objectForKey:kIASKMailComposeCcRecipents]];
|
||||
}
|
||||
if ([[specifier specifierDict] objectForKey:kIASKMailComposeBccRecipents]) {
|
||||
[mailViewController setBccRecipients:[[specifier specifierDict] objectForKey:kIASKMailComposeBccRecipents]];
|
||||
}
|
||||
if ([specifier localizedObjectForKey:kIASKMailComposeBody]) {
|
||||
BOOL isHTML = NO;
|
||||
if ([[specifier specifierDict] objectForKey:kIASKMailComposeBodyIsHTML]) {
|
||||
isHTML = [[[specifier specifierDict] objectForKey:kIASKMailComposeBodyIsHTML] boolValue];
|
||||
}
|
||||
|
||||
if ([self.delegate respondsToSelector:@selector(mailComposeBody)]) {
|
||||
[mailViewController setMessageBody:[self.delegate mailComposeBody] isHTML:isHTML];
|
||||
}
|
||||
else {
|
||||
[mailViewController setMessageBody:[specifier localizedObjectForKey:kIASKMailComposeBody] isHTML:isHTML];
|
||||
}
|
||||
}
|
||||
|
||||
UIViewController<MFMailComposeViewControllerDelegate> *vc = nil;
|
||||
|
||||
if ([self.delegate respondsToSelector:@selector(viewControllerForMailComposeView)]) {
|
||||
vc = [self.delegate viewControllerForMailComposeView];
|
||||
}
|
||||
|
||||
if (vc == nil) {
|
||||
vc = self;
|
||||
}
|
||||
|
||||
mailViewController.mailComposeDelegate = vc;
|
||||
[vc presentModalViewController:mailViewController animated:YES];
|
||||
[mailViewController release];
|
||||
}else {
|
||||
UIAlertView *alert = [[UIAlertView alloc]
|
||||
initWithTitle:NSLocalizedString(@"Mail not configured", @"InAppSettingsKit")
|
||||
message:NSLocalizedString(@"This device is not configured for sending Email. Please configure the Mail settings in the Settings app.", @"InAppSettingsKit")
|
||||
delegate: nil
|
||||
cancelButtonTitle:NSLocalizedString(@"OK", @"InAppSettingsKit")
|
||||
otherButtonTitles:nil];
|
||||
[alert show];
|
||||
[alert release];
|
||||
}
|
||||
|
||||
} */ else {
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:NO];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//#pragma mark -
|
||||
//#pragma mark MFMailComposeViewControllerDelegate Function
|
||||
//
|
||||
//-(void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
|
||||
//
|
||||
// // Forward the mail compose delegate
|
||||
// if ([self.delegate respondsToSelector:@selector(mailComposeController: didFinishWithResult: error:)]) {
|
||||
// [self.delegate mailComposeController:controller didFinishWithResult:result error:error];
|
||||
// }
|
||||
//
|
||||
// // NOTE: No error handling is done here
|
||||
// [self dismissModalViewControllerAnimated:YES];
|
||||
//}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark UITextFieldDelegate Functions
|
||||
|
||||
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
|
||||
self.currentFirstResponder = textField;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)_textChanged:(id)sender {
|
||||
IASKTextField *text = (IASKTextField*)sender;
|
||||
[_settingsStore setObject:[text text] forKey:[text key]];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kIASKAppSettingChanged
|
||||
object:[text key]
|
||||
userInfo:[NSDictionary dictionaryWithObject:[text text]
|
||||
forKey:[text key]]];
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
|
||||
[textField resignFirstResponder];
|
||||
self.currentFirstResponder = nil;
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Notifications
|
||||
|
||||
- (void)synchronizeSettings {
|
||||
[_settingsStore synchronize];
|
||||
}
|
||||
|
||||
- (void)reload {
|
||||
// wait 0.5 sec until UI is available after applicationWillEnterForeground
|
||||
[self.tableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.5];
|
||||
}
|
||||
|
||||
#pragma mark CGRect Utility function
|
||||
CGRect IASKCGRectSwap(CGRect rect) {
|
||||
CGRect newRect;
|
||||
newRect.origin.x = rect.origin.y;
|
||||
newRect.origin.y = rect.origin.x;
|
||||
newRect.size.width = rect.size.height;
|
||||
newRect.size.height = rect.size.width;
|
||||
return newRect;
|
||||
}
|
||||
@end
|
||||
Reference in New Issue
Block a user