UIScrollView/UIPageControl/


今天学习了UIScrollView和UIPageControl


UIScrollView是滚动视图

最关键的三个点

1.初始化UIScrollView的frame

2.设置UIScrollView的contentSize,contentSize的大小一定要大于frame,不管长或高,因为如果滚动范围等于frame的大小,则看不出滚动效果。

3.添加ScrollView到视图上


UIPageControl

最关键的三个点

1.初始化UIPageControl

2.设置UIPageControl的numberOfPages

3.添加到想要添加到得视图上


关于UIScrollView和UIPageControl的合作


自己做了个相册 可以滚动的相册 关键点出了上述几条之外

还有PagingEnabled是否整屏翻动的属性还有个关键的是contentOffset视图左上角距离坐标原点的偏移量。

UIScrollView的滚动相关属性

ScrollEnabled是否能够滚动 比较重要


相册的图片是可以缩放的,这就涉及到UIScrollView的缩放的几个比较重要的相关属性

minimumZoomScale 缩放的最小比例

maxmumZoomScale 放大的最大比例

zoomScale 设置变化比例

要实现缩放,还需要实现delegate,指定缩放的视图是谁。


另外UIScrollView的滚动代理方法在这里也要提一下

scrollViewDidScroll··· 滚动就会触发

scrollViewDidEndDecelerating···结束减速时触发(停时)

UIScrollView的缩放代理方法

viewForZoomingInScrollView···指定某个UIScrollView的子视图可以被放大缩小


UIPageControl与UILabel相似,用于指示当前第几页,通常与UIScrollView配合使用。

其中比较重要的属性有

currentPage 当前页 也是默认第几页

numberOfPages  指定页面的个数


UIPageControl从类名可以看出,父类是UIControl,所以可以像button一样添加事件,

只不过事件触发使用的是UIControlEvent是ValueChanged


ScrolView和PageControl的合作

通常在ScrollView滚动的时候修改PageControl的currentPage使用场景:引导页,首页的轮播图。

相册一般就是下一节的内容,视图控制器与PageControl的结合使用


总结

contentSize决定了ScrollView是否滚动,contentOffset控制内容区域的偏移量,pageEnabled控制能否整页滚动。

scrollView实现缩放需要指定最大缩放系数,最小缩放系数,并指定缩放的视图。

pageControl不单独使用,通常与ScrollView结合使用

UIScrollView/UIPageControl/_第1张图片


9.8——学习第8天


今天学习了UINavigationViewController和界面通信

UINavigationViewController是一种导航控制器 与一般ViewController是存在不同的 它继承于UIViewController

导航控制器,是iOS中最常用的多视图控制器之一,它用来管理多个视图控制器。

导航控制器可以认为是管理控制器的控制器,主要管理有层级关系的控制器。

那么,接下来我们就建一个导航控制器看看,下图就是一个导航控制器的模样。

设置是后期设置的标题内容,默认是一个这样的一个长方形的视图样子。

UIScrollView/UIPageControl/_第2张图片

学习导航控制器必须明白的知识点~

导航控制器是以栈的方式管理所控制的视图控制器,至少要有一个被管理的视图控制器,这个控制器我们称作,导航控制器的根视图控制器。

任何继承自UIViewController的类(多态)都可以作为根控制器。

UINavigationController通过栈的方式管理控制器的切换,控制入栈和出栈来展示各个视图控制器。

UINavigationController的ContentView里始终显示栈顶控制器的View

viewControllers属性存储了栈中的所有被管理的控制器

navigationController属性,父类中的属性,每个在栈中的控制器,都能通过此属性,获取自己所在的UINavigationController对象。


其中入栈和出栈(也就是所谓的不同层级的控制器之间的切换)的方法有

pushViewController:animated 进入下一个试图控制器

popViewController:animated:返回上一个视图控制器

popToViewController:animated 返回到指定的视图控制器

popToRootViewControllerAnimated 返回到根视图控制器

常用属性

viewControllers 所有处于栈中的控制器

topViewController 位于栈顶的控制器

visibleViewController 当前正在显示的控制器

naVigationBar导航条


说到导航控制器不得不提的是UINavigationBar

如同一个酒吧需要有自己的吧台一样,每个酒吧的样式是差不多的,但是因为吧台设计的不同使得每个酒吧也有点不一样呢。


navigationBar是什么呢? 是一个导航条,iOS7之后默认是透明的(为了看起来更加简洁),iOS7之前默认是不透明的(看起来比较逼真)。

navigationBar在透明情况,与contentView会重合一部分区域。

