iOS设置包中的TableView

时间:2014-09-12 05:36:42

标签: ios settings

我是iOS开发的新手,我正在整理出如何在设置包上添加一个带有复选标记的表格视图,如下所示:

enter image description here

有什么办法吗?或者这仅适用于特定iOS批准的应用程序?

期待一个答案。感谢。

3 个答案:

答案 0 :(得分:1)

您可以通过多值元素来实现此目的。当用户点击包含多值元素的首选项时,“设置”应用程序将显示一个新页面,其中包含可供选择的值。如果需要,可以将Google用于教程(设置包的多值选项)。

以下是详细信息:PSMultiValueSpecifier

答案 1 :(得分:0)

如果我猜对了,你想知道如何在你的应用程序和iOS设置之外显示设置,那么请查看this tutorial。它应该让你开始。

取出以下链接:

我一直在寻找并且无法找到样板解决方案,因此创建了我自己的代码来执行此操作。它支持设置类型标题,组,文本字段,多值和切换开关。

它不支持滑块。

此解决方案支持纵向和横向模式,还可以处理更改设备方向。

首先,我假设您使用以下代码从Settings.bundle中读出默认值。

- (void) registerDefaultsFromSettingsBundle
{
    NSLog(@"Registering default values from Settings.bundle");
    NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
    [defs synchronize];

    NSString *settingsBundle = [[NSBundle mainBundle] pathForResource: @"Settings" ofType: @"bundle"];

    if(!settingsBundle)
    {
        NSLog(@"Could not find Settings.bundle");
        return;
    }

    NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent: @"Root.plist"]];
    NSArray *preferences = [settings objectForKey: @"PreferenceSpecifiers"];
    NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]];

    for (NSDictionary *prefSpecification in preferences)
    {
        NSString *key = [prefSpecification objectForKey:@"Key"];
        if (key)
        {
            // check if value readable in userDefaults
            id currentObject = [defs objectForKey: key];
            if (currentObject == nil)
            {
                // not readable: set value from Settings.bundle
                id objectToSet = [prefSpecification objectForKey: @"DefaultValue"];
                [defaultsToRegister setObject: objectToSet forKey: key];
                NSLog(@"Setting object %@ for key %@", objectToSet, key);
            }
            else
            {
                // already readable: don't touch
                NSLog(@"Key %@ is readable (value: %@), nothing written to defaults.", key, currentObject);
            }
        }
    }

    [defs registerDefaults: defaultsToRegister];
    [defs synchronize];
}

好的,现在你需要2节课。 SettingsTableViewController和MultiValueTableViewController。

SettingsTableViewController.h

    //
//  SettingsTableViewController.h
//  Cochlear App
//
//  Created by Gilles Lesire on 16/07/14.
//  Free to use
//

#import <UIKit/UIKit.h>
#import "MultiValueTableViewController.h"

@interface SettingsTableViewController : UITableViewController <MultiValueDelegate> {
    NSMutableArray *labelViews;
    NSMutableArray *textViews;
    NSMutableArray *settingsKeys;
    NSMutableArray *settingsTableSections;
    NSMutableArray *settingsTableData;
}

@end

SettingsTableViewController.m

//
//  SettingsTableViewController.m
//  Cochlear App
//
//  Created by Gilles Lesire on 16/07/14.
//  Free to use
////

#import "SettingsTableViewController.h"

#define labelCGRectX 25
#define labelCGRectY 25
#define labelCGRectWidth 140
#define labelCGRectHeight 21

#define typeGroup @"PSGroupSpecifier"
#define typeTitle @"PSTitleValueSpecifier"
#define typeToggleSwitch @"PSToggleSwitchSpecifier"
#define typeMultiValue @"PSMultiValueSpecifier"
#define typeTextField @"PSTextFieldSpecifier"

@interface SettingsTableViewController ()

@end

@implementation SettingsTableViewController

