美文网首页
IOS基础:OC的UIKit语法

IOS基础:OC的UIKit语法

作者: 时光啊混蛋_97boy | 来源:发表于2020-10-22 14:15 被阅读0次

原创:知识点总结性文章
创作不易,请珍惜,之后会持续更新,不断完善
个人比较喜欢做笔记和写总结,毕竟好记性不如烂笔头哈哈,这些文章记录了我的IOS成长历程,希望能与大家一起进步
温馨提示:由于简书不支持目录跳转,大家可通过command + F 输入目录标题后迅速寻找到你所需要的内容

目录

  • 1、UIWindow与UIView
  • 2、UIControl
  • 3、Input View
  • 4、UIScrollView
  • 5、UITableView
  • 6、UICollectionView
  • 7、UIPickerView
  • 8、AlertView
  • 9、UISearchBar
  • 10、UIViewController
  • 11、GestureRecognizer
  • 12、touches与motion
  • Demo
  • 参考文献

1、UIWindow与UIView

UIWindow
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
UIView
- (void)setNeedsLayout;
- (void)layoutIfNeeded;
- (void)layoutSubviews;
- (void)removeFromSuperview;
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;

self.view.subviews
[self.view exchangeSubviewAtIndex:0 withSubviewAtIndex:1];
CALayer
CALayer  *layer;
layer.borderWidth
layer.borderColor

2、UIControl

a、UISlider
UISlider
创建滑条视图
- (void)createSliderView
{
    UISlider *horizontalSlider = [[UISlider alloc] initWithFrame:CGRectZero];
    
    horizontalSlider.minimumValue = 10;
    horizontalSlider.maximumValue = 100;
    [horizontalSlider addTarget:self action:@selector(horizontalSliderChanged:) forControlEvents:UIControlEventValueChanged];
    
    [self.view addSubview:horizontalSlider];
    [horizontalSlider mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop);
        make.height.equalTo(@44);
        make.left.equalTo(self.view.mas_left).offset(30);
        make.right.equalTo(self.view.mas_right).offset(-30);
    }];
    
    UISlider *verticalSlider = [[UISlider alloc] initWithFrame:CGRectZero];
    
    // 旋转90度
    CGAffineTransform transform = verticalSlider.transform;
    transform = CGAffineTransformRotate(transform, -M_PI/2);
    verticalSlider.transform = transform;
    
    verticalSlider.minimumValue = 10;
    verticalSlider.maximumValue = 100;
    [verticalSlider addTarget:self action:@selector(verticalSliderChanged:) forControlEvents:UIControlEventValueChanged];
    [self.view addSubview:verticalSlider];
    
    [verticalSlider mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop).offset(280);
        make.height.equalTo(@44);
        make.left.equalTo(self.view.mas_left).offset(30);
        make.right.equalTo(self.view.mas_right).offset(-30);
    }];
}
事件方法
- (void)horizontalSliderChanged:(id)sender
{
    UISlider *slider = sender;
    NSLog(@"水平滑条值改变:%f", slider.value);
}

- (void)verticalSliderChanged:(id)sender
{
    UISlider *slider = sender;
    NSLog(@"垂直滑条值改变: %f", slider.value);
}
输出结果
2020-10-13 15:36:17.451947+0800 BasicGrammarDemo[45225:2120947] 水平滑条值改变:58.211006
2020-10-13 15:36:17.822776+0800 BasicGrammarDemo[45225:2120947] 水平滑条值改变:58.211006
2020-10-13 15:36:18.509124+0800 BasicGrammarDemo[45225:2120947] 垂直滑条值改变: 10.000000
2020-10-13 15:36:18.530712+0800 BasicGrammarDemo[45225:2120947] 垂直滑条值改变: 12.110093
b、SegmentedControl
SegmentedControl
创建SegmentedControl视图
- (void)createSegmentedControl
{
    UISegmentedControl *segmentControl = [[UISegmentedControl alloc] initWithItems:@[@"item1", @"item2", @"item3"]];
    
    segmentControl.selectedSegmentIndex = 1;
    
    [segmentControl addTarget:self action:@selector(segmentControlChanged:) forControlEvents:UIControlEventValueChanged];
    [self.view addSubview:segmentControl];
    
    [segmentControl mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop).offset(60);
        make.height.equalTo(@44);
        make.left.equalTo(self.view.mas_left).offset(20);
        make.right.equalTo(self.view.mas_right).offset(-100);
    }];
}
事件方法
- (void)segmentControlChanged:(id)sender
{
    UISegmentedControl *segmentControl = sender;
    NSLog(@"segmentControl值改变:%@", @(segmentControl.selectedSegmentIndex));
}
输出结果
2020-10-13 15:35:23.543024+0800 BasicGrammarDemo[45161:2117200] segmentControl值改变:0
c、UISwitch
UISwitch
创建开关视图
- (void)createSwitchView
{
    UISwitch *switcher = [[UISwitch alloc] initWithFrame:CGRectZero];
    [switcher addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
    [self.view addSubview:switcher];
    
    
    [switcher mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop).offset(120);
        make.height.equalTo(@44);
        make.left.equalTo(self.view.mas_left).offset(20);
        make.width.equalTo(@100);
    }];
}
事件方法
2020-10-13 16:06:16.290280+0800 BasicGrammarDemo[45707:2145882] 开关改变了:1
d、UIActivityIndicatorView
指示器
- (void)createActivityIndicatorView
{
    UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleMedium];
    
    // 只能设置中心,不能设置大小
    activityIndicator.center = CGPointMake(200.0f, 200.0f);
    // 改变圈圈的颜色为红色
    activityIndicator.color = [UIColor redColor];
    
    // 开始旋转
    [activityIndicator startAnimating];
    // 结束旋转
    [activityIndicator stopAnimating];
    
    // 添加指示器到导航栏
    self.navigationItem.titleView = activityIndicator;
    self.navigationItem.prompt =  @"正在使出吃奶的劲加载中...";
    
    // 停止指示器控件本应该调用 stopAnimating 方法,但放在导航栏项目中的活动指示器控件有所不同
    // 要移除这个控件,让原来的title内容显示出来
    self.navigationItem.titleView = nil;
    self.navigationItem.prompt = nil;
    
    [self.view addSubview:activityIndicator];
}
e、UIProgressView
self.progressView.progress = self.progressView.progress + 0.1;
if (self.progressView.progress == 1.0)
{
    [self.timer invalidate];
}
f、UIRefreshControl
self.collectionView.alwaysBounceVertical = YES;// 必须打开
self.refreshControl.tintColor = [UIColor grayColor];
[self.refreshControl addTarget:self action:@selector(urlRequestForCollection) forControlEvents:UIControlEventValueChanged];
[self.collectionView addSubview:self.refreshControl];
[weakSelf.refreshControl endRefreshing];// 结束刷新

3、Input View

