【iOS】标签视图与分组静态表布局使用、利用通知和全局变量传值

本文和《【Android】底部标签页,Tabhost置底》(点击打开链接)是姊妹篇,标签视图Tabbar在各大apps中实在是常见。不过对比起安卓,iOS的标签视图的设置与使用,似乎比较繁琐。而在《【iOS】表视图》(点击打开链接)我只完成了iOS中最简单的一种表视图,其实,在iOS,分组静态表的布局也很常见。下面举一个例子来说明iOS中标签视图Tab Bar View的使用与分组静态表使用。


如上图,我定义3个标签页,在第一个标签页中还使用了分组静态表布局去刻画登录页面。在登录页面输入完表单,则能跳转到第二个标签页中显示结果。第三个标签页则是简单地显示本程序的信息。具体制作步骤如下:

一、场景布局

1、在新建项目的时候,直接选择Tabbed Application,而不是往常的Single View Application可以得到一个成熟的标签视图模板的项目,我们在此之前进行修改即可。其实这两种新建方式没有区别,即使以Single View Application也可以自己在右下角拖出Tab bar Controller。


2、如图所示,将自带的First View Controller的视图和代码文件一并删除,用Table View Controller取代(也可以新建一个View Controller再拖个Table View进去)。并且新建一个View Controller,选中Tab Bar Controller按着Ctrl,将两者建立关联。


3、点选各个Tab Bar Item,修改其Title和Image,Title分别为“登录页面”、“输入结果”、“关于”,Image分别为“first”、"second"、"second"。


点选Tab Bar Controller,对于各个标签页选项双击之后,可以长按拖拽,从而控制各个标签页的顺序。


4、对于刚刚新建的Table View Controller“登录页面”中的Table View,修改其样式,Content改成Static Cells,Sections段数设置为3,然后Style设置为Grouped


旗下的3个Table View Section,第1个是有Header的,且Rows行数为2,其余2个行数为1。


在第一段中拖入两个Text Field,设置好字体Fonts为18号字和替换文本Placeholder,同时选择为无边框。


然后先在下面两个表格单元格拖入Label,改为“登录”和“关于”居中摆放,再打开这个单元格的Disclosure Indicator,不然居中的位置会有所偏移的。

同时设置这两个单元格的标签Tag分别为111和222,用于一会儿程序点击使用。


5、其余两个页面分别拖入Label摆到合适的位置,并调整好这个Label的大小和所容纳的行数。



至此,布局完毕,开始写代码。

二、代码编写

1、首先,和《【iOS】View跳转和传值》(点击打开链接)一样,为新建的Table View Controller新建Objective-C Class代码文件ViewController.h与ViewController.m。指明这个ViewController是继承于UITableViewController而不是UIViewController的!


同时在MainStoryboard.storyboard中指明,这个我们新建的Table View Controller“登录页面”的控制Class就是我们新建的这个ViewController文件。


2、然后和 《【iOS】点击按钮Button,更变标签文字Label的颜色》(点击打开链接)中一样,对“登录页面”中的两个TextField,“输入结果”页面中的Label进行组件的注册。并且由于我们涉及到跨页面的传值,所以在SecondViewController.h定义两个全局变量,并且在ViewController.h要引入SecondViewController.h这个头文件。所以ViewController.h如下所示:

//
//  ViewController.h
//  tab
//
//  Created by pc on 17-7-19.
//  Copyright (c) 2017年 pc. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "SecondViewController.h"

@interface ViewController : UITableViewController

@property (weak, nonatomic) IBOutlet UITextField *textfield1;
@property (weak, nonatomic) IBOutlet UITextField *textfield2;

@end

SecondViewController.h如下所示:

//
//  SecondViewController.h
//  tab
//
//  Created by pc on 17-7-19.
//  Copyright (c) 2017年 pc. All rights reserved.
//

#import <UIKit/UIKit.h>

/*可以被其他变量操控的全局变量*/
NSString *username;
NSString *password;

@interface SecondViewController : UIViewController

@property (weak, nonatomic) IBOutlet UILabel *label1;//承载输入结果的label1

