iPhone 9 导航及标签栏控制器

来源:互联网 发布:工业增加值月度数据 编辑:程序博客网 时间:2024/06/13 01:05

ScrollView

       UIScrollView

     UIScrollView为了显示多于一个屏幕的内容或者超过你能放在内存中的内容。

                 Scroll View为你处理缩小放大手势,UIScrollView实现了这些手势,并且替你处理对于它们的探测和回应。其中需要注意的子类是UITableView以及UITextView(用来显示大量的文字)。还有一个UIWebView,尽管那不是UIScrollView的直接子类,它适用UIScrollView去显示网页内容

        contentsize是内容的宽和高,contentsize.width是内容的宽度,contentsize.heght是高度,contentsizeUIScrollView的一个属性,它是一个CGSize,是由核心图形所定义的架构,那定义了你可以滚轴内容的宽度和高度,你也可以添加可以上下滚动的额外区域。第一种方法是你可以通过添加内容的大小来完成。另外一个比较动态的选择是UIScrollView的另一个属性contentInsetcontentInset增加你在contentsize中指定的内容能够滚动的上下左右区域数量contentInset.top以及contentInset.buttom分别表示上面和下面的距离。

          在滚轴视图中,有一个叫做ContentOffset的属性跟踪UIScrollView的具体位置,你能够自己获取和设置它,ContentOffset是你当前可视内容在滚轴视图边界的左上角那个点。如图:


          可以看出,ContentOffset内容中的那个点不是从contentInset的左上角开始的,而是内容的左上角,此时的ContentOffset是正值,但有时也是负值,如下图所示:


使用一个ScrollView

    创建一个UIScrollView

             CGRectframe = CGRectMake( 0, 0, 200, 200);

              scrollView= [[UIScrollView alloc] initWithFrame: frame];

   添加子视图(框架可以超过scroll view的边界)

            frame= CGRectMake( 0, 0, 500, 500);

            myImageView= [[UIImageView alloc] initWithFrame: frame];

           [scrollViewaddSubview:myImageView];

   设置内容尺寸

           scrollView.contentSize= CGSize(500,500);


扩展Scroll View的行为

     应用程序通常需要知道有关的滚图的事件

            scrolloffset改变的时候

          拖动开始和结束

           减速的开始和结束


通过子类化扩展Scroll View的行为

       创建一个子类

       重写一些功能并改变行为

       关于这种方式的争议

              应用程序的逻辑和行为变成了视图本身的一部分,就像,你可能有一些定制的滚轴逻辑,,在那你只在意一个视图控制,但你想在不同地方重复使用你的滚轴视图,如果你必须为每个都子类化,你最后会有很多不同的滚轴视图子类以及在视图中的特定应用逻辑。

             编写很多子类是很沉闷的事情,你最后会有很多无法重复使用的单独视图,而MVC的视图部分的一个重点是视图是可以在不同的控制器和不同的模式之中重复使用的,如果我们把所有逻辑都放在视图中,它减少了可复用性。

             你的代码变得很牢固地配对在一起,它实际上变成了超类的一部分,你无法从UIScrollView中析取它,之后用其它东西代替,如果它在你控制器中且为控制器的一部分,在之后更容易改变它工作的方式和重新安排你应用程序的一些部分。


通过委派来扩展Scroll View的行为(常用的)

        委派是一个单独的对象,协议,定义了委派会实现的一系列功能的Objective-C协议,它创建了一系列很清晰的撤销点,在那里你能定制行为和外观。它在这些对象之间保持了松散的配对,视图本身与视图控制器或任何其它的控制器对象,委派不是滚轴视图的直接子类,它比起牢固配对的子类更加的松散。

         UIScrollView委托

@protocolUIScrollViewDelegate <NSObject>

@optional//表示是可选的,不用实现所有的方法

-(void)scrollViewDidScroll:(UIScrollView*)scrollView;//每次滚轴的contentoffsize改变时都会被调用,当用户在四周移动手指时也会被调用

-(BOOL)scrollViewShouldScrollToTop:(UIScrollView*)scrollView;//如果你不是完全滚动到滚轴视图的顶部,你可以轻点状态栏,那个可视的滚轴视图会一直滚动到顶部,那是默认行为,你可以通过该方法返回NO来关闭它