a、UILabel
UILabel
- (void)createLabelView
{
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(150, 100, 100, 50)];

    // 位置位于视图中央
    label.center = self.view.center;

    // 自适应大小的方法,即标签的大小由字体的大小长度决定
    // 这个打开后会让label不再显示,慎用!!!
    // [label sizeToFit];

    // 设置字体大小是否适应label宽度
    label.adjustsFontSizeToFitWidth = YES;

    // 设置label的换行模式为根据单词进行换行
    label.lineBreakMode = NSLineBreakByWordWrapping;
    
    // 设置label显示几行,0表示可以有无限行
    label.numberOfLines = 0;

    // 设置文本是否高亮和高亮时的颜色
    label.highlighted = YES;
    label.highlightedTextColor = [[UIColor orangeColor] colorWithAlphaComponent:0.5];
    
    // 设置阴影的颜色和阴影的偏移位置
    label.shadowColor = [UIColor redColor];
    label.shadowOffset = CGSizeMake(1.0, 1.9);
    
    // 设置label中的文字是否可变,默认值是YES
    label.enabled = YES;

    // 如果adjustsFontSizeToFitWidth属性设置为YES,这个属性就来控制文本基线的行为
    // 将文本缩小到基于原始基线的位置时使用,默认不使用
    label.baselineAdjustment = UIBaselineAdjustmentNone;
    
    // 设置背景色为透明
    label.backgroundColor = [UIColor clearColor];
    
    // 设置label的旋转角度
    label.transform = CGAffineTransformMakeRotation(0.2);
    
    // 让label自适应里面的文字,自动调整宽度和高度
    NSString *string = @"天地之间隐有梵音";
    [string boundingRectWithSize:CGSizeMake(320, 2000) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16]} context:nil];
    
    // 让UILabel具有链接功能
    // 如果我并没有安装app那它就会失败,同时会调用safari来打开这个链接
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http:baidu.com"] options:@{UIApplicationOpenURLOptionUniversalLinksOnly : @YES} completionHandler:nil];
    
    // 让label显示出来
    label.backgroundColor = [UIColor blackColor];
    label.text = string;
    [self.view addSubview:label];
}
b、UITextField
UITextField
创建textField视图
- (void)createTextFieldView
{
    self.passwordTextField = [[UITextField alloc] initWithFrame:CGRectZero];
    
    self.passwordTextField.borderStyle = UITextBorderStyleRoundedRect;// 圆角矩形
    self.passwordTextField.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 22, 22)];// 左视图大小
    self.passwordTextField.leftView.backgroundColor = [UIColor redColor];// 左视图背景颜色
    self.passwordTextField.leftViewMode = UITextFieldViewModeAlways;// 左视图总是显示
    self.passwordTextField.clearButtonMode = UITextFieldViewModeWhileEditing;// 显示清空按钮
    self.passwordTextField.secureTextEntry = YES;// 加密显示,该属性通常用于设置密码输入框
    self.passwordTextField.clearsOnBeginEditing = YES;// 当重复开始编辑时候清除文字
    //  返回类型:Default换行 Go前往 Google/Search搜索 Join加入 Next下一项 Route路线 Send发送 Done完成 Continue继续
    self.passwordTextField.returnKeyType = UIReturnKeySearch;
    // 设置弹出视图inputView,即弹出的不是键盘而是这个视图
    // 默认的整个键盘宽度,只有设置高度会有用
    self.passwordTextField.inputView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"luckcoffee.JPG"]];
    // 纵向对齐方式,默认是居中
    self.passwordTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
    // 设置调整文字大小以适配宽度(即输入不下时缩小文字,实在缩小不了了,就向后滚动),默认是向右滚动的
    self.passwordTextField.adjustsFontSizeToFitWidth = YES;
    // 设置最小字号,和上面有关,即小于这个字号的时候就不缩小了,直接向右滚动
    self.passwordTextField.minimumFontSize = 2;
    // 设置字母大小样式 AllCharacters-所有字母大写 Words-单词首字母大写 Sentences-句首字母大写
    self.passwordTextField.autocapitalizationType = UITextAutocapitalizationTypeSentences;

    self.passwordTextField.delegate = self;
    [self.passwordTextField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

    [self.view addSubview:self.passwordTextField];
    [self.passwordTextField mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop).offset(60);
        make.height.equalTo(@44);
        make.left.equalTo(self.view.mas_left).offset(20);
        make.right.equalTo(self.view.mas_right).offset(-20);
    }];
}
UITextFieldDelegate
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField// 是否可以编辑
{
    return YES;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField// 开始编辑
{
    NSLog(@"开始编辑");
}

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField// 是否应该结束编辑
{
    return YES;
}

- (void)textFieldDidEndEditing:(UITextField *)textField// 结束编辑
{
    NSLog(@"结束编辑");
}

- (void)textFieldDidChange:(UITextField *)textField// 获取编辑完成的文本
{
    NSLog(@"获取编辑完成的文本 %@", textField.text);
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string// 编辑过程中会不断调用
{
    if (string.length > 0)// 有输入字符
    {
        if ([string isEqualToString:@"0"])// 输入0则允许改变,可以继续输入
        {
            return YES;
        }
        return NO;
    }
    return YES;
}

- (BOOL)textFieldShouldClear:(UITextField *)textField// 是否可以清空
{
    // 点击清除按钮,应该同时将本地数据源里的文本清空
    if (textField == self.passwordTextField)
    {
        self.password = @"";
    }
    return YES;
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField// 是否可以返回
{
    return YES;
}
输出结果
2020-10-13 16:09:15.357943+0800 BasicGrammarDemo[45707:2145882] 开始编辑
2020-10-13 16:09:16.478273+0800 BasicGrammarDemo[45707:2145882] 获取编辑完成的文本 0
2020-10-13 16:09:16.643681+0800 BasicGrammarDemo[45707:2145882] 获取编辑完成的文本 00
c、UITextView
UITextView
创建textView视图
- (void)createTextView
{
    self.textView = [[UITextView alloc] initWithFrame:CGRectZero];
    
    self.textView.layer.borderColor = [UIColor blackColor].CGColor;
    self.textView.layer.borderWidth = 1.0;
    
    self.textView.delegate = self;
    self.textView.text = @"孟子,既然男女授受不亲,嫂子掉到水里,要不要伸手去拉,假如“礼”是那么重要,人命就不要了吗?,不去救嫂子则“是豺狼也”,但这要怪嫂子干吗要掉进水里。他没有说戴上了手套再去拉嫂子,唯一的不幸就是自己的无能,对数学家来说,只要他能证明费尔马定理,就可以获得全球数学家的崇敬,自己也可以得到极大的快感,问题在于你证不出来。";
    
    [self.view addSubview:self.textView];
    [self.textView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop).offset(120);
        make.height.equalTo(@100);
        make.left.equalTo(self.view.mas_left).offset(20);
        make.right.equalTo(self.view.mas_right).offset(-20);
    }];
}
UITextViewDelegate
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView// 是否可以编辑
{
    return YES;
}

- (BOOL)textViewShouldEndEditing:(UITextView *)textView// 是否应该结束编辑
{
    return YES;
}

- (void)textViewDidBeginEditing:(UITextView *)textView
{
    NSLog(@"开始编辑");
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
    NSLog(@"结束编辑");
}

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text// 编辑过程中会不断调用
{
    return YES;
}

- (void)textViewDidChange:(UITextView *)textView// 获取编辑完成的文本
{
    NSLog(@"获取编辑完成的文本 %@", textView.text);
}

- (void)textViewDidChangeSelection:(UITextView *)textView// 编辑完成的文本
{
    NSLog(@"改变了选中部分的文本");
}
输出结果
2020-10-13 17:25:36.642017+0800 BasicGrammarDemo[55396:2252994] 开始编辑
2020-10-13 17:25:36.645211+0800 BasicGrammarDemo[55396:2252994] 改变了选中部分的文本
2020-10-13 17:25:47.733527+0800 BasicGrammarDemo[55396:2252994] 获取编辑完成的文本 孟子,既然男女授受不亲,嫂子掉到水里,要不要伸手去拉,假如“礼”

4、UIScrollView

UIScrollView
创建滚动视图
- (void)createScrollView
{
    self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
    self.scrollView.delegate = self;
    
    self.scrollView.pagingEnabled = YES;// 是否支持翻页
    self.scrollView.showsHorizontalScrollIndicator = YES;// 展示水平滚动条
    self.scrollView.showsVerticalScrollIndicator = NO;// 展示垂直滚动条
    self.scrollView.minimumZoomScale = 0.5;// 最小化
    self.scrollView.maximumZoomScale = 2.0;// 最大化
    self.scrollView.scrollsToTop = YES;// 要不要返回顶部
    self.scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;// 滚动条颜色
    CGSize viewSize = self.view.bounds.size;
    self.scrollView.contentSize = CGSizeMake(viewSize.width*3, viewSize.height);// 内容为屏幕3倍用于横向滑动
    
    [self.view addSubview:self.scrollView];
    [self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop);
        make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom);
        make.left.equalTo(self.view.mas_left);
        make.right.equalTo(self.view.mas_right);
    }];

    self.pageControl = [[UIPageControl alloc] initWithFrame:CGRectZero];
    
    self.pageControl.numberOfPages = 3;// 3页
    self.pageControl.pageIndicatorTintColor = [UIColor colorWithWhite:1 alpha:0.5];// 小点的颜色
    self.pageControl.currentPageIndicatorTintColor = [UIColor whiteColor];// 当前点的颜色
    
    [self.view addSubview:self.pageControl];
    [self.pageControl mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-20);
        make.height.equalTo(@44);
        make.left.equalTo(self.view.mas_left);
        make.right.equalTo(self.view.mas_right);
    }];

    // 创建红、蓝、绿三个页面
    UIView *redView = [self createScrollViewSubViewWithOffset:0];
    redView.backgroundColor = [UIColor redColor];
    
    UIView *blueView = [self createScrollViewSubViewWithOffset:viewSize.width];
    blueView.backgroundColor = [UIColor blueColor];
    
    UIView *greenView = [self createScrollViewSubViewWithOffset:viewSize.width*2];
    greenView.backgroundColor = [UIColor greenColor];
}

