精华内容
下载资源
问答
  • 表视图

    千次阅读 2013-12-15 14:55:32
    IOS中,一般情况,我们都会以的形式来展示数据在表视图中,分节、分组和索引功能使我们展示的数据看起来更规整。 一、概述 1、表视图组成 IOS中,表视图是最重要的视图。与表视图相关的一些概念如下: ...

    在IOS中,一般情况下,我们都会以表的形式来展示数据。在表视图中,分节、分组和索引功能使我们展示的数据看起来更规整。


    一、概述

    1、表视图组成

    在IOS中,表视图是最重要的视图。与表视图相关的一些概念如下:

    (1)表头视图。表视图最上边的视图,用于展示表视图的信息,如表视图刷新信息等。

    (2)表脚视图。表视图最下边的视图,用于展示表视图的信息,如表视图分页时显示“更多”等信息。

    (3)单元格(cell)。单元格是组成表视图每一行的单位视图。

    (4)节(section)。它由多个单元格组成,有节头和节脚。


    2、表视图相关类

    表视图继承自UIScrollView,UITableViewCell是单元格类,UITableViewController类是UITableView的控制器,UITableViewHeaderFooterView类用于节头和节脚提供视图(IOS6之后才有的新类)。下图是相关类的构成。



    3、表视图分类

    表视图主要分为普通视图(下左图)和分组视图(下右图)。

    (1)普通视图。主要用于动态表,而动态表一般在单元格数目未知的情况下使用。

    (2)分组视图。一般用于静态表,组将表分成很多部分(由一些类似的单元格组成)。静态表一般用于控件的界面布局,它是在IOS 5之后由storyboard提供的。

                             


    除此之外,在表视图中还可以带有索引、选择列和搜索栏等。


    4、单元格的组成和样式

    单元格由图标、标题和扩展视图等组成。


    单元格可以有很多样式,也可以自定义。图标、标题和副标题可以有选择地设置,扩展视图可以有内置或者自定义,其中内置的扩展视图是在枚举UITableViewCellAccessoryType中定义的。UITableViewCellAccessoryType中定义的常量有:

    (1)UITableViewCellAccessoryNone,没有扩展视图。

    (2)UITableViewCellAccessoryDisclosureIndicator,扩展指示器。触摸该图标将切换到下一级表视图。

    (3)UITableViewCellAccessoryDetailDisclosureButton,细节展示按钮。触摸该单元格的适合,表视图会以视图的方式显示当前单元格的更多详细信息。

    (4)UITableViewCellAccessoryCheckmark,选中标志。表示该行被选中。


    在实际的开发过程中,我们首先考虑apple提供的一些固有单元格样式。IOS API提供的单元格样式是在枚举UITableViewCellStyle中定义的。UITableViewCellStyle中定义的常量有:

    (1)UITableViewCellStyleDefault。默认样式,只有图标和主表土。

    (2)UITableViewCellStyleSubtitle。带有副标题的样式,有图标、主标题和副标题。

    (3)UITableViewCellStyleValue1。无图标带副标题样式1,有主标题和子标题。

    (4)UITableViewCellStyleValue2。无图标带副标题样式2,有主标题和子标题。


    如果以上单元格样式都不满足需求,我们可以考虑自定义。


    二、简单实现

    这里我们实现一个简单的表视图,其中单元格采用默认样式,有图标和主标题。


    有两个地方需要注意:

    1、Scene列表中选择TableView,打开表视图的属性检查器。可以看到Content下有两个选项(Dynamic Prototypes和Static Cells),这两个选项只有在storyboard中才有。Dynamic Prototype用于构建“动态表”,而Static Cells用于构建“静态表”。


    2、如果通过代码实现单元格的创建,则TableView的属性检查器中的Prototype Cells项要设为0;如果用视图文件创建单元格,则这里设为1。


    这里我们在代码中创建单元格,具体代码如下:


    //  ViewController.h
    
    #import <UIKit/UIKit.h>
    
    @interface ViewController : UITableViewController
    
    @property (strong,nonatomic) NSArray *data;
    @end
    


    //  ViewController.m
    
    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        NSString *path=[[NSBundle mainBundle] pathForResource:@"team" ofType:@"plist"];
        self.data=[NSArray arrayWithContentsOfFile:path];
    }
    
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return [self.data count];
    }
    
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {  
        static NSString *cellIdentifier=@"Cell";
        UITableViewCell *tableViewCell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        if(!tableViewCell){
            tableViewCell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        }
        
        //根据indexPath获取相应的数据
        NSUInteger row=[indexPath row];
        NSDictionary  *dict=[self.data objectAtIndex:row];
        
        //设置cell的显示数据
        tableViewCell.textLabel.text=[dict objectForKey:@"name"];
        NSString *imgPath=[dict objectForKey:@"image"];
        imgPath=[imgPath stringByAppendingString:@".png"];
        UIImage *image=[UIImage imageNamed:imgPath];
        tableViewCell.imageView.image=image;
        
        //设置cell的扩展视图的样式
        tableViewCell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
        
        return tableViewCell;
    }
    
    @end
    

    如果利用storyboard中创建单元格,打开Table View Cell的属性检查器。Style选项中有很多可用属性,这些都与表视图描述的单元格的样式一致,Identifier是指可重用单元格的标识符。这样做之后,我们就不需要在代码中实例化单元格了。我们可以直接通过Identifier取得单元格的实例。下面是获取单元格的代码:

        static NSString *cellIdentifier=@"Cell";
        UITableViewCell *tableViewCell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    //    if(!tableViewCell){
    //        tableViewCell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    //    }
        
    


    三、带搜索栏

    IOS提供了搜索栏控件,方便我们查询数据。这里我们在上面代码的基础上再实现搜索功能。


    1、IOS的搜索栏有很多样式:

    (1)基本搜索栏。

    (2)带清除按钮的搜索栏。

    (3)带查询结果按钮的搜索栏。


    显示最近搜索结果,事件响应由UISearchBarDelegate对象中的searchBarResultsListButtonClicked:方法管理。


    (4)带书签按钮的搜索栏。


    显示用户收藏的书签列表,事件响应由UISearchBarDelegate对象中的searchBarBookmarkButtonClicked:方法管理。


    (5)带取消按钮的搜索栏。


    事件响应由UISearchBarDelegate对象中的searchBarCancelButtonClicked:方法管理。


    (6)带Scope的搜索栏。


    事件响应由UISearchBarDelegate或UISearchDisplayDelegate对象管理。

    这里有一点需要注意,默认情况下,Scope Bar初始是显示的。这在iphone上用户体验比较差,我们需要让它初始隐藏,当SearchBar获取 焦点时再显示。为此,我们需要在初始化时调用SearchBar的两个方法:

    [searchBar setShowsScopeBar:NO];

    [searchBar sizeToFit];


    2、相对来说SearchBar是一个比较复杂的控件,它涉及到一些其它类:


    UISearchBarDelegate是UISearchBar的委托协议;UISearchDisplayController用于管理SearchBar并显示搜索结果视图,其事件处理由UISearchDisplayDelegate协议的委托对象来管理。


    3、我们用storyboard来设计我们的视图,这里有个小技巧:

    我们从对象库中拖拽的是Search Bar and Search Display Controller到界面,而不是Search Bar控件。前者的好处在于它可以把UISearchDisplayController也添加到搜索栏,并且将委托和数据源连线完毕。


    下面是我们的实现:

    //  ViewController.h
    
    #import <UIKit/UIKit.h>
    
    @interface ViewController : UITableViewController<UISearchBarDelegate,UISearchDisplayDelegate>
    @property (strong,nonatomic) NSArray *data;
    @property (strong,nonatomic) NSMutableArray *filterData;
    @property (weak, nonatomic) IBOutlet UISearchBar *searchBar;
    
    //根据text和选中的scope过滤数据
    -(void)filterDataWithText:(NSString*)text scope:(NSUInteger) scopeIndex;
    @end


    //  ViewController.m
    
    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        //设置搜索栏的ScopeBar初始隐藏
    	[self.searchBar setShowsScopeBar:NO];
        [self.searchBar sizeToFit];
        
        NSString *path=[[NSBundle mainBundle] pathForResource:@"team" ofType:@"plist"];
        self.data=[NSArray arrayWithContentsOfFile:path];
        //加载所有数据
        [self filterDataWithText:@"" scope:-1];
    }
    
    -(void)filterDataWithText:(NSString *)text scope:(NSUInteger)scopeIndex
    {
        if([text length]==0){
            self.filterData=[NSMutableArray arrayWithArray:self.data];
            return;
        }
        NSPredicate *predicate;
        switch (scopeIndex) {
            case 0:
                //按中文查询
                predicate=[NSPredicate predicateWithFormat:@"SELF.name contains[c] %@",text];
                self.filterData=[NSMutableArray arrayWithArray:[self.data filteredArrayUsingPredicate:predicate]];
                break;
            case 1:
                //按英文查询
                predicate=[NSPredicate predicateWithFormat:@"SELF.image contains[c] %@",text];
                self.filterData=[NSMutableArray arrayWithArray:[self.data filteredArrayUsingPredicate:predicate]];
                break;
                
            default:
                //默认查询所有
                self.filterData=[NSMutableArray arrayWithArray:self.data];
                break;
        }
    }
    
    
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return [self.filterData count];
    }
    
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *cellIdentifier=@"Cell";
        UITableViewCell *tableViewCell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        if(!tableViewCell){
            tableViewCell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
        }
        
        //根据indexPath获取相应的数据
        NSUInteger row=[indexPath row];
        NSDictionary  *dict=[self.filterData objectAtIndex:row];
        
        //设置cell的显示数据
        tableViewCell.textLabel.text=[dict objectForKey:@"name"];
        NSString *imgPath=[dict objectForKey:@"image"];
        tableViewCell.detailTextLabel.text=imgPath;
        imgPath=[imgPath stringByAppendingString:@".png"];
        UIImage *image=[UIImage imageNamed:imgPath];
        tableViewCell.imageView.image=image;
        
        //设置cell的扩展视图的样式
        tableViewCell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
        return tableViewCell;
    }
    
    -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
    {
        [self filterDataWithText:searchString scope:self.searchBar.selectedScopeButtonIndex];
        return YES;
    }
    
    -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
    {
        [self filterDataWithText:self.searchBar.text scope:searchOption];
        return YES;
    }
    
    -(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
    {
        [self filterDataWithText:@"" scope:-1];
    }
    
    @end
    


    在搜索栏中输入查询条件,会触发UISearchBarDelegate委托对象的searchBar:textDidChange:方法和UISearchDisplayDelegate委托对象的searchDisplayController:shouldReloadTableForSearchString:方法,我们只要实现这两者之一即可。这里我们选择实现后者,因为后者的优势在于可以控制表视图数据源是否重新加载。如果实现searchBar:textDidChange:方法,则我们还需要自己调用[tableView reloadData]方法重新加载表视图数据。


    ScopeBar进行切换时,会触发UISearchBarDelegate委托对象的searchBar:selectedScopeButtonIndexDidChange:方法和UISearchDisplayDelegate委托对象的searchDisplayController:shouldReloadTableForSearchScope:方法,我们也只要实现两者之一即可。这里我们同样选择实现后者,因为后者能控制表视图数据源是否重新加载。


    四、分节和索引


    当表中的数据需要归类时,我们会用到节;当表中数据量比较大时,我们还可以建立索引。下面是一个简单的实现。


    1、数据组织



    这里我们在Dictionary中存放Array,每个Array为一个节。


    具体实现:

    //  ViewController.h
    
    #import <UIKit/UIKit.h>
    
    @interface ViewController : UITableViewController
    
    @property (nonatomic,strong) NSDictionary *data;
    @property (nonatomic,strong) NSArray *groupName;
    
    @end


    //  ViewController.m
    
    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    	
        //获取所有数据
        self.data=[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"team_dictionary" ofType:@"plist"]];
        //获取组名
        NSArray *temp=[self.data allKeys];
        //从哈希表中获取的数据是无序的,所以需要排序
        self.groupName=[temp sortedArrayUsingSelector:@selector(compare:)];
       
    }
    
    //定义表中的节数
    -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return [self.groupName count];
    }
    
    //定义节头显示字符串
    -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
    {
        return [self.groupName objectAtIndex:section];
    }
    
    //定义节索引
    -(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
    {
        NSMutableArray *sectionIndexArray=[[NSMutableArray alloc] initWithCapacity:[self.groupName count]];
        for(NSString *temp in self.groupName){
            NSString *indexTitle=[temp substringToIndex:1];
            [sectionIndexArray addObject:indexTitle];
        }
        return sectionIndexArray;
    }
    
    //定义节中的行数
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        NSString *group=[self.groupName objectAtIndex:section];
        NSArray *temp=[self.data objectForKey:group];
        return [temp count];
    }
    
    //定义单元格
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *cellIdentifier=@"cell";
        UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        if(!cell){
            cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
        }
        
        //获取节
        NSUInteger section=[indexPath section];
        NSUInteger row=[indexPath row];
        //获取组名
        NSString *group=[self.groupName objectAtIndex:section];
        //获取组中的数据
        NSArray *temp=[self.data objectForKey:group];
        
        cell.textLabel.text=[temp objectAtIndex:row];
        
        return cell;
    }
    
    
    @end
    


    五、编辑表视图

    TableView的编辑包括:insert、delete和move。

    //  ViewController.m
    
    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        self.tableView.delegate=self;
        self.tableView.dataSource=self;
        self.textField.delegate=self;
        //设置NavigationItem的右按钮以及title
    	self.navigationItem.rightBarButtonItem=self.editButtonItem;
        self.navigationItem.title=@"TableView Editing";
        //初始隐藏TextField
        self.textField.hidden=YES;
        
        self.data=[[NSMutableArray alloc] initWithObjects:@"Houston",@"New York",@"Los Angeles",@"Boston",@"Miami",@"Washington", nil];
    }
    
    /*
     Sets whether the view controller shows an editable view.
     Subclasses that use an edit-done button must override this method to change their view to an editable state if editing is YES and a non-editable state if it is NO. This method should invoke super’s implementation before updating its view.
     */
    -(void)setEditing:(BOOL)editing animated:(BOOL)animated
    {
        [super setEditing:editing animated:YES];
        
        [self.tableView setEditing:editing animated:YES];
        if(editing){
            self.textField.hidden=NO;
        }else{
            self.textField.hidden=YES;
        }
    }
    
    //Asks the delegate for the editing style of a row at a particular location in a table view.
    -(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if(indexPath.row==[self.data count]){
            return UITableViewCellEditingStyleInsert;
        }else{
            return UITableViewCellEditingStyleDelete;
        }
    }
    
    //Asks the data source to commit the insertion or deletion of a specified row in the receiver.
    -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if(editingStyle==UITableViewCellEditingStyleDelete){//delete
            [self.data removeObjectAtIndex:indexPath.row];
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        }else if(editingStyle==UITableViewCellEditingStyleInsert){//insert
            [self.data insertObject:self.textField.text atIndex:[self.data count]];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        }
        [tableView reloadData];
    }
    
    //Asks the data source whether a given row can be moved to another location in the table view.
    -(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if(indexPath.row==[self.data count]){
            return NO;
        }
        return YES;
    }
    
    //Tells the data source to move a row at a specific location in the table view to another location.
    -(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
    {
        NSString *str=[self.data objectAtIndex:sourceIndexPath.row];
        [self.data removeObjectAtIndex:sourceIndexPath.row];
        [self.data insertObject:str atIndex:destinationIndexPath.row];
    }
    
    -(BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if(indexPath.row==[self.data count]){
            return NO;
        }
        return YES;
    }
    
    //Asks the delegate if the text field should process the pressing of the return button.
    -(BOOL)textFieldShouldReturn:(UITextField *)textField
    {
        [textField resignFirstResponder];
        return YES;
    }
    
    //Tells the delegate that editing began for the specified text field.
    //设置tableview内容的offset,以免文本框被键盘挡住
    -(void)textFieldDidBeginEditing:(UITextField *)textField
    {
        UITableViewCell *cell=(UITableViewCell*)[[textField superview] superview];
        [self.tableView setContentOffset:CGPointMake(0.0, cell.frame.origin.y) animated:YES];
    }
    
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return [self.data count]+1;
    }
    
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *cellIdentifier=@"cell";
        UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        if(!cell){
            cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        }
        if([indexPath row]==[self.data count]){
            self.textField.frame=cell.contentView.frame;
            self.textField.text=@"";
            [cell.contentView addSubview:self.textField];
        }else{
            cell.textLabel.text=[self.data objectAtIndex:[indexPath row]];
            cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
        }
           return cell;
    }
    
    @end
    


    setEditing:animated:方法是UIViewController生命周期方法,用于响应视图编辑状态的变化。在我们这里,当点击NavigationItem上的Edit(这个编辑按钮是视图控制器中预定义的按钮,点击后按钮会转换到Done)时便会触发setEditing:animated:方法。在这个方法里,我们触发TableView的编辑方法。 


    tableView:commitEditingStyle:forRowAtIndexPath:方法是TableView的编辑提交方法,我们编辑完成后,点击NavigationItem上的Done便会触发该方法。


    在处理键盘遮挡输入框时,有一点需要注意,


    这里textField的父亲的父亲才是UITableViewCelltextField的父亲是单元格内容视图,并不是UITableViewCell。


    tableView:canMoveRowAtIndexPath:控制cell是否可移动,我们这里除了最后一条(最后一条是添加item选项),都能移动。cell移动时,我们需要在tableView:moveRowAtIndexPath:toIndexPath:方法中做相应的处理。


    下面是运行截图:

                        


    六、自定义UITableViewCell

    iOS提供了几种cell的样式,实际应用中经常需要根据需求自定义cell。自定义的方式有多种,这里介绍两种方式。第一种,新建一个cell类(不带xib),并继承UITableViewCell,然后在类中用代码添加view,这种方式会稍微麻烦一点。第二种,新建一个cell类,附带xib(xib中的根view不是UIView,而是TableViewCell),指定cell的复用id,类继承UITableViewCell,然后在xib中添加view。


    上面提到两种自定义TableViewCell的方式,接下来还有一个复用的问题。第一种方式自定义的TableViewCell在使用的时候与使用系统的cell一样,先调用tableview的dequeueReusableCellWithIdentifier方法获取复用,如果为nil,直接调用alloc创建并初始化一个复用id;第二种方式自定义的TableViewCell在使用的时候稍微有点不一样,首先在viewDidLoad方法中注册Nib:

    UINib *nib = [UINib nibWithNibName:@"MusicPickerViewCell" bundle:nil];
        [self.tableView registerNib:nib forCellReuseIdentifier:cellIdentifier];

    注册之后,在

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    方法中直接获取复用cell即可(不需要判断nil):

    MusicPickerViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];








    展开全文
  • 表视图学习

    千次阅读 2012-03-07 11:37:00
    iPhone中,表视图是iPhone上的一个列,多个行的;用户可以上下滚动来查看更多的数据。从用户的角度来看,创建一个表视图就是完成下面三个功能: 创建表视图为每一行提供文本或图像当用户选择某一行时,做出...

    一、概述

    我们经常需要显示大量数据,比如iPhone内置的通讯录应用。UITableView是UIScrollView的子类。在iPhone中,表视图是iPhone上的一个列,多个行的表;用户可以上下滚动来查看更多的数据。从用户的角度来看,创建一个表视图就是完成下面三个功能:

    • 创建表视图
    • 为每一行提供文本或图像
    • 当用户选择某一行时,做出响应

    一个表视图必须有个一个数据源,这是通过UITableViewDataSource协议来完成的。另外表视图通过UITableViewDelegate协议来实现表视图上的操作。一般而言,你会创建一个UITableViewController的子类,然后在这个子类上实现数据源和表视图的操作。

    1.1 表视图的类型

    表视图的显示风格分为两类:

    1、不分组的显示---UITableViewStylePlain

    2、分组的显示---UITableViewStyleGrouped

    对于分组的结构,每组叫做section,在section的每一行叫做表单元(Table Cell)


    二、UITableView的常用方法


    2.1 初始化一个表视图的方法

    - (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style ;

    2.2 表视图的相关配置方法

    - (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier ;//根据唯一标识,查找可重用表视图单元(UITableViewCell)对象

    - (NSInteger)numberOfRowsInSection:(NSInteger)section ;//返回指定section的表视图行数

    - (NSInteger)numberOfSections ;//返回表视图中的section数目

    2.3 访问section和表单元(UITableViewCell)

    - (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath ;//返回指定NSIndexPath的表单元,NSIndexPath对象代表在一个嵌套数组集合树的特定节点的路径。这条道路被称为索引路径。此处只要将NSIndexPath理解为一个可代表表单元位置的一个路径,根据这个NSIndexPath路径,可用定位到对应的表单元。

    - (NSIndexPath *)indexPathForCell:(UITableViewCell *)cell ;//返回指定表单元的NSIndexPath路径信息

    - (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point;//返回指定了CGPoint的NSIndexPath路径信息

    - (NSArray *)indexPathsForRowsInRect:(CGRect)rect;//返回指定CGRect的NSIndexPath路径信息数组


    - (NSArray *)visibleCells;//返回可见的表单元(UITableViewCell)数组


    - (NSArray *)indexPathsForVisibleRows;//返回可见的表单元的NSIndexPath路径信息数组

    2.4 管理section

    - (NSIndexPath *)indexPathForSelectedRow;//返回选中行的NSIndexPath路径信息


    - (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;//

    - (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated;//

    2.5 插入和删除表单元(UITableViewCell)

    - (void)beginUpdates

    - (void)endUpdates


    - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation


    - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation


    - (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation


    - (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation


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

    2.6 表视图数据的加载

    - (void)reloadData

    - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation


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


    - (void)reloadSectionIndexTitles



    展开全文
  • 视图文件存放 resources/views 目录中。下面是一个简单的视图示例: &lt;!-- resources/views/greeting.blade.php 视图文件 --&gt; &lt;html&gt; &lt;body&gt; &lt;h1&gt;...

    创建视图

    视图包含应用的 HTML 代码,并将应用的控制器逻辑和表现逻辑进行分离。视图文件存放在 resources/views 目录中。下面是一个简单的视图示例:

    <!--  resources/views/greeting.blade.php 视图文件 -->
    
    <html>
        <body>
            <h1>Hello, {{ $name }}</h1>
        </body>
    </html>
    

    可以通过辅助函数 view ,返回这个视图响应:

    Route::get('/', function () {
        return view('greeting', ['name' => 'jack']);
    });
    

    view 方法的第一个参数是 resources/views 目录下相应的视图文件的名称,第二个参数是一个数组,表示传递给视图文件的数据。

    在这个例子中,我们传递了一个 name 变量,在视图中通过使用 Blade 语法将其显示出来。

    当然,视图还可以存放在 resources/views 的子目录中,用“.”号来引用子目录中的视图。

    例如,如果视图存放路径是 resources/views/admin/profile.blade.php,那么我们可以这样引用它:

    return view('admin.profile', $data);
    

    判断视图是否存在

    如果需要判断视图是否存在,可调用 View 门面上的 exists 方法,如果视图存在则返回 true:

    use Illuminate\Support\Facades\View;
    
    if (View::exists('emails.customer')) {
        //
    }
    

    创建第一个有效视图

    调用 View 门面上的 first 方法,可以用于创建给定视图数组中的第一个存在的视图:

    use Illuminate\Support\Facades\View;
    
    return View::first(['custom.admin', 'admin'], $data);
    

    这个功能在应用或扩展包允许视图被自定义或覆盖时很有用。

    传递数据到视图

    可以简单通过数组方式将数据传递到视图:

    return view('greeting', ['name' => 'jack']);
    

    除此之外,还可以通过 with 方法传递独立的数据片段到视图:

    $view = view('greeting')->with('name', 'jack');
    

    在视图间共享数据

    有时候,我们需要在所有视图之间共享数据片段,这时可以使用视图门面的 share 方法,通常,需要在某个服务提供者的 boot 方法中调用 share 方法,你可以将其添加到 AppServiceProvider 或生成独立的服务提供者来存放这段代码逻辑:

    <?php
    
    namespace App\Providers;
    
    use View;
    
    class AppServiceProvider extends ServiceProvider
    {
        /**
         * 启动所有应用服务
         *
         * @return void
         */
        public function boot()
        {
            View::share('key', 'value');
        }
    
        /**
         * 注册服务提供者
         *
         * @return void
         */
        public function register()
        {
            //
        }
    }
    

    视图 Composer

    视图 Composer 是当视图被渲染时的回调函数或类方法。

    如果你有一些数据需要在视图每次渲染时都做绑定,可以使用视图 Composer 将逻辑组织到一个单独的地方。

    在本例中,首先要在某个服务提供者中注册视图 Composer,我们将会使用 View 门面来访问 Illuminate\Contracts\View\Factory 的底层实现,记住,Laravel 不会包含默认的视图 Composer 目录,我们可以按照自己的喜好组织其路径,例如可以创建一个 app/Http/ViewComposers 目录:

    <?php
    
    namespace App\Providers;
    
    use Illuminate\Support\Facades\View;
    use Illuminate\Support\ServiceProvider;
    
    class ComposerServiceProvider extends ServiceProvider
    {
        /**
         * 在容器中注册绑定.
         *
         * @return void
         */
        public function boot()
        {
            // 使用基于类方法的 composers...
            View::composer(
                'profile', 'App\Http\ViewComposers\ProfileComposer'
            );
    
            // 使用基于回调函数的 composers...
            View::composer('dashboard', function ($view) {});
        }
    
        /**
         * 注册服务提供者.
         *
         * @return void
         */
        public function register()
        {
            //
        }
    }
    

    注:如果创建一个新的服务提供者来包含视图 Composer 注册,需要添加该服务提供者到配置文件 config/app.php 的 providers 数组中。

    现在我们已经注册了视图 Composer,每次 profile 视图被渲染时都会执行 ProfileComposer@compose 方法,接下来我们来定义该 Composer 类:

    <?php
    
    namespace App\Http\ViewComposers;
    
    use Illuminate\View\View;
    use Illuminate\Repositories\UserRepository;
    
    class ProfileComposer
    {
        /**
         * 用户仓库实现.
         *
         * @var UserRepository
         */
        protected $users;
    
        /**
         * 创建一个新的属性composer.
         *
         * @param UserRepository $users
         * @return void
         */
        public function __construct(UserRepository $users)
        {
            // 依赖注入通过服务容器自动解析...
            $this->users = $users;
        }
    
        /**
         * 绑定数据到视图.
         *
         * @param View $view
         * @return void
         */
        public function compose(View $view)
        {
            $view->with('count', $this->users->count());
        }
    }
    

    视图被渲染前,Composer 类的 compose 方法被调用,同时 Illuminate\View\View 实例被注入该方法,从而可以使用其 with 方法来绑定数据到视图。

    注:所有视图 Composer 都通过服务容器被解析,所以你可以在 Composer 类的构造函数中声明任何你需要的依赖。

    添加 Composer 到多个视图

    你可以传递视图数组作为 composer 方法的第一个参数来一次性将视图 Composer 添加到多个视图:

    View::composer(
        ['profile', 'dashboard'],
        'App\Http\ViewComposers\MyViewComposer'
    );
    

    composer 方法还支持 * 通配符,允许将一个 Composer 添加到所有视图:

    View::composer('*', function ($view) {
        //
    });
    

    视图创建器

    视图创建器和视图 Composer 非常类似,不同之处在于前者在视图实例化之后立即失效而不是等到视图即将渲染。

    使用 View 门面的 creator 方法即可注册一个视图创建器:

    View::creator('profile', 'App\Http\ViewCreators\ProfileCreator');
    展开全文
  • 数据驱动视图简单实现

    千次阅读 2016-05-30 11:38:12
    数据驱动视图简单实现前端框架日新月异,Angularjs的MVVM模式风靡全球,React的MV模式也被大家捧得火热。我不知道有多少人使用Vue.js,这也不重要,框架对于前端从业人员而言绝对是提升效率的利器,各种框架/各种...

    数据驱动视图简单实现

    前端框架日新月异,Angularjs的MVVM模式风靡全球,React的MV模式也被大家捧得火热。我不知道有多少人在使用Vue.js,这也不重要,框架对于前端从业人员而言绝对是提升效率的利器,各种框架/各种库帮我们解决了大量的繁琐工作/兼容性工作。

    最近在一个移动端项目中想去使用Vue.js,那必然会跟跟当下其他比较火热的框架进行一个比较,具体的比较过程大家也可以从 是否能完成需求/库文件的大小/社区活跃度/稳定性/性能/团队技术特点 等等方面去观测,这里不再去赘述。

    今天的题目是“数据驱动视图简单实现”,我们知道Angularjs号称数据双向绑定,也就是说数据模型中数据发生改变时相应的视图也会跟随发生改变,而Vuejs也是如此,并且称自己不用像Angularjs那样做数据脏检查。那我们先看看数据脏检查是什么意思

    脏检查 即一种不关心你如何以及何时改变的数据, 只关心在特定的检查阶段数据是否改变的数据监听技术.

    那既然Vuejs不使用这种轮巡式的检测方式,它使用的是什么方式呢?没错,就是事件触发式。它不会去劳心费力地做一些无用功,当数据发生变化时,直接给Vuejs打个电话,让它去看看是否需要进行下一步处理即可。

    为了更好地去理解这种机制,我们取了一个很唬人的标题,当然唬人不是骗人,下面我们就来简单实现一个demo,当数据变动时去自动更新视图。

    首先,我们在页面上放置一个简单的视图

    <h1>你好:<span id="target">世界</span></h1>

    接下来,我们来设置数据模型并且将数据模型跟视图进行驱动绑定

    document.addEventListener('DOMContentLoaded',function () {
        //视图
        var view = document.getElementById('target');
    
        //数据
        var data = {
            name : '世界'
        };
    
        //视图和数据进行关联
        Object.defineProperty(data,'name',{
            get : function () {
                return view.innerHTML;
            },
            set : function (val) {
                view.innerHTML = val;
            }
        });
    
        //修改测试
        var timer = setTimeout(function () {
            //数据发生改变
            data.name = 'chaoluo';
        },3000);
    });

    这里使用Object.defineProperty来对指定数据对象值变动进行监听,并且在对象值变化时实时去执行相应视图的更新,当然这里是没有任何优化且仅仅是用于简单演示所用,你可以在数据值被设置时先检测新的值是否改变,如值未改变则视图可以保持原样。

    再来看看该方法的支持性 http://kangax.github.io/compat-table/es5/#test-Object.defineProperty 总体而言在移动端支持性还是很不错的。

    本文简单介绍了如何通过Object.defineProperty进行数据与视图的绑定,也是告诉自己当我们在使用一些框架时要更加清晰地去了解它的实现原理和适用场景,不要只停留在会用的层面。小菜的日常,望共勉。

    展开全文
  • Android数据驱动视图更新

    千次阅读 2011-03-20 12:28:00
    再加上数据类型的繁杂,所以不太适合每个类中添加对数据更新的方法去处理视图的展现。更简单而又方便的方式,就是使用数据监听器。这个有点像JavaBean中的property change的数据监听方式。当数据发生改变,外面对...
  • 少数情况,可以直接在表中修改,但这是不被推荐的作法。ABAP开发的过程中有时需要在数据字典中自定义数据表,而自定义数据表,也需要进行数据维护。除了自己定义报表程序来进行维护外,SAP还给我们提供了一种...
  • Oracle之数据字典、空间、的操作、视图
  • 当你用vue加axios,发请求,请求后端接口更新数据,实现视图同步更新,这个操作ie本地,谷歌以及360等浏览器是没有问题的,但是鄙人发现,一旦你把项目打包后,发到服务器上ie上访问,就会发现,你用axios发请求,更新页面...
  • Android ListView无数据视图

    千次阅读 2015-12-08 10:13:24
    正确使用ListView中的setEmptyView方法来设置Adapter为空或者无数据时候的自定义视图
  • Oralce静态数据字典目录,为采集前获取上游Oralce系统结构做准备
  • 一个Lotus Notes应用中常常有各种配置数据保存专门的视图中。由一个关键字和一个值组成的键—值对,是最常见的形式之一。程序中使用到它们的时候,可以很方便地通过NotesView. GetDocumentByKey之类的方法或者...
  • Spring MVC 传递模型数据视图中的方法总结一般来说,有如下的4种方法来传递模型数据视图中1、ModelAndView要求:处理方法返回值类型为 ModelAndView。方法体中我们通过该ModelAndView对象添加模型数据。2、...
  • select语句的数据源:视图

    千次阅读 2020-01-14 20:27:58
    甚至某些特定条件,可以通过视图对表进行更新操作。 创建视图 视图中保存的仅仅是一条select语句,视图中的源数据都来自于数据库,数据库称为基表,视图称为虚。基表的数据发生变化时,虚数据也会随...
  • 1. 向视图插入数据的时候分两种情况1.1 对于简单视图视图建立一张上),跟一样直接插入数据就好;1.2 对于复杂视图视图建立时包含多关联、分组、聚合函数),这个时候不能直接插入数据,应该创建一个 ...
  • SSAS_创建数据源和数据视图

    千次阅读 2012-05-30 15:43:35
    启动VS2010或SQL Server Data Tools,如图所示,新建一个Analysis Services 多维和数据挖掘项目 定义新的数据源 1 如图,右击数据源并选择“新建数据源” 2 单击“一步”后,在下图点击“新建...
  • SQL 数据库里是否可以通过视图更改中的数据? 2011-09-14 11:23呱呱的蛙 分类:数据库DB | 浏览 6809 次 书上说"视图被看成是虚拟,它并不代表任何的物理数据,只是用来查看数据的视窗而已。数据库中只...
  • 利用excel的数据视图功能对数据求和

    千次阅读 2015-01-16 20:44:22
    对一个月值数据求和时,比较老土的方法就是插入一行求和了,这是小学生使用的...下面介绍利用excel的数据视图功能求和方法: 首先,选择“插入”—->“数据透视”,然后选择你的数据区域,如图所示: 其次,拖
  • 数据库视图的区别

    千次阅读 2016-04-22 14:23:46
    区别: 1、视图是已经编译好的sql语句。而不是 2、视图没有实际的物理记录。而有。...6、视图是查看数据表的一种方法,可以查询数据表中某些字段构成的数据,只是一些SQL语句的集合。从安
  • 我们开发过程中会碰到数据更新,但是视图并未改变的情况,情况如下: 1.数组数据改变时,使用某些方法操作数组,数据变了,但是视图并没改变。(页面没有监测到数据改变) 解决办法: 使用下面这些方法操作数组,...
  • 创建两个源,只有两个字段,通过id关联: CREATE TABLE default.test0 ( `id` String, `name` String ) ENGINE = MergeTree PARTITION BY id ORDER BY id SETTINGS index_granularity = 8192 CREATE TABLE ...
  • oracle数据库对象--视图

    千次阅读 2018-01-23 17:08:50
    oracle数据库对象–和...是作为oracle数据库存储数据的一种数据结构,就相当于我们java中用集合list,或者数组存储我们的数据一样,是一种二维结构,有行 有列,我们把相同类型的数据归为一列,比如每个人都
  • 用过echarts的同胞们都知道,自带的数据视图是怎样的。真正做项目时,肯定需要...下面以表格样式的数据视图为例,来实现一个自己的数据视图。 ECharts table { cellspacing:0 ; *border-collap
  • 实际应用中,会遇到某个用户需要查询另一个用户表数据视图的情况,然而没有授权时,会提示无权限操作的错误。那就需要通过授权处理后,再能进行查询操作,下面我们来看看是怎么处理的。一、系统权限说明...
  • 视图

    千次阅读 2013-02-26 17:08:20
     ORACLE中,称视图为逻辑。逻辑二字还是说明了视图不是真正的。因为视图内根本就没有数据视图的全部家当,也就是你创建视图时的SELECT语句。 二、创建视图: 1、创建视图的主法是:  CREATE ...
  • MySQL视图

    万次阅读 多人点赞 2019-08-03 16:44:21
    1、视图概述 视图是由数据库中的一个或多个导出的虚拟,是一种虚拟存在的,方便用户对数据的操作。...这些数据存放原来的中。使用视图查询数据时,数据库系统会从原来的中取出对应的数据。...
  • 本文对物料主数据中质量视图的各字段进行介绍
  • oracle复制、临时视图

    千次阅读 2014-12-10 11:43:49
    创建一个new_table和old_table结构一样(没有old_table的记录) create table new_table as select * from old_table where 1=0;   创建一个new_table和old_table结构一样(有old_table的记录) ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 371,616
精华内容 148,646
关键字:

下面是在数据表视图的方式下