New StoryBoard in iOS9

发布于:2023-03-12 ⋅ 阅读:(81) ⋅ 点赞:(0)

Storyboards在iOS5就已经添加进来了,被开发者们指点了很多年了,如今他也添加了不少的新的功能。Apple现在是鼓励开发者们使用Storyboards来进行页面的开发的,虽然一直还没有完全那些代码写界面的所接受,但是我觉的这将会是以趋势。

原文链接

再开始之前我觉的你可以先去看下这个视频,这是WWDC2015上关于这部分的介绍。这个视屏字幕是翻译成中文的。视频链接

项目初始地址

Storyboard references

如果你已经看过了上边的那个视频,那么你就会知道Storyboard references这个功能有多么棒。

如果你曾经使用 interface builder 创建过一个复杂、界面非常多的应用,你就会明白最后那些Storyboards 文件变的有多大。他会迅速变的无法管理,阻碍你的进度。自从引入 Storyboard 以来,其实是可以把你的应用的不同模块切开到不同的 Storyboard 中的。在过去,这要手动创建多个 Storyboard 文件,并且要写大量的代码。

为了解决这个问题,在 iOS 9 中苹果介绍了 Storyboard References 这个概念。Storyboard References 允许你从 segue 中引用其他 storyboard 中的 viewController。这意味中你可以保持不同功能模块化,同时 Storyboard 的体积变小并易与管理。不仅容易理解了,和团队一起工作时,合并(工作成果)也变的简单了。

Creating your first storyboard reference

打开我们的项目来创建你的第一个storyboard reference,打开Main.storyboard,选择除了tar bar controller之外的所有视图控制器,然后选择Editor\Refactor to storyboard And 输入Checklists.storyboard 作为这个新的故事版的名称。然后点击存储。

你的新的故事版的样子应该是下边这个样子:

而你的原来的故事版将会是这个样子:

接下来我们在Main.storyboard中选择名字是ChecklistsNavigationControllerreferences在属性面板中删除Referenced ID里的值。

修改之后就回变成下边的样子

打开你的Checklists.storyboard 选择Checklists Navigation Controller在属性面板中选中Is Initial View Controller

我们也可以从Object Library中拖进来一个Storyboard reference控件。

Views in the scene dock

在我们项目中的ChecklistDetail.storyboard中选择Checklist Detail View Controller,从Object Library拖出一个View放在secne dock

你会不会吓一跳。可是你会想,额。我们怎么去使用它呢。我们先来一个简单的使用吧。

选中这个View在属性栏中将背景颜色设置为#FFFAE8

ChecklistItemCell拖出Ctrl-drag到你的这个view中,选择selectBackgroundView

然后你运行你的项目,点击任何cell

Conditional views using the scene dock

我们经常会想创建一个只需要在特定条件下才显示的view。我们可以使用scene dock来方便的实现这一点。

我们仍然在ChecklistDetail.storyboard中拖进来一个 Viewscene dock中,将刚才的那个设置过背景颜色的View的宽高设置为321;128

在这个新的View中拖进来一个labeltext View。设置label的文字是notes,颜色设置为#BB991E

textView的属性中editableselectable不要勾选。就像下边的这个样子:

接下来我们在代码中将新添加进来的view和这个textView做一个关联。

ChecklistDetailViewController.swift中添加两个方法,一个是用来显示新添加进来的View另外一个自然是移除了。

   func addNotesViewToCell(cell:ChecklistItemTableViewCell){
        notesVIew.heightAnchor.constraintEqualToConstant(notesViewHeight).active = true
        notesVIew.clipsToBounds = true
        
        cell.stackView.addArrangedSubview(notesVIew)
    }
    
    func removeNotesView(){
        if let stackview = notesVIew.superview as? UIStackView{
            stackview.removeArrangedSubview(notesVIew)
            notesVIew.removeFromSuperview()
        }
    }

上边的方法可以确保自动布局定义笔记的高度,然后将其添加到对应的单元格中,他还设置了clipsToBounds为true,以防止文本视图从cell中外溢。

接下来就是使用这两个方法了。在ChecklistDetailViewController.swift中完成下边的方法。

 override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        //1
        guard let cell = tableView.cellForRowAtIndexPath(indexPath) as? ChecklistItemTableViewCell else {return}
        //2调用这个方法来以动画更改单元格的高度
        tableView.beginUpdates()
        //3 如果cell的stackView已经包含了它则删除,如果没有则添加
        if cell.stackView.arrangedSubviews.contains(notesVIew){
            removeNotesView()
        }else{
            addNotesViewToCell(cell)
            
            notesTextView.text = checklist.items[indexPath.row].notes
        }
        //5 最后来条用这个方法来提交更改。
        tableView.endUpdates()
        
    }

接下里运行你的程序就会看到下边的效果。

Using multiple bar buttons

在故事版中给Checklist Detail View Controller拖进来两个bar button item放在navigation bar 的右边,给其中一个的图片设置为AddButtonicon

addbutton拖拽出一天线到add item navigation controller从弹出来的菜单中选择present modally。这样的话我们点击add button则会弹出一个新的界面。

接下来我们需要给我们弹出的界面添加消失的功能。

checklistDetail.storyboard中选择add item view controller,从Cancel按钮中拖出一条线到Exit,从弹出的菜单中选择cancelToChecklistDetailViewController

同样的方法给save按钮添加saveToChecklistDetailViewController

运行一下程序来看下效果吧。

我们在最后的最后来添加删除cell的功能。

ChecklistDetailViewController.swift中完成下边的方法。

viewDidLoad中添加

navigationItem.rightBarButtonItems![1] = editButtonItem()

重写下边的方法

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete{
            removeNotesView()
            checklist.items.removeAtIndex(indexPath.row)
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        }
    }

本文含有隐藏内容,请 开通VIP 后查看