- (UIView *)createScrollViewSubViewWithOffset:(CGFloat)offsetX
{
    CGSize viewSize = self.view.bounds.size;
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(offsetX, 0, viewSize.width, viewSize.height)];
    [self.scrollView addSubview:view];
    return view;
}
UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView// 滚动了
{
    NSLog(@"偏移量:%@", @(scrollView.contentOffset.x));
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView// 结束滚动
{
    CGFloat offsetX = scrollView.contentOffset.x;
    NSLog(@"结束滚动时候在X轴的偏移量:%@", @(offsetX));
    
    // 计算当前页数
    NSInteger index = offsetX / scrollView.frame.size.width;
    self.pageControl.currentPage = index;
}

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView// 需要缩放的视图
{
    CGFloat offsetX = scrollView.contentOffset.x;
    NSInteger index = offsetX / scrollView.frame.size.width;
    return scrollView.subviews[index];
}

- (void)scrollViewDidZoom:(UIScrollView *)scrollView// 缩放比例
{
    NSLog(@"缩放了 %@", @(scrollView.zoomScale));
}
输出结果
2020-10-13 17:43:22.163863+0800 BasicGrammarDemo[55573:2261834] 缩放了 0.7947149384108813
2020-10-13 17:43:22.241076+0800 BasicGrammarDemo[55573:2261834] 偏移量:-23.19056305867597
2020-10-13 17:45:23.062048+0800 BasicGrammarDemo[55573:2261834] 结束滚动时候在X轴的偏移量:228.3333333333333

5、UITableView

UITableView
PersonTableViewCell.h文件
@interface PersonTableViewCell : UITableViewCell

@property (nonatomic, strong, readonly) UILabel *nameLabel;// 姓名
@property (nonatomic, strong, readonly) UILabel *namePinyinLabel;// 姓名拼音
@property (nonatomic, strong, readonly) UILabel *mobileLabel;// 手机
@property (nonatomic, strong, readonly) UILabel *introductionLabel;// 介绍

@end
PersonTableViewCell.m文件
@implementation PersonTableViewCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self)
    {
        [self createSubViews];
        [self createSubViewsConstraints];
    }
    return self;
}

// 添加子视图
- (void)createSubViews
{
    self.nameLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    self.nameLabel.textAlignment = NSTextAlignmentLeft;
    [self.contentView addSubview:self.nameLabel];
    
    self.namePinyinLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    self.namePinyinLabel.textAlignment = NSTextAlignmentRight;
    [self.contentView addSubview:self.namePinyinLabel];
    
    self.mobileLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    [self.contentView addSubview:self.mobileLabel];
    
    self.introductionLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    self.introductionLabel.numberOfLines = 0;
    [self.contentView addSubview:self.introductionLabel];
}

// 添加约束
- (void)createSubViewsConstraints {
    [self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.contentView.mas_top).offset(10);
        make.height.equalTo(@30);
        make.left.equalTo(self.contentView.mas_left).offset(20);
        make.right.equalTo(self.contentView.mas_right).offset(-20);
    }];
    
    [self.namePinyinLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.nameLabel.mas_top);
        make.bottom.equalTo(self.nameLabel.mas_bottom);
        make.left.equalTo(self.contentView.mas_left).offset(20);
        make.right.equalTo(self.contentView.mas_right).offset(-20);
    }];
    
    [self.mobileLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.nameLabel.mas_bottom).offset(10);
        make.height.equalTo(@30);
        make.left.equalTo(self.contentView.mas_left).offset(20);
        make.right.equalTo(self.contentView.mas_right).offset(-20);
    }];
    
    [self.introductionLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.mobileLabel.mas_bottom).offset(10);
        make.bottom.equalTo(self.contentView.mas_bottom).offset(-10);
        make.left.equalTo(self.contentView.mas_left).offset(20);
        make.right.equalTo(self.contentView.mas_right).offset(-20);
    }];
}

@end
编辑 TableView
- (void)configureNavigationbar
{
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"编辑" style:UIBarButtonItemStylePlain target:self action:@selector(editTable)];
    
    self.editFinished = YES;
}