navigationBar在不透明情况,contentView跟在navigationBar的下面

navigationBar竖屏下默认高度是44,横屏下默认高度是32,这个就涉及到自定义导航栏的设计了,要考虑吧的是横竖屏不同情况。

navigationBar的机构

UIScrollView/UIPageControl/_第3张图片

导航条可以自定义吗?这个问题问的好。

可以。

barTintColor设置导航条的颜色 注意 不是文字的颜色 也不是按钮的颜色哦 是整条导航栏的颜色呢

setBackgrundImage:forBarMetrics:导航条加背景图片,这点大家可以参考QQ的自定义界面,各种皮肤是不是很漂亮呢?


管理UINavigationItem

UiNavigationBar 除了能定义自身的样式外,还管理一组UINavigationItem。

与UINavigationController相似,UINavigationBar也是以栈的方式管理一组UINavigationItem,提供push和pop操作Item。

那么Item是个什么东西呢?

其实每个视图控制器都有一个navigationItem属性。

navigationItem中可以设置导航条上的左按钮(leftBarButtonItem)右按钮(rightBarButtonItem),标题(self.navigationItem.title=@"设置";)等

会随着控制器的显示,也显示到navigationBar上面。

UINavigationItem属于MVC中的M,封装了要显示在UINavigationBar上的数据。


看到左按钮和右按钮是不是又好气BarButtonItem是个什么鬼?

我来介绍一下吧,全名是UIBarButtonItem,它属于MVC中的M,也就是数据模型。

它定义了UINavigationItem上按钮的触发时间,外观等,

有几个方法,你们可以感受一下···

-initWithBarButtonSystemItem:target:action:

-initWithTitle:style:target:action:

-initWithImage:style:target:action:

tintColor


下面我们来介绍一下一个重要的知识点 界面间传值 这个需要你深度理解(很重要,我就不太懂)

下面介绍的是两种传值的方法,一般从第一个页面传值给第二个页面都是用属性传值,但是从第二个页面传给第一个页面就是用代理传值了。

/*
 属性:
    1.在第二个控制器.h文件声明传值属性
    2.在第一个页面跳转第二个页面的方法中,给第二个控制器对象的传值属性赋值
    3.在第二个控制器的viewDidLoad方法中,取出属性的值,放到页面上显示
 
 
 代理传值:
    1.在第二个控制器的.h文件声明了协议和协议方法
    2.在第二个控制器的.h文件声明了delegate属性
    3.在第二个控制器的.m文件中,返回上一个页面的方法中,让delegate去执行协议方法,并且把要传递的值,作为参数
 
    4.在第一个控制器跳转到第二个控制器的方法中,secondVC.delegate = self;
    5.遵守协议
    6.实现协议方法,获取参数的值,放到页面上显示
 */

好了,现在我们来做一下今天的总结把~

UINavigationController 以栈的方式管理视图控制器,通过push和pop控制跳转,

这里有个小tip:后面我们还会学到模态,使用present和dismiss控制“跳转”的,不要混淆哦~

UINavigationBar管理一组UINavigationItem,UINavigationItem包含了UIBarButtonItem

使用属性传值解决从前往后传值的问题,

使用delegate解决从后往前传值的问题。


那么我学完了NavigationViewController之后做了些什么呢

UIScrollView/UIPageControl/_第4张图片

做了一个结合ScrollView的相册 但是做的不够完善···

UIScrollView/UIPageControl/_第5张图片





9.10——学习第9天


今天学习了UITableView表视图的一个基础

下图是成品

UIScrollView/UIPageControl/_第6张图片

说说这个表视图啊,是个UI学习中的一个重点,为什么呢?从它在APP中的应用就可以看出来。

我不是做广告,我不是做广告,我不是做广告,重要的事情要说三遍!

比如美团APP 滑动的那些一条一条的团购就是一个表视图的使用。

Zaker 这个APP 每条新闻,每条资讯也是一个表视图的使用。

淘宝 每个商品还是一个表视图的使用

系统中的通讯录,也是基于表视图做出来的应用呢。

看吧,表视图在生活中的使用如此之多,你动心了嘛?

好啦,这是后事儿,我们要做的是先学好这个TableView呢


今天我们要学的内容是很重要的,这个事表视图的基础,一定要吃透哦~

表视图是干什么的呢?

前文已经提到,表视图通常用来管理一组具有相同数据结构的数据。什么新闻啊,团购啊,商品啊,是不是,当然还有通讯录。


现在开始进入正题