- (id)initWithStyle: (UITableViewStyle)style
{
    self = [super initWithStyle: style];

    if (self) {
    }

    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Track rotation changes
    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(deviceOrientationDidChange) name: UIDeviceOrientationDidChangeNotification object: nil];

    // Avoid tab bar to overlap tableview
    self.edgesForExtendedLayout = UIRectEdgeAll;
    self.tableView.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, CGRectGetHeight(self.tabBarController.tabBar.frame), 0.0f);

    // Custom initialization
    labelViews = [NSMutableArray arrayWithObjects: nil];
    textViews = [NSMutableArray arrayWithObjects: nil];
    settingsTableSections = [NSMutableArray arrayWithObjects: nil];
    settingsTableData = [NSMutableArray arrayWithObjects: nil];
    settingsKeys = [NSMutableArray arrayWithObjects: nil];

    NSLog(@"Created arrays");


    NSString *settingsBundle = [[NSBundle mainBundle] pathForResource: @"Settings" ofType: @"bundle"];

    if(!settingsBundle) {

        NSLog(@"Could not find Settings.bundle");

    } else {

        NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent: @"Root.plist"]];
        NSArray *preferences = [settings objectForKey: @"PreferenceSpecifiers"];
        NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity: [preferences count]];

        for (NSDictionary *prefSpecification in preferences) {

            NSLog(@"%@", prefSpecification);

            NSString *title = [prefSpecification objectForKey: @"Title"];
            NSString *type = [prefSpecification objectForKey: @"Type"];

            if([type isEqualToString: typeGroup]) {

                // Create new section
                [settingsTableSections addObject: title];
                NSMutableArray *newSection = [NSMutableArray arrayWithObjects: nil];
                [settingsTableData addObject: newSection];

            } else {

                // Add specification to last section
                [[settingsTableData objectAtIndex: ([settingsTableData count] - 1)] addObject:prefSpecification];

            }
        }
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView
{
    // Return the number of sections.
    return [settingsTableSections count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [[settingsTableData objectAtIndex: section] count];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return [settingsTableSections objectAtIndex: section];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    // Get the dictionary item
    NSDictionary *prefSpecification = [[settingsTableData objectAtIndex: indexPath.section] objectAtIndex: indexPath.row];

    NSString *title = [prefSpecification objectForKey: @"Title"];
    NSString *key = [prefSpecification objectForKey: @"Key"];
    NSString *type = [prefSpecification objectForKey: @"Type"];

    // Define cell
    UITableViewCell *cell;

    // Keep tag of keys
    [settingsKeys addObject: key];
    int tag = [settingsKeys count] - 1;

    if([type isEqualToString: typeTitle]) {

        // Create cell
        cell = [tableView dequeueReusableCellWithIdentifier: @"Cell" forIndexPath:indexPath];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        // Set title
        cell.textLabel.text = title;

        // Add label
        UILabel *labelView = [[UILabel alloc] initWithFrame: CGRectMake(labelCGRectX, labelCGRectY, labelCGRectWidth, labelCGRectHeight)];
        labelView.text = [[NSUserDefaults standardUserDefaults] objectForKey: key];
        labelView.textAlignment = NSTextAlignmentRight;
        labelView.textColor = [UIColor grayColor];
        cell.accessoryView = labelView;

    }
    if([type isEqualToString: typeToggleSwitch]) {

        // Create cell
        cell = [tableView dequeueReusableCellWithIdentifier: @"Cell" forIndexPath:indexPath];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        // Set title
        cell.textLabel.text = title;

        // Add switch
        UISwitch *switchView = [[UISwitch alloc] initWithFrame: CGRectZero];
        cell.accessoryView = switchView;
        switchView.tag = tag;
        [switchView setOn: [[[NSUserDefaults standardUserDefaults] objectForKey: key] boolValue] animated: NO];

        // Connect action to switch
        [switchView addTarget: self action: @selector(switchChanged:) forControlEvents:UIControlEventValueChanged];

    }
    if([type isEqualToString: typeTextField]) {

        // Create cell
        cell = [tableView dequeueReusableCellWithIdentifier: @"Cell" forIndexPath:indexPath];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        int frameSize = self.view.frame.size.width;

        UITextField *textField = [[UITextField alloc] initWithFrame: CGRectMake(15, 10, frameSize,labelCGRectHeight)];
        textField.tag = tag;
        textField.text = [[NSUserDefaults standardUserDefaults] objectForKey: key];

        [textField addTarget: self
                      action: @selector(textFieldChanged:)
            forControlEvents: UIControlEventEditingChanged];

        [cell.contentView addSubview: textField];

        // Tract text field
        [textViews addObject: textField];
    }
    if([type isEqualToString: typeMultiValue]) {

        // Create cell
        cell = [tableView dequeueReusableCellWithIdentifier: @"MultiValueCell" forIndexPath:indexPath];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        // Get value
        int value = [[[NSUserDefaults standardUserDefaults] objectForKey: key] intValue];
        NSArray *values = [prefSpecification objectForKey: @"Values"];
        NSArray *titles = [prefSpecification objectForKey: @"Titles"];
        NSString *multiValue = @"Unknown";
        int index = [values indexOfObject: [NSString stringWithFormat: @"%d", value]];

        if(index >= 0 && index < [values count]) {
            multiValue = [titles objectAtIndex: index];
        }

        // Set title
        cell.textLabel.text = title;

        int frameSize = self.view.frame.size.width;

        // Add label
        UILabel *labelView = [[UILabel alloc] initWithFrame: CGRectMake((frameSize - labelCGRectWidth - 30), 12, labelCGRectWidth, labelCGRectHeight)];
        labelView.textAlignment = NSTextAlignmentRight;
        labelView.text = multiValue;
        labelView.textColor = [UIColor grayColor];

        [cell addSubview: labelView];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

        // Track label
        [labelViews addObject: labelView];
    }

    return cell;
}

- (void) switchChanged: (id) sender {
    UISwitch* switchControl = sender;

    NSString *key = [settingsKeys objectAtIndex: switchControl.tag];
    NSNumber *numberValue = [NSNumber numberWithBool: switchControl.on];

    [[NSUserDefaults standardUserDefaults] setObject: numberValue forKey: key];
}
- (void) textFieldChanged: (id) sender {
    UITextField* textControl = sender;

    NSString *key = [settingsKeys objectAtIndex: textControl.tag];
    NSString *stringValue = textControl.text;

    [[NSUserDefaults standardUserDefaults] setObject: stringValue forKey: key];
}

- (void) selectedMultiValue {
    [self reloadTable];
}

- (void) deviceOrientationDidChange {
    [self reloadTable];
}

- (void)prepareForSegue: (UIStoryboardSegue *) segue sender: (id) sender
{
    if ([[segue identifier] isEqualToString: @"changeMultiValue"])
    {
        MultiValueTableViewController *multiValueViewController =
        [segue destinationViewController];

        NSIndexPath *indexPath = [self.tableView
                                  indexPathForSelectedRow];

        // Get the dictionary item
        NSDictionary *prefSpecification = [[settingsTableData objectAtIndex: indexPath.section] objectAtIndex: indexPath.row];

        multiValueViewController.prefSpecification = prefSpecification;
        multiValueViewController.delegate = self;
    }
}

- (void) reloadTable {
    for (UILabel *labelView in labelViews) {
        [labelView removeFromSuperview];
    }
    for (UITextField *textView in textViews) {
        [textView removeFromSuperview];
    }

    // Remove references to objects for garbage collection
    labelViews = [NSMutableArray arrayWithObjects: nil];
    textViews = [NSMutableArray arrayWithObjects: nil];

    [self.tableView reloadData];
}

- (void) dealloc {
    // Remove observers
    [[NSNotificationCenter defaultCenter] removeObserver: self];
}
@end

MultiValueTableViewController.h

//
//  MultiValueTableViewController.h
//  Cochlear App
//
//  Created by Gilles Lesire on 16/07/14.
//  Free to use
//

#import <UIKit/UIKit.h>
#import "SettingsController.h"

@protocol MultiValueDelegate

- (void) selectedMultiValue;

@end

@interface MultiValueTableViewController : UITableViewController {
    NSDictionary *prefSpecification;
}

@property (nonatomic) id<MultiValueDelegate> delegate;
@property (strong, nonatomic) NSDictionary *prefSpecification;

@end

MultiValueTableViewController.m

//
//  MultiValueTableViewController.m
//  Cochlear App
//
//  Created by Gilles Lesire on 16/07/14.
//  Free to use
//

#import "MultiValueTableViewController.h"

@interface MultiValueTableViewController ()

@end

@implementation MultiValueTableViewController

@synthesize prefSpecification;

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSString *title = [prefSpecification objectForKey: @"Title"];
    self.navigationItem.title = title;

// Avoid tab bar to overlap tableview
self.edgesForExtendedLayout = UIRectEdgeAll;
self.tableView.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, CGRectGetHeight(self.tabBarController.tabBar.frame), 0.0f);
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSArray *values = [prefSpecification objectForKey: @"Values"];

    // Return the number of rows in the section.
    return [values count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: @"Cell" forIndexPath:indexPath];

    NSString *key = [prefSpecification objectForKey: @"Key"];
    NSArray *titles = [prefSpecification objectForKey: @"Titles"];
    NSArray *values = [prefSpecification objectForKey: @"Values"];
    NSString *title = [titles objectAtIndex: indexPath.row];

    // Create cell
    cell.selectionStyle = UITableViewCellSelectionStyleGray;

    // Set title
    cell.textLabel.text = title;

    // If this is the selected value
    if([[values objectAtIndex: indexPath.row] intValue] == [[[NSUserDefaults standardUserDefaults] objectForKey: key] intValue]) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *key = [prefSpecification objectForKey: @"Key"];
    NSArray *values = [prefSpecification objectForKey: @"Values"];

    NSNumber *value = [values objectAtIndex: indexPath.row];

    [[NSUserDefaults standardUserDefaults] setObject: value forKey: key];

    [self.delegate selectedMultiValue];
    [self.tableView reloadData];
}

@end

故事板现在转到故事板并创建一个TableViewController。选择TableViewController并选择&#34;编辑器&#34; - &GT; &#34;嵌入&#34; - &GT; &#34;导航控制器&#34;。

将TableViewController的类设置为SettingsTableViewController。将单元格的标识符设置为&#34; Cell&#34;,将第二个TableViewCell添加到TableView并将其标识符设置为&#34; MultiValueCell&#34;。添加第二个TableViewController,然后按CTRL + CLICK并从MultiValueCell拖动到第二个TableViewController。将第二个TableViewController的类设置为MultiValueTableViewController。在第二个TableViewController中将单元格的标识符设置为&#34; Cell&#34;太。那就是它!

答案 2 :(得分:0)

#import "SettingViewController.h"
NSInteger selectedIndex;
//Use this, it works for me 

- (void)viewDidLoad
{
selectedIndex = 0;
    [super viewDidLoad];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 50.0f;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [_arrayForSaveSetting count];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = nil;

    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
    if (indexPath.row==selectedIndex) {
        cell.accessoryType =UITableViewCellAccessoryCheckmark;
    }

    return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    selectedIndex=indexPath.row;   
    [_tblSaveSetting reloadData];
}