@end

实现一个委托

        服从一个委托协议

@interfaceMyController : NSObject<UIScrollViewDelegate>

实现所以需要实现的方法以及可选的任意方法

-(void)scrollViewDidScroll:(UIScrollView*)scrollView

if(scrollView.contentOffset....){

}

      实际上在UIScrollViewDelegate该协议中所有的方法都是可选的。

使用ScrollView进行缩放

        设置最大/最小以及初始的缩放比例

scrollView.maxmumZoomScale= 2.0;

scrollView.minmumZoomScale= scrollView.size.width / myImage.size.width;

       实现缩放的委托方法

-(UIView*)viewForZoomingInScrollView:(UIScrollView*)scrollView {

returnsomeViewThatWillBeScaled;//返回的是会缩放的UIScrollView的一些子视图

}

实例:

       新建一个viewbased的项目,项目名为ScrollIPadViewController,删除.xib文件上的view,然后向.xib文件中拖拽入一个UIScrollView,按住control键,由File'sOwner拖向UIScrollView,实现view的连接,然后按住control键由UIScrollView拖向File'sOwner,实现委托的连接。

       scrollIPadViewController.h文件中:

#import<UIKit/UIKit.h>


@interfaceScrollIPadViewController : UIViewController{

UIImageView*imageView ;

}

@end


     scrollIPadViewController.m文件

-(void)viewDidLoad{

UIImage*image = [UIImageimageNamed:@"11.jpg"];

imageView= [[UIImageViewalloc]initWithImage:image];

[self.viewaddSubview:imageView];

[(UIScrollView*)self.viewsetContentSize:[imagesize]];

[(UIScrollView*)self.viewsetMaximumZoomScale:3.0];

[(UIScrollView*)self.viewsetMinimumZoomScale:0.1];

}

-(UIView*)viewForZoomingInScrollView:(UIScrollView*)scrollView {//对滚轴进行缩放就是对图片进行缩放

returnimageView;

}


(具体项目见我附件)



TableViews

     显示大型内容的列表

           单行,多列

            垂直滚动,没有水平滚动

           大量的数据集

   性能强大,而且普遍存在于iPhone的应用程序中


TableView Styles

         UITableView有两个默认的内置风格,第一个是UITableViewStylePlain(简明风格,简明风格表明表格视图自身没有真正地在你自己实际地提供任何外观之前提供很多的外观,大部分情况下,它会做的唯一的事情是它会给你这些headerfooter,在顶部的章节header有章节F,它是当前固定在屏幕的顶部,即使你滚动那个内容章节的header F会保持在那里,直到所有F的内容都移走,然后它滚出去。表格视图还提供你在右边的索引部分,那只用在简易风格的表格视图中,你能够获取它。)另一种风格是UITableViewStyleGrouped风格(组团风格),UITableViewStyleGrouped表格视图是UIKit提供的另外一个默认风格,它给围绕章节分段的外观,它是垂直条纹的背景,顶部是白色圆形分段,你默认通过UITableViewStyleGrouped获得该类型的外观。


表格视图以及组成部分

          在顶部,我们有表格header,它是UITableView上的一个可设置的属性,它只是个UIView,你能创建任何UIView子类或用UIImageViewUILable分配并设置它们为表格视图的tableheader view ,然后表格视图会安置它到你其余的内容之上,它会随着内容上下滚动。

        在表格视图的内容底部,我们有表格footer,与header一样是UIView的任意子视图,它是你设置的UITableView的属性,然后表格视图会安置它到你其余的内容之下,在表格headerfooter视图之间的是章节内容。

      在章节中,有章节的header和章节的footer,在它们之间是所有的独立单元,就是Tablecell。如下图:



使用TableViews

在表格视图中显示数据

定制显示的外观和行为


一个直接的解决方法

表格视图用来显示一列数据,所以使用一个数组

[myTableView setList : myListOfStuff];//该方法不存在,想法比较天真

该方法争议性

所有的数据必须事先装载

所有的数据都装载在内存中


更加灵活的方案

另外一个对象为表格视图提供数据

不是一次性全部取得

只取现在需要展示的数据

像一个委托,它是纯粹的数据导向,它只向数据源询问数据


