iOS学习之应用偏好设置

简介:

如今,即便是最简单的计算机程序也会包含一个偏好设置窗口,用户可以在其中设置应用专属的选项。在MAC OS X中,Preferences...菜单通常位于应用菜单中。选择该菜单项会弹出一个窗口,用户可以在其中输入和更改各种选项。iPhone和其他iOS设备有一个专门的“设置”应用程序来进行各种设置,你肯定用过很多次了。

设置捆绑包

通过应用设置,用户可以输入和更改任何带有设置捆绑包(settings bundle)的应用中的偏好设置。设置捆绑包是应用自带的一组文件,用于告诉设置该应用期望得到用户的哪些偏好设置。下图是实例效果图:

       

对于iOS用户默认设置(User Defaults)机制,设置应用充当着通用用户界面的角色。用户默认设置是保存和获取偏好设置的系统的一部分。

在iOS应用中,用户默认设置由NSUserDefaults类实现。应用通过NSUserDefaults用键值对的方式来读取和保存偏好设置数据,与通过键从NSDictionary对象中获取数据一样。不同之处在于NSUserDefaults数据会被持久保存在文件系统中,而不是存储在内存的对象实例中。

应用

接下来的部分,通过创建一个简单的应用,来实现应用设置控制应用程序。

创建应用

在Xcode中,创建Tabbed Application工程。

使用设置捆绑包

设置应用使用每个应用中设置捆绑包的内容构建出一个应用的设置视图。如果应用没有设置捆绑包,则设置应用不会显示出应用程序的任何信息。每个设置捆绑包必须包含一个名为Root.plist的属性列表,它定义了根级偏好设置视图。此属性列表必须遵循一种非常严格的格式。

当设置应用启动时,它会检查每个应用程序的设置捆绑包并为包含设置捆绑包的每个应用添加设置组。

在项目中添加设置捆绑包

新建设置捆绑包,操作如下图

在iOS-->Resource-->Settings Bundle点击Next,名字保留默认,最后点击Create即可。

编辑属性列表文件

接下来需要编辑Root.plist文件,具体内容如下图

在Item8中,引用的More.plist文件,具体内容如下图

这里需要补充说明一点:

iOS上的应用不能从其他应用的沙盒中读取文件。设置捆绑包并不是我们应用沙盒的一部分,而是设置应用沙盒的一部分。

设计展示界面

数据准备好之后,添加图标资源,设计数据展示界面。效果图如下

    

界面是通过代码实现的,主要使用了如下几个控件:


@interface FirstViewController ()

@property (nonatomic, strong) UILabel *officerLabel;
@property (nonatomic, strong) UILabel *authorizationCodeLabel;
@property (nonatomic, strong) UILabel *rankLabel;
@property (nonatomic, strong) UILabel *warpDriveLabel;
@property (nonatomic, strong) UILabel *warpFactorLabel;
@property (nonatomic, strong) UILabel *favoriteTeaLabel;
@property (nonatomic, strong) UILabel *favoriteCaptainLabel;
@property (nonatomic, strong) UILabel *favoriteGadgetLabel;
@property (nonatomic, strong) UILabel *favoriteAlienLabel;

@end

@interface SecondViewController ()

@property (nonatomic, strong) UISwitch *engineSwitch;
@property (nonatomic, strong) UISlider *warpFactorSlider;
@property (nonatomic, strong) UIButton *settingInfo;

@end

读取应用中的设置

我们将使用NSUserDefaults类访问用户设置。NSUserDefaults作为单例类,意味着应用中只能有一个NSUserDefaults实例在运行。为了访问这个实例,需要调用standardUserDefaults。


#ifndef BridgeControl_Constants_h
#define BridgeControl_Constants_h

#define kOfficerKey @"officer"
#define kAuthorizationCodeKey @"authorizationCode"
#define kRankKey @"rank"
#define kWarpDriveKey @"warp"
#define kWarpFactorKey @"warpFactor"
#define kFavoriteTeaKey @"favoriteTea"
#define kFavoriteCaptionKey @"favoriteCaptain"
#define kFavoriteGadgetKey @"favoriteGadget"
#define kFavoriteAlienKey @"favoriteAlien"

#endif

更新主视图控制器


//FirstViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self refreshFields];
}

-(void)refreshFields{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    self.officerLabel.text = [defaults objectForKey:kOfficerKey];
    self.authorizationCodeLabel.text = [defaults objectForKey:kAuthorizationCodeKey];
    self.rankLabel.text = [defaults objectForKey:kRankKey];
    self.warpDriveLabel.text = [defaults boolForKey:kWarpDriveKey] ? @"engaged" : @"Disabled";
    self.warpFactorLabel.text = [[defaults objectForKey:kWarpFactorKey] stringValue];
    self.favoriteTeaLabel.text = [defaults objectForKey:kFavoriteTeaKey];
    self.favoriteCaptainLabel.text = [defaults objectForKey:kFavoriteCaptionKey];
    self.favoriteGadgetLabel.text = [defaults objectForKey:kFavoriteGadgetKey];
    self.favoriteAlienLabel.text = [defaults objectForKey:kFavoriteAlienKey];
}


//SecondViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self refreshFields];
}

-(void)refreshFields{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    self.engineSwitch.on = [defaults boolForKey:kWarpDriveKey];
    self.warpFactorSlider.value = [defaults floatForKey:kWarpFactorKey];
}

添加控件响应事件

为SecondViewController中的UIButton,UISwitch和UISlider控件添加监听事件。