- (void)editTable
{
    if (self.isEditFinished)
    {
        self.editFinished = NO;
        self.navigationItem.rightBarButtonItem.title = @"完成";
        self.tableView.editing = YES;// 正在编辑
    }
    else
    {
        self.editFinished = YES;
        self.navigationItem.rightBarButtonItem.title = @"编辑";
        self.tableView.editing = NO;// 非编辑状态
    }
}
创建TableView
- (void)createTableView
{
    self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
    [self.tableView registerClass:[PersonTableViewCell class] forCellReuseIdentifier:TableCellReuseIdentifier];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    
    // 不显示右侧滑块
    self.tableView.showsVerticalScrollIndicator = NO;
    // 分割线
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
    // 表头表尾高度
    self.tableView.sectionHeaderHeight = 20;
    self.tableView.sectionFooterHeight = 20;
    // 弹动
    self.tableView.bounces = NO;
    
    // 多选模式
//    self.tableView.allowsSelection = YES;
//    self.tableView.allowsSelectionDuringEditing = YES;
//    self.tableView.allowsMultipleSelection = YES;
//    self.tableView.allowsMultipleSelectionDuringEditing = YES;
    
    [self.view addSubview:self.tableView];
    [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop);
        make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom);
        make.left.equalTo(self.view.mas_left);
        make.right.equalTo(self.view.mas_right);
    }];
}
UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView// section 数量
{
    return self.personTableArray.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section// cell 数量
{
    return self.personTableArray[section].count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath// cell 样式
{
    PersonTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TableCellReuseIdentifier forIndexPath:indexPath];
    
    cell.selectionStyle = UITableViewCellSelectionStyleNone;// 选中风格
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;// 右指示器
    //cell.accessoryView = imageBtn;// cell可以设置装饰图
    
    // cell自带imageView属性、text属性、detailTextLabel属性
    cell.detailTextLabel.text = @"更多";
    
    PersonModel *personModel = self.personTableArray[indexPath.section][indexPath.row];
    cell.nameLabel.text = personModel.name;
    cell.namePinyinLabel.text = personModel.namePinyin;
    cell.mobileLabel.text = personModel.mobile;
    cell.introductionLabel.text = personModel.introduction;
    
    return cell;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section// SectionHeader 标题
{
    return self.sectionIndexTitles[section];// 索引数组
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath// 能否编辑 cell
{
    return (indexPath.section > 0);// 除第一节外都可编辑
}

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath// 能否移动 cell
{
    return (indexPath.section == 1);// 第二节可以移动cell
}

- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView// TableView的右边索引列的标题
{
    return self.sectionIndexTitles;
}

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index// TableView的右边索引列的位置,好像没什么用
{
    return index;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath// 支持插入和删除 cell
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        // 从数据源里移除当前cell的数据
        NSMutableArray *personArray = self.personTableArray[indexPath.section];
        [personArray removeObjectAtIndex:indexPath.row];

        // 移除完后当前Section不再拥有cell了
        if (personArray.count == 0)
        {
            // 移除当前Section的数据和索引标题
            [self.personTableArray removeObjectAtIndex:indexPath.section];
            [self.sectionIndexTitles removeObjectAtIndex:indexPath.section];
        }

        // 从视图中移除当前cell
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
}

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath// 支持移动 cell
{
    // 从数据源中移除初始cell的数据
    NSMutableArray *sourcePersonArray = self.personTableArray[sourceIndexPath.section];
    PersonModel *sourcePersonModel = sourcePersonArray[sourceIndexPath.row];
    [sourcePersonArray removeObjectAtIndex:sourceIndexPath.row];
    self.personTableArray[sourceIndexPath.section] = sourcePersonArray;

    // 从数据源中向目的cell添加数据
    NSMutableArray *destinationPersonArray = self.personTableArray[destinationIndexPath.section];
    [destinationPersonArray insertObject:sourcePersonModel atIndex:destinationIndexPath.row];
    self.personTableArray[destinationIndexPath.section] = destinationPersonArray;
}
UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath// 选中 cell
{
    NSLog(@"didSelectRowAtIndexPath %@", indexPath);
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath// 编辑风格
{
    return UITableViewCellEditingStyleDelete;
}

- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath// 删除确认按钮的标题
{
    return @"删除";
}
配置数据源
- (void)readTablePersonData
{
    NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"person" withExtension:@"json"];
    NSData *fileData = [NSData dataWithContentsOfURL:fileURL options:NSDataReadingMappedIfSafe error:nil];
    NSArray<NSDictionary *> *persons = [NSJSONSerialization JSONObjectWithData:fileData options:NSJSONReadingMutableContainers error:nil];
    
    // json to model
    NSMutableArray<PersonModel *> *personModelArray = [NSMutableArray array];
    [persons enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        PersonModel *personModel = [[PersonModel alloc] init];
        personModel.name = obj[@"name"];
        personModel.namePinyin = obj[@"pinyin"];
        personModel.nameFirstLetter = obj[@"first_letter"];
        personModel.mobile = obj[@"mobile"];
        personModel.introduction = obj[@"introduction"];
        
        [personModelArray addObject:personModel];
    }];
    
    // 按照字母顺序进行排序
    [personModelArray sortUsingComparator:^NSComparisonResult(PersonModel *obj1, PersonModel *obj2) {
        return [obj1.namePinyin compare:obj2.namePinyin];
    }];
    
    // 按拼音首字母拆分,顺序遍历
    NSMutableArray<NSMutableArray<PersonModel *> *> *personDataArray = [NSMutableArray array];
    NSMutableArray<NSString *> *sectionIndexArray = [NSMutableArray array];
    NSMutableArray<PersonModel *> *personArray = [NSMutableArray array];
    
    NSInteger count = personModelArray.count;
    for (int i=0; i<count; I++)
    {
        PersonModel *personModel = personModelArray[I];
        if (![sectionIndexArray containsObject:personModel.nameFirstLetter])// 不包含的首字母则需要新的array容纳
        {
            // 将该首字母添加到索引数组
            [sectionIndexArray addObject:personModel.nameFirstLetter];
            if (personArray.count > 0)// array代表的上一个section存在model
            {
                // personDataArray代表[Section[row]]
                [personDataArray addObject:[personArray mutableCopy]];
                // 清空旧的model,成为新array
                [personArray removeAllObjects];
            }
        }
        // 首字母已经被包含,说明是该model处于同一个section,则添加到array即可
        [personArray addObject:personModel];
    }
    // 添加最后一个personArray
    [personDataArray addObject:[personArray copy]];
    
    // 重新加载table
    self.personTableArray = personDataArray;
    self.sectionIndexTitles = sectionIndexArray;
    [self.tableView reloadData];
}

6、UICollectionView

UICollectionView
通讯录cell的.h文件
@interface PersonCollectionViewCell : UICollectionViewCell

@property (nonatomic, strong, readonly) UILabel *nameLabel;// 姓名
@property (nonatomic, strong, readonly) UILabel *namePinyinLabel;// 姓名拼音
@property (nonatomic, strong, readonly) UILabel *mobileLabel;// 手机
@property (nonatomic, strong, readonly) UILabel *introductionLabel;// 介绍

@end
通讯录cell的.m文件
@interface PersonCollectionViewCell ()

@property (nonatomic, strong, readwrite) UILabel *nameLabel;
@property (nonatomic, strong, readwrite) UILabel *namePinyinLabel;
@property (nonatomic, strong, readwrite) UILabel *mobileLabel;
@property (nonatomic, strong, readwrite) UILabel *introductionLabel;

@end

@implementation PersonCollectionViewCell

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        [self createSubViews];
        [self createSubViewsConstraints];
    }
    return self;
}

// 添加子视图
- (void)createSubViews
{
    self.nameLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    self.nameLabel.textAlignment = NSTextAlignmentLeft;
    [self.contentView addSubview:self.nameLabel];
    
    self.namePinyinLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    self.namePinyinLabel.textAlignment = NSTextAlignmentRight;
    [self.contentView addSubview:self.namePinyinLabel];
    
    self.mobileLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    [self.contentView addSubview:self.mobileLabel];
    
    self.introductionLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    self.introductionLabel.numberOfLines = 0;// 可多行显示
    self.introductionLabel.font = [UIFont systemFontOfSize:15.0];
    [self.contentView addSubview:self.introductionLabel];
    
    // 给Cell添加红色边框
    self.contentView.layer.borderColor = [UIColor redColor].CGColor;
    self.contentView.layer.borderWidth = 1.0;
}

// 添加约束
- (void)createSubViewsConstraints
{
    [self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.contentView.mas_top).offset(10);
        make.height.equalTo(@30);
        make.left.equalTo(self.contentView.mas_left).offset(10);
        make.right.equalTo(self.contentView.mas_right).offset(-10);
    }];
    
    [self.namePinyinLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.nameLabel.mas_bottom).offset(10);
        make.height.equalTo(@30);
        make.left.equalTo(self.contentView.mas_left).offset(10);
        make.right.equalTo(self.contentView.mas_right).offset(-10);
    }];
    
    [self.mobileLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.namePinyinLabel.mas_bottom).offset(10);
        make.height.equalTo(@30);
        make.left.equalTo(self.contentView.mas_left).offset(10);
        make.right.equalTo(self.contentView.mas_right).offset(-10);
    }];
    
    [self.introductionLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.mobileLabel.mas_bottom).offset(10);
        make.bottom.equalTo(self.contentView.mas_bottom).offset(-10);
        make.left.equalTo(self.contentView.mas_left).offset(10);
        make.right.equalTo(self.contentView.mas_right).offset(-10);
    }];
}

@end
通讯录model的.h文件
@interface PersonModel : NSObject

