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

302 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第34天,点击查看活动详情

引言

一个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点菜系统

这里写图片描述

/
 
//  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 mark - UIPickerViewDataSource 协议方法
// 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 mark - UIPickerViewDelegate 代理方法细节实现
- (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 国旗选择

这里写图片描述

#pragma mark -  UIPickerViewDelegate
/**  通常用于自定义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;
 
    }
 
}

这里写图片描述

see also

🍅 联系作者: iOS逆向(公号:iosrev)


🍅 作者简介:CSDN 博客专家认证🏆丨全站 Top 50、华为云云享专家认证🏆、iOS逆向公号号主


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