@end
3、ViewController.m的代码如下所示,这里由于是一个Table View Controller视图,默认在这个视图是都被一个Table View填充了,所以无法用《【iOS】基本控件:文本输入框、开关、分段控件、滑块与输入键盘隐藏的问题》( 点击打开链接)和处理View视图一样,直接点击空白处来关闭键盘,只能通过用户开始拖拽界面的方式,来隐藏输入键盘了。

//
//  ViewController.m
//  tab
//
//  Created by pc on 17-7-19.
//  Copyright (c) 2017年 pc. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

//允许用户点击拖拽关闭键盘
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    [self.view endEditing:YES];
    
}
//允许用户通过点击return键关闭键盘
-(BOOL)textFieldShouldReturn:(UITextField *) textField{
    [textField resignFirstResponder];
    return YES;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath//单元格被点击之后所触发的函数
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];//拿到被点击单元格的指针
    if(cell.tag==111){//如果点击的单元格的tag为111,也就是“登陆”
        /*通知方式传递数值,用于每次切换标签页都能修改label1的值*/
        NSDictionary *dictionary =[[NSDictionary alloc]initWithObjectsAndKeys:self.textfield1.text,@"textfield1",self.textfield2.text,@"textfield2", nil];//创建一个数据字典dictionary,里面存放我们要压入通知,传递给通知中心的变量
        NSNotification *notification =[NSNotification notificationWithName:@"message_handler" object:nil userInfo:dictionary];//指明数据字典dictionary的送达地为通知中心message_handler
        [[NSNotificationCenter defaultCenter] postNotification:notification];//发送通知
        /*全局变量传递数值*/
        username=self.textfield1.text;
        password=self.textfield2.text;
        
        [self.tabBarController setSelectedIndex:1];//从这个第0个标签页,切换到第1个标签页
    }
    else if(cell.tag==222){
        [self.tabBarController setSelectedIndex:2];//切换到第2个标签页
    }
}

@end

标签页切换其实就一行代码:self.tabBarController setSelectedIndex:X];表示切换到第X个标签页,大家可以看到无须传值,切换到第2个“关于”标签页是一个很简单的事情。

至于标签页传值的问题,我们看完SecondViewController.m的代码再说:

//
//  SecondViewController.m
//  tab
//
//  Created by pc on 17-7-19.
//  Copyright (c) 2017年 pc. All rights reserved.
//



#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    /*全局变量传递数值的方式*/
    if(username&&password){
        self.label1.text=[[NSString alloc]initWithFormat:@"传递过来的信息\n登陆名:%@,密码:%@",username,password];
    }
    /*通知传递数值的方式*/
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(message_handler:) name:@"message_handler" object:nil];//初始化通知中心,指明通知处理函数为message_handler
}
//通知的处理函数,也就是受到通知会做什么事情。
- (void)message_handler:(NSNotification *)notification{
    self.label1.text=[[NSString alloc]initWithFormat:@"传递过来的信息\n登陆名:%@,密码:%@",notification.userInfo[@"textfield1"],notification.userInfo[@"textfield2"]];
}

@end
这里我似乎是多此一举,用两种方式来传递数值,其实不然,因为在这个“输入结果”的视图中,viewDidLoad这个初始化函数,只会在第一次切换到这个标签页之中触发一次,同时以后不再触发,而第一次进入这个页面的话,通知中心才刚刚被初始化,只有以后通过点击“登录页面”的“登录”按钮,才会每次发送一次信息,给消息处理函数message_handler进行处理。在现实中就分两种情况了,(1)用户直接点击“输入结果”页面,才输入信息登录(2)用户输入完信息登录,直接跳到这个标签页。所以要两种传值方式配合,来完成标签页的传值了。

最后说句题外话,这里的iOS消息传递,其实和《【Android】进度条与线程之间的消息处理》(点击打开链接)中利用消息处理的机制来更新组件,有异曲同工之妙。由于iOS标签页的特殊性,我们无法用《【iOS】View跳转和传值》(点击打开链接)中提到的设置属性的方式来传值了~只能做得这么复杂,我也不想的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值