6 控制器多态性 导航控制器 选项卡控制器

本文探讨了在Project Matchismo中如何利用控制器的多态性来提高代码复用性和整洁度,通过创建一个专门针对扑克牌的视图控制器子类,使基类更加通用,并介绍了如何在Storyboard中配置并链接这些控制器。

主要内容:

1 在project Matchismo中控制器的多态性,如何在控制器中继承,可以生成控制器的子类

2 如何添加多个MVC


生成一个卡牌游戏视图控制器的子类,只针对扑克牌,让当前类显得整洁和通用

通过把createDeck修改成return nil后,我们把卡牌游戏视图控制器抽象化

(Deck *)createDeck
{
    return nil;
}

抽象意味着这个类不能被实例使用,只能作为具体类的父类,我们如果想对其操作,需要创建一个具体子类

- (Deck *)createDeck
{
    return [[PlayingCardDeck alloc]init];
}


所有抽象方法都应该是公有的,否则具体子类会无法知道

指定初始化方法,因为我们现在都从storyboard开始执行,我们会用viewDidLoad awakeFromNib

如何让storyboard和类联系起来?

顶级视图,正确选中后周边会有蓝色框,按住control 和 shift 单击,会显示鼠标指针下的所有元素


选择controller,转到标识符检查器


如何在MVC间进行切换?


点击返回按钮时,右边的MVC离开屏幕,会在堆中被释放,所以这些MVC需要知道如何变为活动状态,准备出现在屏幕上,完成功能,完成之后,保存进度

如果某些数据需要继续使用,你就要对它进行保存,可以通过反向通信,通过将你压入的MVC发送消息来实现,但是必须借助不可视结构化通信来实现

 segue是用来从一个MVC跳入另一个MVC

操作:

1 从对象面板中拖入一个UIViewController

2 然后转到标识符检查器,将类型设置成之前通过新建文件创建的类

3 向左边的MVC中拖入一个Button

4 control Button指向右边的MVC,创建push segue

5 命名segue,通常选择具有描述性的标识符

6 Editor中压入UINavigationController

UINavigationController

组成:顶部有浅灰色一栏,导航栏,它始终在屏幕上,但不同mvc出现时,它会产生略微变化

title   UIBarButtonItem

导航控制器如果想要确定显示哪个按钮,需要向嵌入的视图请求一个对象,叫作navigationItem,所有的UIViewController都有这个属性

返回的对象中包括rightBarButtonItems

UIBarButtonItems,只有在嵌入导航控制器需要时才会显示底下那一栏,对应的另一属性时toolBarItems

DEMO:

1 创建UIViewController的子类TextStatsViewController

我们需要先设置一个公有API,然后才考虑如何组织我们的元素

@interface textStatsViewController : UIViewController
@property (strong, nonatomic)NSAttributedString *textToAnalyze;
@end

假想我们是这个MVC,有人设置了这个textToAnalyze,我要如何反应?

我要设置变量和更新我的UI,只要有人设置了textToAnalyze,我就要更新UI,保持UI和模型的同步

- (void)setTextToAnalyze:(NSAttributedString *)textToAnalyze
{
    _textToAnalyze = textToAnalyze;
    if(self.view.window) [self updateUI];//如果是在当前视图所在窗口,view指的是MVC的顶级视图,如果是nil,说明不在屏幕上
}


还有一个时间节点需要考虑,如果我不在屏幕上,textToAnalyze被设置了怎么办,也可能是在输出口没设置好的时候,我希望视图将要出现时同步数据

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self updateUI];
}

创建两个标签,然后连接到控制器

@property (weak, nonatomic) IBOutlet UILabel *colorfulCharactersLabel;
@property (weak, nonatomic) IBOutlet UILabel *outlinedCharactersLabel;

如何分析属性化字符串?

- (NSAttributedString *)characterWithAttribute:(NSString *)attributeName
{
    NSMutableAttributedString *characters = [[NSMutableAttributedString alloc]init];
    int index = 0;
    while (index < [self.textToAnalyze length]) {
        NSRange range;
        id value =[self.textToAnalyze attribute:attributeName atIndex:index effectiveRange:&range];
        if(value){
            [characters appendAttributedString:[self.textToAnalyze attributedSubstringFromRange:range]];
            index = range.location + range.length;
        }
        else{
            index++;
        }
    }
    return characters;
    
}


update UI

- (void)updateUI
{
    self.colorfulCharactersLabel.text = [NSString stringWithFormat:@"%d colorful characters", [[self characterWithAttribute:NSForegroundColorAttributeName] length]];
    self.outlinedCharactersLabel.text = [NSString stringWithFormat:@"%d outlined characters", [[self characterWithAttribute:NSStrokeWidthAttributeName] length]];

}


2 添加prepareForSegue方法

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"abc"]){
        if([segue.destinationViewController isKindOfClass:[textStatsViewController class]]){
            textStatsViewController *tsvc = (textStatsViewController*)segue.destinationViewController;
            tsvc.textToAnalyze = self.body.textStorage;
        }
    }
}











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值