表视图UITableView继承子UIScrollView,所以可以滚动,对于UIScrollView不熟悉的同学请自己回顾哦~

表视图的每一条数据都是现实在UITableViewCell中,就像组成一个人需要很多很多细胞一样,表视图也需要细胞~

表视图可以区分现实数据,每个分区称为一个section,每一行称为一个row,都是从0开始的。


表视图这么好,该怎么创建呢?

其实表视图的创建和其他视图是一样的,但是也有区别,多了个样式。

UITableView *tableView=[[UITableView alloc]initWithFrame:self.bounds style:UITableViewStyleGrouped];
[self addSubview:tableView];

这里除了style样式有plain和group两种之外

还有分割线样式separatorStyle和分割线颜色separatorColor的还有rowHeight行高等重要属性。

然后把表视图添加到视图中,可是运行出来的结果完全看不到是什么情况?


其实UITableView有一个很重要的特点,把它和其他视图区分开来,那就是它有自己的DataSource 数据源。

DataSource实际上和Delegate差不多,都是要遵守一个协议,区别呢?问度娘去···


那我们接下来的操作是到ViewController里面指定表视图的数据源,然后遵守数据源的协议。

数据源是负责给TableView提供数据。

下一步我们就要实现协议方法了

1、设置组数(这里一定要说的是这是表视图的样式,有分组的也有平滑的,要分组才能看出组别呢)

2、设置行数(和组数不一样是必选的协议方法,协议分可选择的必选的方法,这个大家一定要清楚)

3、设置每行显示的什么,这就涉及到UITableViewCell,返回值一定是它,但是这里要提到的重点是cell的重用机制。

重用机制:

UITableVIew靠mutableSet来实现重用功能。

出屏幕的cell会添加到mutableSet中,即重用池,进入屏幕的cel,先从重用池中获取,如果获取不到,才创建一个cell,在cell显示之前,给cell赋上相应的内容。

cell 的reuseIdentifier是重用的关键。

下图就是一个设置每行显示什么方法的具体实现:

UIScrollView/UIPageControl/_第7张图片

提到每一行显示的数据我要仔细说明一下

cell.textLable.text是显示每一行位于第一行上面的文字的。

cell.detailTextLable.text是显示每一行位于第二行上面的文字。

cell.imageView.image是显示前面那个图片的。

cell.accessoryType是选择后面是个 > 还是一个 √ 还是别的···学名叫什么’指定辅助效果样式‘,似乎然并卵···

selectionStyle是指定选中效果,具体自行分析吧···


4、设置分区标题,可选方法,这里返回值就是NSString类型的咯。

5、设置快速索引,可选方法,因为快速索引是有一个或者多个的,所以要用数组。返回值就是NSArray类型的。

进行第六步之前,我们要设置表视图的代理,然后遵循其代理协议,一般我们会和数据源一起搞定。避免忘记。

6、点击某行执行的方法,这是代理方法。一般这种的返回值是Void,记住返回值是很重要的,能提高你的工作效率。


表视图的配置问题

NSindexPath 它有几个谁能够 一个是行 row 一个是组 section

还有一个方法是 +(NSindexPath *)indexPathForRow:(NSUInteger)row inSection:(NSUInteger)section


多个分区问题

TableView默认是一个分区,可是设置多个分区

tableView的plain和group样式决定分区的样式不同。

每个分区可以设置区头区尾。

方法见下一节


总结

TableView有两种样式:plain和grouped

由DataSource提供要显示的数据,delegate提供辅助设置。

系统提供4种样式的cell

TableView的重用机制极大提升了性能。




今天暂时介绍这些。明天我们还要讲。


9.11 


今天我们首先要做的是回顾昨天的内容,其次是我们今天的新内容。

今天的内容很简单,就是讲TableView的编辑操作。

编辑包括什么,一般我们都会想到,增删查改。

但是我们今天讲的是TableView的删除和移动两个操作。

UIScrollView/UIPageControl/_第8张图片

UIScrollView/UIPageControl/_第9张图片

删除就是前面的减号,移动就是后面的三条杠,大家应该是认识的。


下面我们先来看一下TableView的编辑 TableViewDataSource的协议方法

这是

看到左上角的编辑按钮了嘛,我们要先对他进行设置,点击编辑按钮之后会进入下面这种样子


1.让TableView处于编辑状态

-(void)setEditing:(BOOL)editing animated:(BOOL)animated;

设置编辑按钮的点击事件