@property (nonatomic, copy) NSString *name;// 姓名
@property (nonatomic, copy) NSString *namePinyin;// 姓名拼音
@property (nonatomic, copy) NSString *nameFirstLetter;// 姓名首字母
@property (nonatomic, copy) NSString *mobile;// 手机
@property (nonatomic, copy) NSString *introduction;// 介绍

@end
通讯录model的.m文件
@implementation PersonModel

@end
ViewController
NSString * const CollectionCellReuseIdentifier = @"cell";

@interface ViewController ()<UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>

// 数据源
@property (nonatomic, strong) NSArray *personArray;

// 集合视图
@property (nonatomic, strong) UICollectionView *collectionView;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [self createCollectionView];
    [self readPersonData];
}

......

@end
创建集合视图
- (void)createCollectionView
{
    // 创建集合视图的布局
    CGSize viewSize = self.view.bounds.size;
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    layout.itemSize = CGSizeMake(viewSize.width/2 - 10, viewSize.height);
    layout.minimumLineSpacing = 10;// Item之间的上下间距
    layout.minimumInteritemSpacing = 10;// Item之间的左右间距
    layout.scrollDirection = UICollectionViewScrollDirectionVertical;// 滚动方向
    
    // 创建集合视图
    self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
    self.collectionView.backgroundColor = [UIColor whiteColor];// 默认没有颜色,会渲染成黑色
    [self.collectionView registerClass:[PersonCollectionViewCell class] forCellWithReuseIdentifier:CollectionCellReuseIdentifier];
    self.collectionView.delegate = self;
    self.collectionView.dataSource = self;
    [self.view addSubview:self.collectionView];
    [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop);
        make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom);
        make.left.equalTo(self.view.mas_left);
        make.right.equalTo(self.view.mas_right);
    }];
}
集合数据源
- (void)readPersonData
{
    NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"person" withExtension:@"json"];
    NSData *fileData = [NSData dataWithContentsOfURL:fileURL options:NSDataReadingMappedIfSafe error:nil];
    NSArray<NSDictionary *> *persons = [NSJSONSerialization JSONObjectWithData:fileData options:NSJSONReadingMutableContainers error:nil];
    
    // json to model
    NSMutableArray<PersonModel *> *personArray = [NSMutableArray array];
    [persons enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        
        PersonModel *personModel = [[PersonModel alloc] init];
        personModel.name = obj[@"name"];
        personModel.namePinyin = obj[@"pinyin"];
        personModel.nameFirstLetter = obj[@"first_letter"];
        personModel.mobile = obj[@"mobile"];
        personModel.introduction = obj[@"introduction"];
        
        [personArray addObject:personModel];
    }];
    
    // 按照字母顺序进行排序
    [personArray sortUsingComparator:^NSComparisonResult(PersonModel *obj1, PersonModel *obj2) {
        return [obj1.namePinyin compare:obj2.namePinyin];
    }];
    
    // 重新加载页面
    self.personArray = personArray;
    [self.collectionView reloadData];
}
UICollectionViewDataSource
// Item数目
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return self.personArray.count;
}

// Item内容
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    PersonCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CollectionCellReuseIdentifier forIndexPath:indexPath];
    
    PersonModel *personModel = self.personArray[indexPath.item];
    cell.nameLabel.text = personModel.name;
    cell.namePinyinLabel.text = personModel.namePinyin;
    cell.mobileLabel.text = personModel.mobile;
    cell.introductionLabel.text = personModel.introduction;
    
    return cell;
}
UICollectionViewDelegate
// 选中Item
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"选中了Item");
}
UICollectionViewDelegateFlowLayout
// Item尺寸大小
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    // 页面宽度一半 - 10 作为Item宽度
    CGSize viewSize = self.view.bounds.size;
    CGFloat width = viewSize.width/2 - 10;
    
    // 根据字号、宽度、内容来估计introduction的高度
    PersonModel *personModel = self.personArray[indexPath.row];
    CGSize size = [personModel.introduction boundingRectWithSize:CGSizeMake(width - 24, 2000) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:15.0]} context:nil].size;
    
    // 返回Item尺寸大小
    return CGSizeMake(width, size.height + 160);
}

7、UIPickerView

创建选择器视图
- (void)createPickerView
{
    self.pickerView = [[UIPickerView alloc] initWithFrame:CGRectZero];
    self.pickerView.delegate = self;
    self.pickerView.dataSource = self;
    [self.view addSubview:self.pickerView];
    [self.pickerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop);
        make.height.equalTo(@200);
        make.left.equalTo(self.view.mas_left);
        make.right.equalTo(self.view.mas_right);
    }];
    
    self.datePicker = [[UIDatePicker alloc] initWithFrame:CGRectZero];
    [self.datePicker addTarget:self action:@selector(datePickerChanged:) forControlEvents:UIControlEventValueChanged];
    [self.view addSubview:self.datePicker];
    [self.datePicker mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop).offset(300);
        make.height.equalTo(@200);
        make.left.equalTo(self.view.mas_left);
        make.right.equalTo(self.view.mas_right);
    }];
}

- (void)datePickerChanged:(id)sender
{
    UIDatePicker *datePicker = sender;
    NSLog(@"选择的日期为:%@", datePicker.date);
}
UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView// 转盘数目
{
    return 2;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component// 每个转盘的行数
{
    return 5;
}
UIPickerViewDelegate
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component// 每个转盘的宽度
{
    return self.view.bounds.size.width/2;
}

- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component// 转盘中每一行的高度
{
    return 44.0;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component// 每一行的标题
{
    return self.pickerData[component][row];
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    NSLog(@"选择的转盘为:%@, 选择的行数上的内容为:%@", @(component), self.pickerData[component][row]);
    if (component == 0)// 滚动第一个转盘时候需要联动第二个转盘
    {
        [pickerView reloadComponent:1];
    }
}

// 数据源
- (void)configuePickerData
{
    NSArray *columnFirst = @[@"谢佳培", @"王德胜", @"白落梅", @"车行迟", @"林风眠"];
    NSArray *columnSecond = @[@"IOS开发", @"院士", @"作家", @"虚构", @"画家"];
    self.pickerData = @[columnFirst, columnSecond];
    
    // 重新加载表盘
    [self.pickerView reloadAllComponents];
}
输出结果
2020-10-13 18:12:46.186157+0800 BasicGrammarDemo[56013:2286395] 选择的转盘为:1, 选择的行数上的内容为:IOS开发

8、AlertView

a、创建选择面板
选择面板
- (void)showActionSheetController
{
    UIAlertController *actionSheetController = [UIAlertController alertControllerWithTitle:@"作家" message:@"每个人的名字都像一幅水墨画" preferredStyle:UIAlertControllerStyleActionSheet];
    
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        NSLog(@"点击了取消");
    }];
    [actionSheetController addAction:cancelAction];
    
    UIAlertAction *firstAction = [UIAlertAction actionWithTitle:@"查看白落梅" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        NSLog(@"查看白落梅");
    }];
    [actionSheetController addAction:firstAction];
    
    UIAlertAction *secondAction = [UIAlertAction actionWithTitle:@"查看丰子恺" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        NSLog(@"查看丰子恺");
    }];
    [actionSheetController addAction:secondAction];
    
    UIAlertAction *thirdAction = [UIAlertAction actionWithTitle:@"查看郁达夫" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        NSLog(@"查看郁达夫");
    }];
    [actionSheetController addAction:thirdAction];
    
    [self presentViewController:actionSheetController animated:YES completion:nil];
}
b、利用KVC方法进行UIAlertController属性的自定义
利用KVC方法进行UIAlertController属性的自定义
- (void)customAlert
{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:@"提示内容" preferredStyle:UIAlertControllerStyleAlert];
    
    // 修改title
    NSMutableAttributedString *alertControllerStr = [[NSMutableAttributedString alloc] initWithString:@"提示"];
    [alertControllerStr addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, 2)];
    [alertControllerStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:17] range:NSMakeRange(0, 2)];
    // 利用KVC方法进行UIAlertController属性的自定义
    // 有时候使用第三方控件会带来很多不必要的代码量和bug,所以能用系统自带最好
    [alertController setValue:alertControllerStr forKey:@"attributedTitle"];
    
    // 修改message
    NSMutableAttributedString *alertControllerMessageStr = [[NSMutableAttributedString alloc] initWithString:@"提示内容"];
    [alertControllerMessageStr addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(0, 4)];
    [alertControllerMessageStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:20] range:NSMakeRange(0, 4)];
    [alertController setValue:alertControllerMessageStr forKey:@"attributedMessage"];
    
    // 常规按钮
    UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"Default" style:UIAlertActionStyleDefault handler:nil];
    // 销毁按钮
    UIAlertAction *destructiveAction = [UIAlertAction actionWithTitle:@"Destructive" style:UIAlertActionStyleDestructive handler:nil];
    // 取消按钮
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
    
    [alertController addAction:defaultAction];
    [alertController addAction:destructiveAction];
    [alertController addAction:cancelAction];
    
    [self presentViewController:alertController animated:YES completion:nil];
}
c、UIAlertController上添加文本框
UIAlertController上添加文本框
- (void)textFieldForAlert
{
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"title" message:@"message" preferredStyle:UIAlertControllerStyleAlert];
    
    // 添加文本框
    [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        // 设置键盘输入为数字键盘
        textField.keyboardType = UIKeyboardTypeNumberPad;
        textField.placeholder = @"请填写";
    }];
    
    // 添加取消按钮
    UIAlertAction *cancelButton = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        // 取消
    }];
    [alert addAction: cancelButton];
        
    // 添加确定按钮
    UIAlertAction *confirmButton = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        
        // 文本框结束编辑,收起键盘
        [[alert.textFields firstObject] endEditing:YES];
        // 获取文本框填写的内容
        NSString *meetingId = [alert.textFields firstObject].text;
        if (meetingId.length > 12)
        {
            //[weakSelf showText:@"会议号过长"];
        }
        else
        {
            //[weakSelf enterVideoMeeting:meetingId];
        }
    }];
    [alert addAction: confirmButton];
    
    //显示
    [self presentViewController:alert animated:YES completion:nil];
}