UITableViewDataSource(数据源协议)

提供章节和行的数目

//optionalmethod ,default to 1 if not implemented

-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView;


//requiredmethod

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;

必要的时候向表格视图提供所要显示的cells

//required method

                        -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;//在该方法中,UITableViewCellUIView的一个子类,它知道如何在表格视图滚轴,知道如何绘制分组风格表格视图和组群风格表格视图,它必须自己是一个UITableViewCell或者UITableViewCell的子类。



NSIndexPath

          Foundation框架中的一个普通的类,它提供了到嵌套数列的树中特定节点的路径,事实上,它是一个整数阵列,表格视图使用这个去表现在特定章节中的特定行,UITableView用的所有索引路径正好有两个元素,第一个是章节,第二个是行。



NSIndexPathTableViews

@interfaceNSIndexPath (UITableView) {

}

+(NSIndexPath*)indexPathForRow:(NSUInteger)row inSection:(NSUInteger)section;

@property(nonatomic,readonly)NSUIntegerrow;

@property(nonatomic,readonly)NSUIntegersection;

@end


SingleSection Table View

返回行数

-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section{

return[myStringcount];

}

请求时提供一个单元

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {

UITableViewCell*cell = ......;

cell.textLabel.text=[myStringobjectAtIndex:indexPath.row];

return[cellautorelease];

}


