0826-DataPicker
采用c ios/2、其次看/2014 5期/5-8月/03高级ui/0603点菜国旗 ---- 0604UIwindow
-------------
UIPickerView 滚动选择
1、storyboard直接拖 UIPickerView 连线datasource delegate代理到view Controller
2、实现数据源方法 numberOfcomponentInPickerView 和 numberOfRowInComponent (row 和component都是整数)
3、实现delegate titleForRow
4、懒加载plist中的array数据
5、显示设置数组数据到label中
6、初始化选中的pickerView的某行 某列 didSelect 代理方法
7、连线点击 arc4random() %12 相当于 (但是arc4random(0,12);//错误)
连线pickerView [self.pickerView selectRow***] selectRow animation 代理方法
随机后pickeView选择的rowInComponent 做判断while 如果随机数 就重新随机
代码:
// NJViewController.m // 01-点菜 #import "NJViewController.h" @interface NJViewController ()<UIPickerViewDataSource, UIPickerViewDelegate> @property (weak, nonatomic) IBOutlet UIPickerView *pickerView; /** * 随机按钮点击事件 */ - (IBAction)randomFood:(UIButton *)sender; /** * 所有食物 */ @property (nonatomic, strong) NSArray *foods; /** * 水果 */ @property (weak, nonatomic) IBOutlet UILabel *fruitLabel; /** * 主菜 */ @property (weak, nonatomic) IBOutlet UILabel *stapleLabel; /** * 饮料 */ @property (weak, nonatomic) IBOutlet UILabel *drinkLabel; @end @implementation NJViewController - (void)viewDidLoad { [super viewDidLoad]; // 设置默认选中的内容 // self.fruitLabel.text = self.foods[0][0]; // self.stapleLabel.text = self.foods[1][0]; // self.drinkLabel.text = self.foods[2][0]; // [self pickerView:nil didSelectRow:0 inComponent:0]; // [self pickerView:nil didSelectRow:0 inComponent:1]; // [self pickerView:nil didSelectRow:0 inComponent:2]; for (int component = 0; component < self.foods.count; component++) { [self pickerView:nil didSelectRow:0 inComponent:component]; } } #pragma mark - UIPickerViewDataSource // 返回pickerView一共有多少列 - (NSInteger) numberOfComponentsInPickerView:(UIPickerView *)pickerView { // return 3; return self.foods.count; } // 返回pickerView的第component列有多少行 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { // return 4; // 1.获取对应列的数组 NSArray *subFoods = self.foods[component]; // 2.返回对应列的行数 return subFoods.count; } #pragma mark - UIPickerViewDelegate // 返回第component列的第row行显示什么内容 - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { // 1.获取对应列的数组 NSArray *subFoods = self.foods[component]; // 2.获取对应行的标题 NSString *name = subFoods[row]; return name; } // 当选中了pickerView的某一行的时候调用 // 会将选中的列号和行号作为参数传入 // 只有通过手指选中某一行的时候才会调用 - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { // NSLog(@"component = %d, row = %d", component, row); // 1.获取对应列对应行的数据 NSString *name = self.foods[component][row]; // NSLog(@"name = %@", name); // 2.判断选择的是哪一列, 根据列号设置对应的数据 if (0 == component) { // 水果 self.fruitLabel.text = name; }else if (1 == component) { // 主菜 self.stapleLabel.text = name; }else { // 饮料 self.drinkLabel.text = name; } } #pragma mark - 懒加载 - (NSArray *)foods { if (_foods == nil) { NSString *fullPath = [[NSBundle mainBundle] pathForResource:@"foods.plist" ofType:nil]; _foods = [NSArray arrayWithContentsOfFile:fullPath]; } return _foods; } #pragma mark - 监听按钮点击 - (IBAction)randomFood:(UIButton *)sender { // 让pickerView主动选中某一行 // 让pickerView选中inComponent列的Row行 // [self.pickerView selectRow:1 inComponent:0 animated:YES]; /* [self.pickerView selectRow: arc4random() % 12 inComponent:0 animated:YES]; [self.pickerView selectRow: arc4random() % 15 inComponent:1 animated:YES]; [self.pickerView selectRow: arc4random() % 10 inComponent:2 animated:YES]; */ // [self.foods objectAtIndex:0]; == self.foods[0]; // [self.foods[0] count]; /* // 根据每一列的元素个数生成随机值 [self.pickerView selectRow: arc4random() % [self.foods[0] count] inComponent:0 animated:YES]; [self.pickerView selectRow: arc4random() % [self.foods[1] count] inComponent:1 animated:YES]; [self.pickerView selectRow: arc4random() % [self.foods[2] count] inComponent:2 animated:YES]; */ for (int component = 0; component < self.foods.count; component++) { // 获取对应列的数据总数 int total = [self.foods[component] count]; // 根据每一列的总数生成随机数(当前生成的随机数) int randomNumber = arc4random() % total; // 获取当前选中的行(上一次随机后移动到的行) int oldRow = [self.pickerView selectedRowInComponent:0]; // NSLog(@"oldRow = %d", oldRow); // 比较上一次的行号和当前生成的随机数是否相同, 如果相同重新生成 while (oldRow == randomNumber) { randomNumber = arc4random() % total; } // 让pickerview滚动到某一行 [self.pickerView selectRow: randomNumber inComponent:component animated:YES]; // 通过代码选中某一行 [self pickerView:nil didSelectRow:randomNumber inComponent:component]; } } @end
滚动到哪里的操作应该由pickerView自身完成 所以是pickerView的自身方法 而不是通知代理来完成
[self.pickerView selectRow:randomNumber inComponent:component animated:YES];
-------------------
UIPickerView 城市联动 代码创建pickerView
并挂载到self.view (pickerView默认有frame)
1、拷贝写好的模型代码
2、[pickerView reloadComponent:1]; 刷新第一列数据
pickerView selectedRowIncomponent: 被选中的行
// ViewController.m // 21-pickerView-城市联动 #import "ViewController.h" #import "NJProvince.h" @interface ViewController ()<UIPickerViewDataSource,UIPickerViewDelegate> // 保存数据的属性 @property (nonatomic, strong) NSArray *provinces; @property (nonatomic,strong) UIPickerView *pickerView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UIPickerView *pickerView = [[UIPickerView alloc] init]; pickerView.delegate = self; pickerView.dataSource = self; [self.view addSubview:pickerView]; self.pickerView = pickerView; } #pragma mark - 加载数组包数据 - (NSArray *)provinces { if (_provinces == nil) { // 加载资源 NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cities" ofType:@"plist"]]; // 转换为模型 NSMutableArray *models = [NSMutableArray arrayWithCapacity:array.count]; for (NSDictionary *dict in array) { NJProvince *province = [NJProvince provinceWithDictionary:dict]; [models addObject:province]; } _provinces = [models copy]; } return _provinces; } #pragma mark - pickerView数据源方法 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 2; } - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { if (component == 0) { return self.provinces.count; }else { // 城市列 // 获取第0列选中的行 NSInteger selectIndex = [self.pickerView selectedRowInComponent:0]; // 1.根据第0列选中的行数获取对应的省 NJProvince *province = self.provinces[selectIndex]; // 2.获取对应省份对应的城市 NSArray *cities = province.cities; // 3.返回城市的个数r return cities.count; } } #pragma mark - pickerView代理方法 -(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { if (0 == component) { // 省份 // 1.获取对应行对应的省份模型 NJProvince *province = self.provinces[row]; // 2.返回省份的名称 return province.name; }else { // 城市列 // 0.获取第0列选中的行数 NSInteger selectIndex = [pickerView selectedRowInComponent:0]; // 1.获取对应的省份 NJProvince *province = self.provinces[selectIndex]; // 2.获取对应的城市 return province.cities[row]; } } #pragma mark - 选中第一列某行 刷新第2列城市数据 并滚动到第行 -(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { if (0 == component) { // 刷新第1列对应的数据 [pickerView reloadComponent:1]; // 让第1列滚动到第0行 [pickerView selectRow:0 inComponent:1 animated:NO]; // [pickerView selectRow:0 inComponent:1 animated:YES]; } } @end
---------
UIPickerView 国旗选择 -单列图文混合
实现方法 viewForRow
自定义UIView+xib 里面放入 uilabel 和 uiimageview
懒加载数据
数据给自定义的view view设置label文字 和图片属性
设置rowHeightForComponent 44
自定义view里定义一个方法返回44 方便以后修改
// // ViewController.m // 22-pickerview-自定义view图文混合 #import "ViewController.h" #import "NJCountry.h" #import "NJCountryView.h" @interface ViewController ()<UIPickerViewDataSource,UIPickerViewDelegate> @property (nonatomic, strong) NSArray *countrys; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } #pragma mark - pickerView数据源方法 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 1; } - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { return self.countrys.count; } #pragma mark - pickerView代理方法 //-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component //{ // return @"菜品一"; //} -(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view { NJCountryView *countryView = (NJCountryView *)view; if (countryView == nil) { NSLog(@"创建新的自定义view"); countryView = [NJCountryView countryView]; } // 2.赋值模型数据 countryView.country = self.countrys[row]; // 3.返回自定义view return countryView; } #pragma mark - 国家文字和图片数据 - (NSArray *)countrys { if (_countrys == nil) { // 1.加载plist文件内容 NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"flags.plist" ofType:nil]]; // 2.创建数组保存转换后的模型 NSMutableArray *models = [NSMutableArray arrayWithCapacity:dictArray.count]; // 3.字典转模型 for (NSDictionary *dict in dictArray) { NJCountry *flag = [NJCountry countryWithDictionary:dict]; [models addObject:flag]; } _countrys = models; } return _countrys; } #pragma mark - 设置行高 -(CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component { return [NJCountryView rowHeight]; } @end
-----------
DataPicker日期选择器拖控件认识一下
viewController里直接拖 UIDatePicker
1、设置本地化 手机模拟器设置中文 和 datepicker 属性 locale设置为中文
2、设置时间模式 dadepicker 属性mode设置为 时间和日期
3、初始时间 设置属性 date设置为 current time 当前时间 选择custom选择 初始时间
4、date为custom 下面设置最小选择时间和最大选择时间范围 超出这个选择时间会自动回复到最小或者最大时间位置
设置日期显示模式
datePicker.datePickerMode = UIDatePickerModeDate;
设置为datepicker显示为中文
找到 里面有localizations可以查看国家的标识符号
datePicker.locale = [NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];//
---------
UIToolBar和bar button item控件设置
拖动Toolbar里拖 bar button item 设置identifier属性为flexible space 就变成了小弹簧 能分开2个bar button item控件
Toolbar(只能拖bar button item类型控件) 小弹簧为lexible space bar button item
【 上一个 下一个 flexiblespace 完成】
------------------------
代码实现TextField 弹出datePicker
代码实现input输入时候 弹出 datePicker和自定义的toolBar
(
实现方法1 简单推荐
1、连线TextField (以下开始纯代码)
2、创建datePicker对象设置 日期模式
设置国家locale
3、self.textField.inputView = datePicker
这里是任何控件都可以 都从底部弹出
4、self.textField.accessoryViews = @[bar button item,bar button item]
5、点击完成的bar button item 得到设置textField的文字 并退出键盘
NSDate *date = self.dateView.date;
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy-MM-dd";
self.birthdayField.text = [formatter stringFromDate:date];
注意: 必须制定toolbar的frame 或bounds
UIToolbar *toolBar = [[UIToolbar alloc] init];
toolBar.bounds = CGRectMake(0, 0, 320, 44);
// ViewController.m // 23-datepicker-日期选择 #import "ViewController.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UITextField *textFieldLabel; @property (nonatomic,strong) UIDatePicker *datePicker; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UIToolbar *toolBar = [[UIToolbar alloc] init]; toolBar.bounds = CGRectMake(0, 0, 320, 44); //上一个 UIBarButtonItem *bar1 = [[UIBarButtonItem alloc] initWithTitle:@"上一个" style:UIBarButtonItemStylePlain target:nil action:nil]; //下一个 UIBarButtonItem *bar2 = [[UIBarButtonItem alloc] initWithTitle:@"下一个" style:UIBarButtonItemStylePlain target:nil action:nil]; //可伸缩弹簧 UIBarButtonItem *bar3 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; //完成 UIBarButtonItem *bar4 = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStylePlain target:self action:@selector(done)]; toolBar.items = @[bar1,bar2,bar3,bar4]; UIDatePicker *datePicker = [[UIDatePicker alloc] init]; datePicker.datePickerMode = UIDatePickerModeDate; NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh"]; datePicker.locale = locale; self.textFieldLabel.inputView = datePicker; self.textFieldLabel.inputAccessoryView = toolBar; self.datePicker = datePicker; // NSLog(@"%@",[NSLocale availableLocaleIdentifiers]); } - (void)done { NSDate *date = self.datePicker.date; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; dateFormatter.dateFormat = @"yyyy-MM-dd"; self.textFieldLabel.text = [dateFormatter stringFromDate:date]; [self.textFieldLabel resignFirstResponder]; } @end
实现方法2 麻烦一些
1、连线TextField (以下开始纯代码)
2、自定义UIView 计算frame (考虑放入 toolbar 和 datepicker的高度)
3、自定义view里添加toolbar toolbar里添加几个 bar button item
4、self.textField.inputView = 自定义UIView
)
-----------------------------
xcode程序常见文件夹和文件
xcode-products文件夹做mac开发用的 iphone开发没有用
Framework下的框架 是开发中所依赖的框架 如fundation框架 xcode-6.4没有这个文件夹了
Test下文件是单元测试用的
InfoPlist.Strings做本地化语言用的
----------------
info.plist文件
info.plist应用程序的配置
修改info.plist 后需要 到模拟器上把应用程序删除 并把xcode product->clean清楚缓存一下
( info.plist也可以在图形化界面里修改 在xcode点击应用程序文件-》genral里设置
bundle display name - 应用程序名称
bundle identifier - 应用程序唯一标识 命名规则倒写域名+应用程序名称
bundle version string,short - 正式的版本号 在itunes上查看到等 app store上传应用程序 后面的版本号数字必须要比大于前一次 否则审核不通过
bundle version - 公司内部人员查看的版本
main storyboard file base name - 首次加载的storyboard名称 如:main
supported interface orientations 屏幕支持的旋转方向
)
----------------
pch文件使用注意
(
作用
pch文件的应用常见 用来定义一些全局的宏 #define Number 10 用来导入一些全局都能用到的头文件 用来自定义log
// __OBJC__这个宏,在所有的.m和.mm文件中默认就定义了这个宏 #ifdef __OBJC__ // 如果这个全局的头文件或者宏只需要在.m或者.mm文件中使用, // 请把该头文件或宏写到#ifdef __OBJC__ 中 // 因为 项目中所有文件都会导入这个文件包括.c文件 但是.c文件没有定义__OBJC__ #import <UIKit/UIKit.h> #import <Foundation/Foundation.h> #define ABC 55 #import "Constant.h"
#ifdef DEBUG 如果程序处于开发阶段 系统会自动定义DEBUG宏 , 如果程序处于发布阶段 系统会删除DEBUG宏定义 #define NJLog(...) NSLog(__VA_ARGS__) ... 代表多个参数 如:NJLog(@"%@-%@-%@-%@",a,b,c,d); NSLog(__VA_ARGS__)为固定写法 NJLog(***)自动转为了NSLog(***)了 #else #define NJLog(...) 去公司第一件事就是看看pch文件 查看Log的替代写法 以后都使用这种方式打印Log 否则会很惨 发布阶段自动删除 NJLog(***) 变成空了 #endif #endif #define Number 10 #import "NJGlobal.h" //如果头文件里用了大量大 #if #endif 应该在这里定义
)
--------
------------------------
UIApplication对象
每一个应用程序都有一个UIApplication对象
1、UIApplication对象作用:
UIApplication对象代表着该应用程序 可以进行应用级别的操作,
控制器也可以进行应用级别的操作(IOS7以前都是通过UIApplication对象操作的),是因为这样就可以让每个控制器的一些应用状态不一样
如viewController.m -> preferredStatusBarStyle(return ***)
UIApplication *app = [UIApplication sharredApplication]; app.preferredStatusBarStyle = ***
特别的地方:
UIApplication对象默认不能管理状态栏(其他应用级别操作都可以,单单状态栏这个不可以),需要设置info.plist文件 最后增加一条属性 (禁用viewController设置状态栏status bar)
View controller-based status bar appearance
2、获取UIApplication对象
[UIApplication sharedApplication]只能通过这个方法 获取单例对象
3、UIApplication对象创建时间
应用程序启动-》创建的第一个对象就是UIApplication对象
// NJViewController.m // 06-UIApplication #import "NJViewController.h" @interface NJViewController () @end @implementation NJViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // UIApplication *app = [UIApplication sharedApplication]; // UIApplication *app1 = [UIApplication sharedApplication]; //// UIApplication *app2 = [[UIApplication alloc] init]; // NSLog(@"%p - %p ", app, app1); UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)]; [btn setTitle:@"点我啊" forState:UIControlStateNormal]; [btn addTarget:self action:@selector(onClick) forControlEvents:UIControlEventTouchUpInside]; btn.backgroundColor = [UIColor redColor]; [self.view addSubview:btn]; } - (void)onClick { // NSLog(@"被点了"); UIApplication *app = [UIApplication sharedApplication]; // 设置应用程序图标上的数字 // app.applicationIconBadgeNumber = 998; // 设置状态栏的联网动画 // app.networkActivityIndicatorVisible = YES; // 设置状态栏的样式 // app.statusBarStyle = UIStatusBarStyleLightContent; // [app setStatusBarStyle:UIStatusBarStyleLightContent animated:YES]; // 设置状态栏是否隐藏 // app.statusBarHidden = YES; // [app setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade]; /* URL:统一资源定位符 , 用来唯一的表示一个资源 URL: 协议头://主机地址/资源路径 网络资源:http://www.baidu.com/images/20140603/abc.png 本地资源:file:///users/apple/desktop/abc.png */ NSURL *url = [NSURL URLWithString:@"http://ios.itcast.cn"]; [app openURL:url]; } //- (UIStatusBarStyle)preferredStatusBarStyle //{ // return UIStatusBarStyleLightContent; //} //- (BOOL)prefersStatusBarHidden //{ // return YES; //} @end
-------------
UIApplication的delegate对象
应用程序被打扰 -》进入后台 -》时间长了随时被关闭
UIApplication对象通知delegate来处理一些事情
如:开启和关闭应用程序(应用程序生命周期事件)
来电提醒(系统事件)
内存警告
UIApplicationDelegate 协议
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application;
- (void)applicationDidEnterBackground:(UIApplication *)application;
- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
id<UIApplicationDelegate> delegate
应用程序创建完成就已经有了 @interface AppDelegate:UIResponse<UIApplicationDelegate>对象并遵守了协议 ApplicationDelegate.h 和.m实现了代理方法
#import <UIKit/UIKit.h>
@interface AppDelegate:UIResponse<UIApplicationDelegate>
@property (strong,nonatomic) UIWindow *window;
@end
文档搜索 apps states 讲解应用程序启动过程和状态 等 要看看
inactive是即将进入active的前台时间很短 background 5秒钟内进入 suspended挂起状态 长时间挂起状态 程序可能被关闭not running
xcode->硬件-》模拟内存警告
// // NJAppDelegate.m #import "NJAppDelegate.h" @implementation NJAppDelegate // 当应用程序启动完毕的时候就会调用(系统自动调用) - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. NSLog(@"didFinishLaunchingWithOptions"); return YES; } // 即将失去活动状态的时候调用(失去焦点, 不可交互) - (void)applicationWillResignActive:(UIApplication *)application { NSLog(@"ResignActive"); } // 重新获取焦点(能够和用户交互) - (void)applicationDidBecomeActive:(UIApplication *)application { NSLog(@"BecomeActive"); } // 应用程序进入后台的时候调用 // 一般在该方法中保存应用程序的数据, 以及状态 - (void)applicationDidEnterBackground:(UIApplication *)application { NSLog(@"Background"); } // 应用程序即将进入前台的时候调用 // 一般在该方法中恢复应用程序的数据,以及状态 - (void)applicationWillEnterForeground:(UIApplication *)application { NSLog(@"Foreground"); } // 应用程序即将被销毁的时候会调用该方法 // 注意:如果应用程序处于挂起状态的时候无法调用该方法 - (void)applicationWillTerminate:(UIApplication *)application { } // 应用程序接收到内存警告的时候就会调用 // 一般在该方法中释放掉不需要的内存 - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { NSLog(@"MemoryWarning"); } @end
----------------
ios程序启动过程和UIWindow
1、
int main(int argc, char * argv[]) { @autoreleasepool { /* argc: 系统或者用户传入的参数个数 argv: 系统或者用户传入的实际参数 */ // return UIApplicationMain(argc, argv, nil, NSStringFromClass([NJAppDelegate class])); // return UIApplicationMain(argc, argv, @"UIApplication", NSStringFromClass([NJAppDelegate class])); /* 进入UIApplicatinMain方法的定义里看到说明如下: 1.根据传入的第三个参数创建UIApplication对象 2.根据传入的第四个产生创建UIApplication对象的代理 3.设置刚刚创建出来的代理对象为UIApplication的代理
查看info.plist文件中的main storyboard file name 为 Main ->根据main.storyboard 创年vc.view 和vc -》程序加载完毕 4.开启一个事件循环
监听到程序加载完毕事件
UIApplication对象通知其delegate 执行didFinishLaunchingWithOptions (AppDelegate继承自ViewController)
5、self.window.rootViewController = vc赋值 */ return UIApplicationMain(argc, argv, @"UIApplication", @"NJAppDelegate"); //UIApplicationMain函数里有一个While循环 所以不会返回 否则程序就结束了 } }
2、