- (void)engineSwitchTapped {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setBool:self.engineSwitch.on forKey:kWarpDriveKey];
    [defaults synchronize];
}

- (void)warpSliderTouched {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setFloat:self.warpFactorSlider.value forKey:kWarpFactorKey];
    [defaults synchronize];
}
//切换到“设置”应用程序
-(void)settingInfoClicked{
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}

注册默认值


//AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    //程序启动后的一些自定义设置
    NSDictionary *defaults = @{kWarpDriveKey:@YES,
                               kWarpFactorKey:@2,
                               kFavoriteAlienKey:@"Vulcan"
                               };
    [[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
    
    return YES;
}

保证设置有效

如果现在将应用运行,查看设置信息并按下主屏幕按钮来修改一些值。然后再按Home键,再重新打开应用,结果发现设置并没有生效。

原因在于:在iOS中,当应用正在运行时按Home键并不会退出该应用,而是由操作系统在后台将其暂停,这样它就能随时快速启动。

在这个例子中,我们需要添加一点工作,以实现应用被唤醒时,能重新加载用户偏好设置并重新显示它们。

通知,时对象之间进行通信的轻量级机制。任何对象都能定义一个或多个发送到应用通知中心的通知。通知中心是一个单例对象,作用在于对象之间传送通知。

UIApplication类会发送大量的通知,大多数通知的用途从命名就能看出来,这个例子中我们就使用到了通知。

将下列代码添加到两个控制器的viewDidLoad方法中:


UIApplication *app = [UIApplication sharedApplication];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:app];


然后添加相应的响应方法

-(void)applicationWillEnterForeground:(NSNotification *)notification{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults synchronize];
    [self refreshFields];
}

小结

本文主要讲解了如何使用应用设置,如何使用NSUserDefaults读取偏好设置,以及如何让用户在应用内修改偏好设置。

 

实例源代码地址:https://github.com/CharsDavy/BridgeControl


目录
相关文章
|
6天前
|
Swift iOS开发 UED
揭秘一款iOS应用中令人惊叹的自定义动画效果,带你领略编程艺术的魅力所在!
【9月更文挑战第5天】本文通过具体案例介绍如何在iOS应用中使用Swift与UIKit实现自定义按钮动画,当用户点击按钮时,按钮将从圆形变为椭圆形并从蓝色渐变到绿色,释放后恢复原状。文中详细展示了代码实现过程及动画平滑过渡的技巧,帮助读者提升应用的视觉体验与特色。
27 11
|
11天前
|
API iOS开发
探索iOS开发:打造你的第一个天气应用
【8月更文挑战第31天】 在这篇文章中,我们将一起潜入iOS开发的海洋,从初学者的角度出发,一步步构建我们自己的天气应用。通过实际的项目实践,你将学习到如何获取网络数据、如何在界面上展示这些数据,以及如何处理用户交互。文章以通俗易懂的语言,结合代码示例,引导你理解并实现一个简单天气应用的核心功能。无论你是编程新手还是希望扩展你的iOS开发技能,这篇文章都将为你提供宝贵的指导和启发。
|
3天前
|
开发工具 Android开发 iOS开发
探索安卓与iOS开发的差异:构建未来应用的关键考量
在数字时代的浪潮中,安卓和iOS这两大操作系统如同双子星座般耀眼夺目,引领着移动应用的潮流。它们各自拥有独特的魅力和深厚的用户基础,为开发者提供了广阔的舞台。然而,正如每枚硬币都有两面,安卓与iOS在开发过程中也展现出了截然不同的特性。本文将深入剖析这两者在开发环境、编程语言、用户体验设计等方面的显著差异,并探讨如何根据目标受众和项目需求做出明智的选择。无论你是初涉移动应用开发的新手,还是寻求拓展技能边界的资深开发者,这篇文章都将为你提供宝贵的见解和实用的建议,帮助你在安卓与iOS的开发之路上更加从容自信地前行。
|
11天前
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
61 0
|
11天前
|
JSON API 定位技术
探索iOS开发之旅:打造你的第一个天气应用
【8月更文挑战第31天】 在这篇文章中,我们将一起踏上iOS开发的冒险旅程,学习如何从零开始构建一个简单的天气应用。通过实际操作和代码示例,你将了解到如何在Xcode中设置项目、使用Swift语言编写代码、以及接入第三方API来获取实时天气数据。无论你是刚入门的新手还是想扩展知识的开发者,这篇文章都将为你提供有价值的指导和灵感。
|
11天前
|
存储 搜索推荐 IDE
打造个人iOS记事本应用:从零开始
【8月更文挑战第31天】 在这篇文章中,我们将一起探索如何构建一个简单但功能齐全的iOS记事本应用。通过逐步引导,你将学会如何使用Swift语言和Xcode工具,从设计界面到实现数据存储,再到部署到设备上的每一个细节。无论你是编程新手还是希望拓展你的iOS开发技能,这篇文章都将为你提供一个实际操作的机会,让你能够动手实践并见证自己作品的诞生。
|
11天前
|
JSON 搜索推荐 定位技术
打造个性化天气应用:iOS开发实战
【8月更文挑战第31天】在这篇文章中,我们将一起探索如何从零开始构建一个iOS天气应用。通过简单易懂的步骤,你将学习到如何使用Swift编程语言和苹果的开发工具Xcode来实现这个目标。我们会涉及到用户界面设计、网络编程以及数据解析等关键技能,确保你能够顺利地完成这个项目。无论你是初学者还是有一定经验的开发者,这篇文章都会带给你新的启发和收获。