9、UISearchBar

a、属性
// 搜索框风格 
// UIBarStyleDefault 白色搜索框,灰色背景
// UIBarStyleBlack 黑色搜索框
@property(nonatomic) UIBarStyle barStyle;

 // 搜索的文本
@property(nullable,nonatomic,copy)   NSString *text;  
 // 搜索框顶部的提示信息 
@property(nullable,nonatomic,copy)   NSString *prompt;    
// 占位符,默认nil, 若有值则在输入文本后消失
@property(nullable,nonatomic,copy)   NSString *placeholder;  

// 搜索框右侧是否显示图书按钮 
@property(nonatomic)  BOOL showsBookmarkButton;   📖
//搜索框右侧是否显示取消按钮 
@property(nonatomic) BOOL showsCancelButton;  Cancel
//搜索框右侧是否显示搜索结果按钮   
@property(nonatomic) BOOL showsSearchResultsButton; ⤓
// 搜索结果按钮为选中状态
@property(nonatomic, getter=isSearchResultsButtonSelected) BOOL searchResultsButtonSelected;☑️

// 风格颜色,可用于修改输入框的光标颜色,取消按钮和选择栏被选中时候都会变成设置的颜色
@property(null_resettable, nonatomic,strong) UIColor *tintColor; //|线条的颜色
// 搜索框背景颜色
@property(nullable, nonatomic,strong) UIColor *barTintColor;

// 搜索框样式
// UISearchBarStyleMinimal:不显示背景,系统自带的背景色无效,自定义的有效,常用在Calendar, Notes and Music
// UISearchBarStyleProminent、UISearchBarStyleDefault:显示背景,常用在my Mail, Messages and Contacts
@property (nonatomic) UISearchBarStyle searchBarStyle

// 选择按钮视图的按钮标题    
@property(nullable, nonatomic,copy) NSArray<NSString *> *scopeButtonTitles ; 
// 选中的按钮下标值 ,默认 0. 如果超出范围则忽略
@property(nonatomic) NSInteger  selectedScopeButtonIndex ; 
// 是否显示搜索栏的附件选择按钮视图
@property(nonatomic) BOOL showsScopeBar;

// 搜索框背景图片
@property(nullable, nonatomic,strong) UIImage *backgroundImage;
// 搜索框附属分栏条的背景颜色
@property(nullable, nonatomic,strong) UIImage *scopeBarBackgroundImage;

// 搜索框中文本框的背景偏移量
@property(nonatomic) UIOffset searchFieldBackgroundPositionAdjustment;
// 搜索框中文本框的文本偏移量
@property(nonatomic) UIOffset searchTextPositionAdjustment;
b、方法
// 设置是否动画效果的显示或隐藏取消按钮
 - (void)setShowsCancelButton:(BOOL)showsCancelButton animated:(BOOL)animated 

// 1.设置搜索框背景图片
- (void)setBackgroundImage:(nullable UIImage *)backgroundImage forBarPosition:(UIBarPosition)barPosition barMetrics:(UIBarMetrics)barMetrics 
//  获取搜索框背景图片
- (nullable UIImage *)backgroundImageForBarPosition:(UIBarPosition)barPosition barMetrics:(UIBarMetrics)barMetrics 

// 2.设置选择按钮视图的背景图片
- (void)setScopeBarButtonBackgroundImage:(nullable UIImage *)backgroundImage forState:(UIControlState)state 
// 获取选择按钮视图的背景图片
- (nullable UIImage *)scopeBarButtonBackgroundImageForState:(UIControlState)state  

// 3.设置搜索框文本框的背景图片
- (void)setSearchFieldBackgroundImage:(nullable UIImage *)backgroundImage forState:(UIControlState)state 
// 获取搜索框文本框的背景图片
- (nullable UIImage *)searchFieldBackgroundImageForState:(UIControlState)state

// 4.设置搜索框的图标
- (void)setImage:(nullable UIImage *)iconImage forSearchBarIcon:(UISearchBarIcon)icon state:(UIControlState)state;
// 获取搜索框的图标
- (nullable UIImage *)imageForSearchBarIcon:(UISearchBarIcon)icon state:(UIControlState)state;

// 5.设置选择按钮视图的分割线图片
- (void)setScopeBarButtonDividerImage:(nullable UIImage *)dividerImage forLeftSegmentState:(UIControlState)leftState rightSegmentState:(UIControlState)rightState;
// 获取选择按钮视图的分割线图片
- (nullable UIImage *)scopeBarButtonDividerImageForLeftSegmentState:(UIControlState)leftState rightSegmentState:(UIControlState)rightState;

// 6.设置选择按钮视图的标题样式
- (void)setScopeBarButtonTitleTextAttributes:(nullable NSDictionary<NSString *, id> *)attributes forState:(UIControlState)state;
// 获取选择按钮视图的标题样式
- (nullable NSDictionary<NSString *, id> *)scopeBarButtonTitleTextAttributesForState:(UIControlState)state

//  设置搜索框图标的偏移量
- (void)setPositionAdjustment:(UIOffset)adjustment forSearchBarIcon:(UISearchBarIcon)icon;
//  获取搜索框图标的偏移量
- (UIOffset)positionAdjustmentForSearchBarIcon:(UISearchBarIcon)icon;
c、UISearchBarDelegate代理方法
// 将要开始编辑文本时会调用该方法,返回 NO 将不会变成第一响应者
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar;                      
// 开始输入文本会调用该方法
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar;                     
// 将要结束编辑文本时会调用该方法,返回 NO 将不会释放第一响应者
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar; 
 // 结束编辑文本时调用该方法
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar;     
// 文本改变会调用该方法(包含clear文本)
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText; 
// 文字改变前会调用该方法,返回NO则不能加入新的编辑文字
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text ;