//编辑按钮的点击事件
- (void)editBarButtonItemAction:(UIBarButtonItem *)sender
{
    if (self.personView.tableView.editing==YES) {
        sender.title=@"编辑";     
    }
    else
    {
        sender.title=@"完成";

        
    }
    //设置取反状态
    [self.personView.tableView setEditing:!self.personView.tableView.editing animated:YES];
    
    
    
}


2.设置编辑范围 这里是可选方法 一般默认是全部都可以编辑

//设置编辑范围
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
//    if (indexPath.section==0) {
//        return NO;
//    }
    //默认情况下所有行都可以被编辑,当有特殊情况时进行判断,然后返回YES代表可以编辑,返回NO,代表不可以编辑
    return YES;
}


3.设置编辑样式 这个就是控制前面显示的是+号还是-号(添加还是删除)

//设置编辑样式
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //进行判断,并返回相应的删除模式
//    if (indexPath.section==0) {
//        return UITableViewCellEditingStyleInsert;
//    }
    return UITableViewCellEditingStyleDelete;
    //|UITableViewCellEditingStyleInsert;
}


4.处理编辑过程 必选方法 否则实现不了删除操作(先操作数据源,在修改UI)

//处理编辑过程
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{

    
    
    //根据indexPath.section获取key
    NSString *key=self.allDataDic.allKeys[indexPath.section];
    //获取数组
    NSMutableArray *mutablearray=self.allDataDic[key];
    //判断元素是否为一个
    if (mutablearray .count==1) {
        //删除分组
        [self.allDataDic removeObjectForKey:key];
        NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:indexPath.section];
        //更新页面
        [tableView deleteSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];
    }
    else
    {
        //删除row
        [mutablearray removeObjectAtIndex:indexPath.row];
        //更新页面
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
  }  

 这里要注意的是一定要更新页面,更新页面,更新页面,重要的事情要说三遍!!!


这样你就可以删掉一个联系人,如果这个组的联系人为空的话,就删除整个分组了。


接下来看看怎样移动吧?

移动和编辑是一样的道理

1.让TableView处于编辑状态(同上)

2.设置移动范围 可选方法 默认全部都可以移动

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

3.处理移动过程

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
    //更新数据
    //先删除再插入
    
    //1.先获取key值
    NSString *key=self.allDataDic.allKeys[sourceIndexPath.section];
    //2.获取数组
    NSMutableArray *mutableArray=self.allDataDic[key];
    //3.获取元素
    Person *person=mutableArray[sourceIndexPath.row];
    //同组
    if (sourceIndexPath.section==destinationIndexPath.section) {
    //4.删除元素
    [mutableArray removeObject:person];
    //5.插入元素
    [mutableArray insertObject:person atIndex:destinationIndexPath.row];
    }
    //不同组
    else
    {
       //先从本来的数组中删除这个元素
    [mutableArray removeObject:person];
       //获取将要插入的目的分区数组的key值
    NSString *key2=self.allDataDic.allKeys[destinationIndexPath.section];
        //获取将要插入的目的分区数组
    NSMutableArray *mutableArray2=self.allDataDic[key2];
        //将移动的元素插入到目的分区的数组中
    [mutableArray2 insertObject:person atIndex:destinationIndexPath.row];
        //重新加载数据 被移动完的分组就消失了
        
    if ([[self.allDataDic objectForKey:key]count]==0) {
            [self.allDataDic removeObjectForKey:key];
        }
        
        
        [self.personView.tableView reloadData];
    }
    
}

这里需要注明的是,一般都是同组间移动。

4.监测移动过程,实现限制跨分区移动(就是不能移动到别的分区)

-(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    if (sourceIndexPath.section==proposedDestinationIndexPath.section) {
        return proposedDestinationIndexPath;
    }
    else
    {
        return sourceIndexPath;
    }
}

懒加载

//重写属性的getter方法 在setter方法中不能使用getter方法 在getter方法中不能使用setter方法
-(NSMutableDictionary *)allDataDic//setter方法
{
    //懒加载
    if (_allDataDic ==nil) {
        self.allDataDic=[NSMutableDictionary dictionary];//setter方法
    }
    return _allDataDic;
}


UITableViewController

UITableViewController继承子UIViewController自带一个TableView

self.view 不是UIView而是UITableView

DataSource和delegate默认都是self(UITableViewController)

开发中只需要建立UITableViewController子类


总结

无论编辑还是移动,都先让tableView进入编辑状态。

编辑结束或者移动结束,要先修改数组或字典中的数组,再更改UI

UITableViewController是封装好了各种delegate和DataSource能提高我们的开发速度。

UIScrollView/UIPageControl/_第10张图片1

你可能感兴趣的:(UI学习)