引言

一个iOS程序之所以能显示到屏幕上,完全是因为它有UIWindow;也就说,没有UIWindow,就看不见任何UI界面。

I UIWindow

键盘也是UIWindow

1.1 添加View到UIWindow中的方式

两种常用方式

- (void)addSubview:(UIView *)view;//直接将UIView添加到UIWindow中,但并不会理会view对应的UIViewController
@property(nullable, nonatomic,strong) UIViewController *rootViewController NS_AVAILABLE_IOS(4_0);  // default is nil;自动将rootViewController的view添加到UIWindow中,负责管理rootViewController的生命周期

1.2 常用方法

makeKeyWindow、makeKeyAndVisible

- (void)makeKeyWindow;//让当前UIWindow变成keyWindow(主窗口)Makes the receiver the main window.
- (void)makeKeyAndVisible; // convenience. most apps call this to show the main window and also make it key. otherwise use view hidden property;Makes the receiver the key window and visible.让当前UIWindow变成keyWindow,并显示出来

1.3 UIWindow的对象获取

获取UIWindow

/**方式一:@property(nonatomic,readonly) NSArray<__kindof UIWindow *>  *windows;  */
[UIApplication sharedApplication].windows//在本应用中打开的UIWindow列表,这样就可以接触应用中的任何一个UIView对象(平时输入文字弹出的键盘,就处在一个新的UIWindow中)
/** 方式二:@property(nullable, nonatomic,readonly) UIWindow *keyWindow;*/
[UIApplication sharedApplication].keyWindow//用来接收键盘以及非触摸类的消息事件的UIWindow,而且程序中每个时刻只能有一个UIWindow是keyWindow。如果某个UIWindow内部的文本框不能输入文字,可能是因为这个UIWindow不是keyWindow
/** 方式三:@property(nullable, nonatomic,readonly) UIWindow *window;*/
view.window//获得某个UIView所在的UIWindow

II 案例

2.1点菜系统

iOS小技能:特殊的UIView(UIWindow)_ios

/

// ViewController.m

// 20160331-点菜系统

//

// Created by devzkn on 3/31/16.

// Copyright © 2016 hisun. All rights reserved.

//




#import "ViewController.h"




@interface ViewController () <UIPickerViewDataSource,UIPickerViewDelegate>

@property (weak, nonatomic) IBOutlet UILabel *mainLabel;

@property (weak, nonatomic) IBOutlet UILabel *drinkLabel;

@property (nonatomic,strong) NSArray *foodsData;

@property (weak, nonatomic) IBOutlet UILabel *fruitLabel;

@property (weak, nonatomic) IBOutlet UIPickerView *pickerView;




@end




@implementation ViewController




-(NSArray *)foodsData{

if (nil == _foodsData) {

_foodsData = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"foods" ofType:@"plist"]];

}

return _foodsData;

}




- (void)viewDidLoad {

[super viewDidLoad];

//初始化label数据

[self.fruitLabel setText:self.foodsData[0][0]];

[self.mainLabel setText:self.foodsData[1][0]];

[self.drinkLabel setText:self.foodsData[2][0]];





}

/** 产生随机的下标 */
- (IBAction)randomMenu {
/** 方式一 */
// int row0 = arc4random_uniform([self.foodsData[0] count]);
// int row1 = arc4random_uniform([self.foodsData[1] count]);
// int row2 = arc4random_uniform([self.foodsData[2] count]);
// [self pickerView:self.pickerView didSelectRow:row0 inComponent:0];
// [self pickerView:self.pickerView didSelectRow:row1 inComponent:1];
// [self pickerView:self.pickerView didSelectRow:row2 inComponent:2];
// //切换pickerView的选择的行,
// [self.pickerView selectRow:row0 inComponent:0 animated:YES];//Selects a row in a specified component of the picker view.
// [self.pickerView selectRow:row1 inComponent:1 animated:YES];//Selects a row in a specified component of the picker view.
// [self.pickerView selectRow:row2 inComponent:2 animated:YES];//Selects a row in a specified component of the picker view.
/** 方式二*/
for (int i = 0; i< self.foodsData.count; i++) {//i 代表分组下标
//获取旧的选择行
int oldRow = [self.pickerView selectedRowInComponent:i];//Returns the index of the selected row in a given component.
//计算行数
int row = oldRow;
while (oldRow == row) {
row = arc4random_uniform([self.foodsData[i] count]);
}
//更新label
[self pickerView:self.pickerView didSelectRow:row inComponent:i];
//更新选择的行
[self.pickerView selectRow:row inComponent:i animated:YES];
}
}

#pragma
// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return self.foodsData.count;
}

// returns the # of rows in each component..

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return [self.foodsData[component] count];
}

#pragma
- (nullable NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component __TVOS_PROHIBITED{
return self.foodsData[component] [row];
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component __TVOS_PROHIBITED{
//避免魔法数组,可采用enum
switch (component) {
case 0:
[self.fruitLabel setText:self.foodsData[component][row]];
break;
case 1:
[self.mainLabel setText:self.foodsData[component][row]];
break;
case 2:
[self.drinkLabel setText:self.foodsData[component][row]];
break;
}
}
@end

2.2 国旗选择

iOS小技能:特殊的UIView(UIWindow)_ios_02

#pragma
/** 通常用于自定义UIPickerTableView 的UIPickerTableViewTitleCell*/
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(nullable UIView *)view __TVOS_PROHIBITED{
HSFlagsCellView *cell = nil;
HSFlagsModel *model = self.flagsList[row];
if (view != nil) { //代表有空循环使用的view
//只须设置下数据模型
cell =(HSFlagsCellView *) view;
[cell setFlagsModel:model];//数据装配
}else{
cell = [HSFlagsCellView pickerVieCellWithFlagsModel:model pickerView:pickerView];
}
NSLog(@" %d--%p",row,cell);
return cell;
}

- (CGFloat) pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component{
return 44;
}

2.3 省市联动

/** 设置分组的表格内容 */

- (UIView *) pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{

UILabel *label = nil;

if (view != nil) {

label = (UILabel *)view;

}else{

label = [[UILabel alloc]init];

}

NSString *text = nil;

if (component == 0) {

text = [self.provincesList[row] name] ;

[label setBackgroundColor:[UIColor lightGrayColor]];

}else{//第二组的数据

//确定目前省所在的分组选择中的行数

NSLog(@"%d %d ",self.provincesIndex,row);

text = [self.provincesList[self.provincesIndex] cities][row];

[label setBackgroundColor:[UIColor magentaColor]];

}

[label setText:text];

return label;

}

/** 设置选择的省份索引 */

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{

if (component == 0) {

self.provincesIndex = row;

[pickerView reloadComponent:1];

//设置城市分组选择第一行

[pickerView selectRow:0 inComponent:1 animated:YES];

}

}

/** 设置分组宽度*/

- (CGFloat) pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component{

if (component == 0) {

return 150;

}else{

return 100;

}

}

iOS小技能:特殊的UIView(UIWindow)_iOS_03

iOS小技能:特殊的UIView(UIWindow)_数据_04

see also

🍅 iOS逆向(公号:iosrev)


🍅 简历模板、技术互助。关注我,都给你。