// 键盘上的搜索按钮点击的会调用该方法
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar;     
// 搜索框右侧图书按钮点击会调用该方法
- (void)searchBarBookmarkButtonClicked:(UISearchBar *)searchBar ;
 // 点击取消按钮会调用该方法
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar;   
// 搜索结果列表按钮被按下会调用该方法
- (void)searchBarResultsListButtonClicked:(UISearchBar *)searchBar ; 
// 搜索框的附属按钮视图中切换按钮会调用该方法
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope;

10、UIViewController

a、UINavigationController
运行效果
导航栏
配置返回按钮
- (void)createBackBarButton
{
    // 自定义后退按钮的文字和颜色
    // 如果不想显示文字,直接"",就会单独显示一个系统的返回箭头图标
    // 必须放在触发push的那个页面才起作用
    // 设置返回按钮的属性
    UIBarButtonItem *backItem = [[UIBarButtonItem alloc] init];
    NSMutableDictionary *backTextAttrs = [NSMutableDictionary dictionary];
    backTextAttrs[NSFontAttributeName] = [UIFont fontWithName:@"GillSans-SemiBoldItalic" size:20];// 字号
    [backItem setTitleTextAttributes:backTextAttrs forState:UIControlStateHighlighted];// 高亮状态
    backItem.title = @"返回";
    self.navigationItem.backBarButtonItem = backItem;
}
配置导航栏
- (void)createNavigationController
{
    self.navigationItem.title = @"详情界面";
    
    // 使用图片作为导航栏标题
    self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"luckcoffee.JPG"]];
    
    // 导航栏右边按钮添加文本
    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"编辑" style:UIBarButtonItemStylePlain target:nil action:nil];
    self.navigationItem.rightBarButtonItem = item;
    self.navigationItem.rightBarButtonItems = @[item,item];// 数组
    
    // 导航栏右边按钮添加图片后仍然使按钮保持原来的系统颜色
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"luckcoffee.JPG"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:nil action:nil];
    
    // 设置导航栏标题的属性
    NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
    textAttrs[NSForegroundColorAttributeName] = [UIColor redColor];// 字体颜色
    textAttrs[NSFontAttributeName] = [UIFont fontWithName:@"GillSans-SemiBoldItalic" size:18];// 字号
    self.navigationController.navigationBar.titleTextAttributes = textAttrs;
    
    // 设置导航栏的背景颜色
    [self.navigationController.navigationBar setBarTintColor:[UIColor greenColor]];
    [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor whiteColor]}];
    
    // 给导航栏添加背景图片
    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"luckcoffee.JPG"] forBarMetrics:UIBarMetricsDefault];
    
    // 获取选中的TabBar
    UINavigationController *navigationController =  (UINavigationController *)self.parentViewController;
    NSString *selectTab = navigationController.tabBarItem.title;
    NSLog(@"选中的TabBar标题为:%@",selectTab);
}
b、UITabBarController
// push到下个界面隐藏底部TabBar
loginViewController.hidesBottomBarWhenPushed = YES;

// 获取当前选中的item
selectedItem

// badge的数值
tabBarItem.badgeValue = @"10";

// Tab标签栏跳转,比如从用户中心跳转到首页:
[self.navigationController popViewControllerAnimated:NO];
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
UITabBarController *tab = (UITabBarController *)delegate.window.rootViewController;
tab.selectedIndex = 0;

// 数组
self.viewControllers = @[redVC, blueVC];

11、GestureRecognizer

a、Tap: 点击
2020-10-29 15:43:11.537921+0800 UIKitGrammarDemo[27813:955310] 点击改变testView的颜色
Tap: 点击
// Tap: 点击
- (void)tapGestureRecognizer
{
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapView:)];
    tap.numberOfTapsRequired = 2;// 设置轻拍次数
    tap.numberOfTouchesRequired = 2;// 设置手指字数

    [self.gestureRecognizerView addGestureRecognizer:tap];
}

- (void)tapView:(UITapGestureRecognizer *)sender
{
    // 改变testView的颜色
    self.gestureRecognizerView.backgroundColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:1];
    NSLog(@"点击改变testView的颜色");
}
b、Swipe: 轻扫
2020-10-29 15:49:03.819006+0800 UIKitGrammarDemo[1244:183307] 轻扫改变testView的颜色
2020-10-29 15:49:09.874471+0800 UIKitGrammarDemo[1244:183307] 从左往右轻扫
- (void)swipeGestureRecognizer
{
    UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeView:)];
    swipe.numberOfTouchesRequired = 1;// 设置手指个数
    swipe.direction = UISwipeGestureRecognizerDirectionLeft;// 设置轻扫方向(默认是从左往右)

    [self.gestureRecognizerView addGestureRecognizer:swipe];
}

- (void)swipeView:(UISwipeGestureRecognizer *)sender
{
    // 改变testView的颜色
    self.gestureRecognizerView.backgroundColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:1];
    NSLog(@"轻扫改变testView的颜色");
    
    if (sender.direction == UISwipeGestureRecognizerDirectionLeft)
    {
        NSLog(@"从左往右轻扫");
    }
}
c、LongPress: 长按
2020-10-29 15:51:28.415827+0800 UIKitGrammarDemo[1248:184810] 长按改变testView的颜色
- (void)longPressGestureRecognizer
{
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
    longPress.minimumPressDuration = 2;// 最小长按时间
    
    [self.gestureRecognizerView addGestureRecognizer:longPress];
}

- (void)longPress:(UILongPressGestureRecognizer *)sender
{
    if (sender.state == UIGestureRecognizerStateBegan)// 在什么时候触发事件
    {
        // 改变testView的颜色
        self.gestureRecognizerView.backgroundColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:1];
        NSLog(@"长按改变testView的颜色");
    }
}
d、Pan: 平移
2020-10-29 16:35:39.932100+0800 UIKitGrammarDemo[28022:965824] 平移改变testView的颜色
Pan: 平移
- (void)panGestureRecognizer
{
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panView:)];
    [self.gestureRecognizerView addGestureRecognizer:pan];
}

- (void)panView:(UIPanGestureRecognizer *)sender
{
    // 起始点
    CGPoint point = [sender translationInView:self.gestureRecognizerView];
    
    // 第一种移动方法:每次移动都是从原来的位置移动
    sender.view.transform = CGAffineTransformMakeTranslation(point.x, point.y);
    
    // 第二种移动方式:以上次的位置为标准(第二次移动加上第一次移动量)
    sender.view.transform = CGAffineTransformTranslate(sender.view.transform, point.x, point.y);
    // 增量置为0
    [sender setTranslation:CGPointZero inView:sender.view];
    
    // 改变testView的颜色
    self.gestureRecognizerView.backgroundColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:1];
    
    NSLog(@"平移改变testView的颜色");
}
e、ScreenEdgePan: 屏幕边缘平移
- (void)screenEdgePanGestureRecognizer
{
    UIScreenEdgePanGestureRecognizer *screenEdgePan = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(screenEdgePanView:)];
    screenEdgePan.edges = UIRectEdgeLeft;// 视图位置(屏幕边缘)
    [self.gestureRecognizerView addGestureRecognizer:screenEdgePan];
}