单元复用(cellreuse

        当你轻滑屏幕,你必须一次滚动上百行的文字,很多很多的不同单元,它不会完成的很好,每次一个消失,你破坏呢个表格视图单元,然后为下一个创建新的,我们最终会做的是当一个表格视图单元从顶部消失,它会放在一个复用队列中,并且在你的TableViewCellforRowIndexPath方法中,你可以选择,当然你应该总是这样做,你有机会去在分配新的单元前,向表格视图询问复用队列其中的一个单元,如果一个单元已经从顶部滚轴消失,对于显示当前可视的东西,它不会必须的,你能取得它改变它的内容为你所需要显示的新行而它会被重新滚进底部。(有点像循环瀑布)

              -(UITableViewCell*)dequeueReusableCellWithindentifier:(NSString*)identifier;

            //取回可复用的一个单元

  -(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {

UITableViewCell*cell = [tableViewdequeueReusableCellWithIdentifier:@"MyIdentifier"];

if(cell==nil){

cell=[[[UITableViewCell alloc] initWithStyle:.....reuseIdentifier:@"MyIdentifier"]autorelease];

}

cell.text= [myStringobjectAtIndex:indexPath.row];

returncell;

}


触发一个更新

什么时候数据源会被请求数据

当一行变得可视

完全更新会被响应当使用reloadData

-(void)viewWillAppear:(BOOL)animated {

[superviewWillAppear:animated]; //所有的数据重新被加载,然后在放到复用队列中

[self.tableViewreloadData];

}


章节和行进行重载数据

-(void)insertSections:(NSIndexSet*)sectionswithRowAnimation:(UITableViewRowAniamtion)animation;//可以插入整个章节

-(void)ideleteSections:(NSIndexSet*)sectionswithRowAnimation:(UITableViewRowAniamtion)animation;//可以删除整个章节

-(void)reloadSections:(NSIndexSet*)sections withRowAnimation:

(UITableViewRowAniamtion)animation;//iPhoneos 3.0中重载章节数据(上面两个方法的合并)

它们能重载部分的数据,而不会把所有东西都丢掉


-(void)insertRowsAtIndexPaths:(NSArray*)indexPahts withRowAnimation:(UITableViewRowAniamtion)animation;

-(void)deleteRowsAtIndexPaths:(NSArray*)indexPahts withRowAnimation:(UITableViewRowAniamtion)animation;

-(void)reloadRowsAtIndexPaths:(NSArray*)indexPahts withRowAnimation:(UITableViewRowAniamtion)animation;


其它的数据源方法

    为章节的headerfooter设置标题(表格的headerfooter是表格视图上的属性,你只分配那些视图章节headerfooter是依据章节的,因此它们由委派功能所提供)

允许编辑和重排单元


外观和行为

     UITableViewDelegate

可定制外观和行为

逻辑独立于视图

数据源和委派经常是相同的对象(事实上,很少情况下数据源不是委派)

   表格视图的外观和行为

          定制表格视图单元的外观

           -(void)tableView:(UITableView *) tableView willDisplayCell:(UITableViewCell *)cellforRowAtIndexPath:(NSIndexPath *)indexPath;

        这个会在表格视图的其中一个单元变为可视前立刻被调用,它是你在表格视图单元显示在屏幕上之前的外观定制的最后机会,它保证一旦你调用这个方法,我们不会涉及任何单元的外观,这之后,你改变的任何东西都会显示在屏幕上,如果有一些东西你可能在TableViewcellForRowAtIndexPath方法中不知道,你想稍微懒惰地做这个,这会在那之后最后的机会去修改外观。


验证和响应所选择的变化

使用表格视图委派功能,对于选择会有不同的功能

-(NSIndexPath*)tableView:(UITableView *)tableViewwillSelectRowAtIndexPath:(NSIndexPath *)indexPath;

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath;//用户选择完成抬起手指,在该方法中,你可能决定去分配新的UIViewController,然后推它到self.navigationContrller,因此一些新事物滑进来,行选择通常会触发一个事件。选择通常不是一个持续的事情,它通常不会在你轻敲之后保持选择状态,通常会谈出选择然后完成一个行为,或者你把它滑出屏幕,当然滑回来时会淡出。在iphone应用程序中你也会看到连续的选择,我们在表格试图中是支持持续选择的,如果用户选择一行而你没有反选它,我们不会替你反选,过去在iPhoneOS 2.0中不是这样的,如果你不反选它,这个行为是不确定的,我们现在支持这个持续选择行为。


响应选择

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {

NSIntegerrow = indexPath.row ;

idobjectToDispaly = [myObjects ObjectAtIndex:row ];


MyViewController* myViewController = …....;

myViewController.object = objectToDispaly ;

[self.navigationControllerpushViewController: myViewController animated:YES];

}

修改和禁用选择

-(NSIndexPath*)tableView:(UITableView *)tableViewwillSelectRowAtIndexPath:(NSIndexPath *)indexPath

if(indexPath.row== ….) {

returnnil;

}

else{ return indexPath ;}


UITableViewController

       UIViewController的子类,如果你想用全屏表格试图风格,它会是很便利的起点,表格试图会被自动创建,这包括控制器,表格视图,数据源和委派,它在你第一次出现时替你调用reloadData,它在用户导航回去时反选,会知道你之前所选的itemUITableViewController在正确的时间替你处理反选的事情,它还会闪烁滚动指示条,实际上这是iPhone人机界面的一部分。


TableView cells

指定的初始化程序

-(id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier ;

//旧的版本,现在已经不是默认的初始化程序了


-(id)initWithStyle:(UITableviewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier ;

//新版本


单元风格(cellstyle)


基本属性

UITableViewCell有一个图像视图和一到两个的文本标签

cell.imageView.image= [UIImage imageNamed:@”vitolidok.png”];

cell.textLabel.text= @”Vitol Idol”;

cell.detailTextLabel.text=@”Billy Idol”;

效果如图:


 如果你在表格视图单元的默认风格上设置detailTextLabel.text,它是不会做任何事情,因为它不显示一个额外的detailText


附件类型

//UITableView委托方法

-(UITableViewCellAccessoryType)tableView:(UITableView*)table accessoryTypeForRowWithIndexPath:(NSIndexPath *) indexPath;

 

-(void)tableView:(UITableView *)tableViewaccessoryButtonTappedForRowWithIndexPath:(NSIndexPath *) indexPath {

//只有是在蓝色描述的按钮(也就是上面的第二个)

NSIntegerrow = indexPath.row.

}


定制内容视图

在有些情况下,简单的图像和文本是不够的

UITableViewCell有一个contentview属性

contentview添加额外的视图

-(UITableViewCell*) tableView :(UITableView) tableViewcellForRowAtIndexPath:(NSIndexPath *)indexPath {

UITableViewCell*cell = ….......;

CGRectframe = cell.contentView.bounds;

UILabel*myLabel = [[UILabel alloc] initWithFrame :frame];

myLabel.text= ….;

[cell.contentViewaddSubview : myLabel];

[myLabelrelease];

}