// 不走这个方法......
- (void)screenEdgePanView:(UIScreenEdgePanGestureRecognizer *)sender
{
    // 获取拖动的位置
    CGPoint point = [sender translationInView:sender.view];
    
    // 每次都以传入的translation为起始参照
    sender.view.transform = CGAffineTransformTranslate(sender.view.transform, point.x, 0);
    
    // 设置当前拖动的位置
    [sender setTranslation:CGPointZero inView:sender.view];
    
    // 改变testView的颜色
    self.gestureRecognizerView.backgroundColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:1];
    
    if (sender.edges == UIRectEdgeLeft)
    {
        NSLog(@"从左边缘向右平移");
    }
}

获取屏幕边缘扇动手势

- (UIScreenEdgePanGestureRecognizer *)screenEdgePanGestureRecognizer
{
    UIScreenEdgePanGestureRecognizer *screenEdgePanGestureRecognizer = nil;
    
    if (self.view.gestureRecognizers.count > 0)
    {
        for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers)
        {
            NSLog(@"手势:%@",recognizer);
            if ([recognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]])
            {
                screenEdgePanGestureRecognizer = (UIScreenEdgePanGestureRecognizer *)recognizer;
                break;
            }
        }
    }
    
    return screenEdgePanGestureRecognizer;
}

输出结果为:

2020-09-25 14:51:28.050270+0800 FunctionCodeBlockDemo[9250:18335987] 手势:<UIScreenEdgePanGestureRecognizer: 0x7fb58ce046d0; state = Possible; delaysTouchesBegan = YES; view = <UIView 0x7fb58f8068f0>; target= <(action=compare:, target=<LittleMethodViewController 0x7fb58cd06e70>)>>
f、Pinch: 捏合
Pinch: 捏合
- (void)pinchGestureRecognizer
{
    // 设置缩放比例
    self.lastScale = 1;
    self.minScale = 0.5;
    self.maxScale = 2;
    
    UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchView:)];
    [self.gestureRecognizerView addGestureRecognizer:pinch];
}

- (void)pinchView:(UIPinchGestureRecognizer *)recognizer
{
    switch (recognizer.state)
    {
        case UIGestureRecognizerStateBegan:// 缩放开始
        case UIGestureRecognizerStateChanged:// 缩放改变
        {
            CGFloat currentScale = [[self.gestureRecognizerView.layer valueForKeyPath:@"transform.scale"] floatValue];
            CGFloat newScale = recognizer.scale - self.lastScale + 1;
            newScale = MIN(newScale, self.maxScale / currentScale);
            newScale = MAX(newScale, self.minScale / currentScale);
            
            self.gestureRecognizerView.transform = CGAffineTransformScale(self.gestureRecognizerView.transform, newScale, newScale);
            self.lastScale = recognizer.scale;
            
            break;
        }
        case UIGestureRecognizerStateEnded:// 缩放结束
            self.lastScale = 1;
            break;
        default:
            break;
    }
}
g、Rotation: 旋转
Rotation: 旋转
- (void)rotationGestureRecognizer
{
    UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationView:)];
    [self.gestureRecognizerView addGestureRecognizer:rotation];
}

- (void)rotationView:(UIRotationGestureRecognizer *)sender
{
    CGFloat rotationAngleInRadians = 0;// 旋转角度
    // 手势识别完成,保存旋转的角度
    if (sender.state == UIGestureRecognizerStateEnded)
    {
        rotationAngleInRadians += sender.rotation;
    }
    // 将上一次角度加上本次旋转的角度作为本次旋转的角度
    self.view.transform = CGAffineTransformMakeRotation(rotationAngleInRadians + sender.rotation);
}
h、支持多个UIGestureRecongnizer共存
// 先接受到了手势事件,直接就处理而没有往下传递实际上就是两个手势共存的问题,先执行了UIScrollerView中包含的手势
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    // 滑动返回无法触发,说明UIScreenEdgePanGestureRecongnizer并没有接受到手势事件
    if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]  && [otherGestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]])
    {
        // 返回YES,手势事件会一直往下传递,不论当前层次是否对该事件进行响应
        return YES;
    }
    else
    {
        return NO;
    }
}

12、touches与motion

a、响应屏幕触摸
// 手指按下时响应
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
    NSLog(@"手指按下时响应");
}

// 手指移动时响应
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];
    NSLog(@"手指移动时响应");
}

// 手指抬起时响应
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];
    NSLog(@"手指抬起时响应");
}

// 触摸取消(意外中断, 如:电话, Home键退出等)
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
    [super touchesCancelled:touches withEvent:event];
    NSLog(@"取消触摸响应(意外中断, 如:电话, Home键退出等)");
}

输出结果为:

2020-10-30 13:50:47.723917+0800 UIKitGrammarDemo[3009:597013] 手指按下时响应
2020-10-30 13:50:47.746602+0800 UIKitGrammarDemo[3009:597013] 手指移动时响应
2020-10-30 13:50:16.141409+0800 UIKitGrammarDemo[3009:597013] 手指抬起时响应
2020-10-30 13:50:47.747051+0800 UIKitGrammarDemo[3009:597013] 取消触摸响应(意外中断, 如:电话, Home键退出等)
b、运动事件监听
// 开始加速
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    [super motionBegan:motion withEvent:event];
    NSLog(@"开始加速");
}

// 结束加速
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    [super motionEnded:motion withEvent:event];
    NSLog(@"结束加速");
}

// 加速取消(意外中断, 如:电话, Home键退出等)
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    [super motionCancelled:motion withEvent:event];
    NSLog(@"加速取消");
}

输出结果为:

2020-10-30 13:51:02.554064+0800 UIKitGrammarDemo[3009:597013] 开始加速
2020-10-30 13:51:03.149090+0800 UIKitGrammarDemo[3009:597013] 结束加速

Demo

Demo在我的Github上,欢迎下载。
UIKitGrammarDemo

参考文献

iOS--UISearchBar 属性、方法详解及应用(自定义搜索框样式)

相关文章

  • IOS基础:OC的UIKit语法

    原创:知识点总结性文章创作不易,请珍惜,之后会持续更新,不断完善个人比较喜欢做笔记和写总结,毕竟好记性不如烂笔头哈...

  • 技术在于交流,知识在于收集(一)

    收集的一些iOS开发技术博客与牛人共同进步 iOS基础: OC语法基础 OC代码规范 从零学习iOS开发的15条建...

  • iOS-面试题-OC基础篇 (3) - (1)

    前言:面试笔试都是必考语法知识点。请认真复习和深入研究OC。 目录:iOS-面试题-OC基础篇 (1) - (84...

  • iOS-面试题-OC基础篇 (2) - (83)

    前言:面试笔试都是必考语法知识点。请认真复习和深入研究OC。 目录:iOS-面试题-OC基础篇 (1) - (84...

  • IOS基础:OC的Foundation语法

    原创:知识点总结性文章创作不易,请珍惜,之后会持续更新,不断完善个人比较喜欢做笔记和写总结,毕竟好记性不如烂笔头哈...

  • 无标题文章

    OC基础语法 //整型 NSIntegera =10; //NSLog是OC里面的打印函数 NSLog(@"a =...

  • iOS培训总结

    一:OC基础语法1 //整型 NSInteger a =10; //NSLog是OC里面的打印函数 NSLog(@...

  • Core Graphics

    Core Graphics 是iOS上层UIKit实现的基础,为了更好的了解iOS的绘制体系,学习Core Gra...

  • OC之01基础之基础语法

    01 语法概述 不妨将OC说成是面向对象的C语言,因为OC是在C语言的基础是建立的,而且在OC的语法中是完全...

  • OC语法基础

    一、属性与成员变量属性表达实例状态,描述类型对外结果,相比直接访问成员变量,属性可以做更多的控制。默认情况下,编译...

网友评论

      本文标题:IOS基础:OC的UIKit语法

      本文链接:https://www.haomeiwen.com/subject/lrnumktx.html