iOS Programming UINavigationController

the Settings application has multiple related screens of information: a list of settings (like Sounds), a detailed page for each setting, and a selection page for each detail. This type of interface is called a drill-down interface.

setting application 有许多屏幕相关的信息:一系列的settings,每个setting的一个detail page和为每个detail page 的一个selection page。

这种类型的interface成为drill-down interface.

1 UINavigationController

When your application presents multiple screens of information, a UINavigationController maintains a stack of those screens.

当你的应用要展现多个屏幕信息的时候,UINavigationController保持了一个栈的这个样的屏幕。

Each screen is the view of a UIViewController,

每个屏幕就是一个UIViewController的view。

and the stack is an array of view controllers.

这个stack 就是一列view controller。

When a UIViewController is on top of the stack, its view is visible.

当一个UIViewController 在stack 的顶部,那么它的view 是可见的。

When you initialize an instance of UINavigationController, you give it one UIViewController. This UIViewController is the navigation controller's root view controller.

当你初始化UINavigationController,你就给它了一个UIViewController。这个UIViewController是navigationcontroller 的root view controller .

The root view controller is always on the bottom of the stack. More view controllers can be pushed on top of the UINavigationController's stack while the application is running.

The root view controller 总是在stack 的底部。当application运行的时候,更多地更控制被放在了UINavigationController's stack 的顶部。

When a UIViewController is pushed onto the stack, its view slides onto the screen from the right. When the stack is popped, the top view controller is removed from the stack and its view slides off to the right, exposing the view of next view controller on the stack.

当UIViewController被放进stack,它的view 将从屏幕的右边滑进来。当stack  is popped,the top view controller  将被移除,并且它的view 也将从右边滑出,展现出在stack 上的下一个view controller

The root view controller is the first object in the array. As more view controllers are pushed onto the stack, they are added to the end of this array.

The root view controller 是列的第一个对象。当更多地 view controllers被推送到stack 上,他们被添加到数组的最后。

Thus, the last view controller in the array is the top of the stack. UINavigationController's topViewController property keeps a pointer to the top of the stack.

因此数组的the last view controller  是stack 的顶部。UINavigationController's的topViewController property 有一个指针指向stack 的顶部。

UINavigationController is a subclass of UIViewController, so it has a view of its own. Its view always has two subviews: a UINavigationBar and the view of topViewController

UINavigationController是UIViewController的一个子类,因此它有一个他自己的view。它的view总是有两个subviews:一个是UINavigationBar,另一个是topViewController的view。

You can set a navigation controller as the rootViewController of the window to make its view a subview of the window.

你可以设置navigation controller为window的rootViewController,从而使它的view 成为window的subview。

1.1

The only requirements for using a UINavigationController are that you give it a root view controller and add its view to the window.

你想用UINavigationController,你就把它给rootviewcontroller ,并把它的view 添加到window。

UINavigationController *navigationController=[[UINavigationController alloc] initWithRootViewController:itemViewController];

self.window.rootViewController=navigationController;

2 An Additional UIViewController

Create a new Objective-C class (File → New → File...). Name this class BNRDetailViewController and choose UIViewController as the superclass. Check the With XIB for user interface box

3 Navigating with UINavigationController

3.1 Pushing view controllers

The viewControllers array of a navigation controller is dynamic – you start with a root view controller and push view controllers depending on user input.

The viewControllers array of a navigation controller是动态的 -你开始一个root view controller 并且根据你的输入,推送view Controller 。

Therefore, some object other than the navigation controller needs to create the instance of BNRDetailViewController and be responsible for adding it to the stack.

因此,除了navigation controller 之外还有其他的对象需要创建BNRDetailViewController的实例,并负责把它添加到stack 中。

This object must meet two requirements: it needs to know when to push a BNRDetailViewController onto the stack, and it needs a pointer to the navigation controller to send the navigation controller messages, namely, pushViewController:animated:.

这个对象需要满足两个要求(1) 它需要知道什么时候把BNRDetailViewController放入到stack 上。(2) 它需要指针指向 navigation controller 发送navigation controller信息,名字为pushViewController:animated。

BNRItemsViewController fills both requirements. First, it knows when a row is tapped in a table view because, as the table view's delegate, it receives the message tableView:didSelectRowAtIndexPath: when this event occurs.

BNRItemsViewController满足以上两条(1) 它知道什么时候在table view中的一行被选中,作为table view的委托,当这个时间发生时,它接受tableView:didSelectRowAtIndexPath的消息。

Second, any view controller in a navigation controller's stack can get a pointer to that navigation controller by sending itself the message navigationController.As the root view controller, BNRItemsViewController is always in the navigation controller's stack and thus can always access it.

(2)任何 在navigation controller's stack中view controller 都有一个指向navigation controller的指针,通过向自己发送navigationController消息。

Therefore, BNRItemsViewController will be responsible for creating the instance of BNRDetailViewController and adding it to the stack.

#import "BNRDetailViewController.h"

- (void)tableView:(UITableView *)tableView

didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{

BNRDetailViewController *detailViewController =[[BNRDetailViewController alloc] init];

// Push it onto the top of the navigation controller's stack

[self.navigationController pushViewController:detailViewController]

}

Since the UINavigationController's stack is an array, it will take ownership of any view controller added to it.

因为UINavigationController's stack 是一个数组,它可以拥有任意类型的view Controller。

Thus, the BNRDetailViewController is owned only by the UINavigationController after tableView:didSelectRowAtIndexPath: finishes. When the stack is popped, the BNRDetailViewController is destroyed. The next time a row is tapped, a new instance of BNRDetailViewController is created.

因此BNRDetailViewController仅仅当tableView:didSelectRowAtIndexPath完成后才被UINavigationController拥有。当这个stack 被poped ,BNRDetailViewController将被销毁。

3.2 Passing data between view controllers

To fill these fields, you need a way to pass the selected BNRItem from the BNRItemsViewController to the BNRDetailViewController.

为了填充空白,你需要用一种方式把选中的从BNRItemsViewController 得到的BNRItem 传递给BNRDetailViewController。

To pull this off, you will give BNRDetailViewController a property to hold a BNRItem.

为了胜利完成这个,你需要给BNRDetailViewController一个属性来拥有BNRItem。

When a row is tapped, BNRItemsViewController will give the corresponding BNRItem to the instance of BNRDetailViewController that is being pushed onto the stack.

当一行被选中后,BNRItemsViewController将给对应的BNRItem传递给将要进入stack的BNRDetailViewController。

The BNRDetailViewController will populate its text fields with the properties of that BNRItem.

BNRDetailViewController将会显示拥有那个BNRItem属性的text field .

Editing the text in the text fields on BNRDetailViewController's view will change the properties of that BNRItem.

编辑在BNRDetailViewController's view中 text field 中得text将会改变那个BNRItem的属性。

#import <UIKit/UIKit.h>
@class BNRItem;

@interface BNRDetailViewController : UIViewController

@property (nonatomic, strong) BNRItem *item;

@end

When the BNRDetailViewController's view appears on the screen, it needs to set up its subviews to show the properties of the item.

当BNRDetailViewController's的view 显示在屏幕上时,它需要设置它的subview 来显示item的属性

- (void)viewWillAppear:(BOOL)animated

{
[super viewWillAppear:animated];

BNRItem *item = self.item;

self.nameField.text = item.itemName; self.serialNumberField.text = item.serialNumber; self.valueField.text = [NSString stringWithFormat:@"%d",

item.valueInDollars];

// You need an NSDateFormatter that will turn a date into a simple date string

static NSDateFormatter *dateFormatter = nil; if (!dateFormatter) {

dateFormatter = [[NSDateFormatter alloc] init]; dateFormatter.dateStyle = NSDateFormatterMediumStyle; dateFormatter.timeStyle = NSDateFormatterNoStyle;

}

// Use filtered NSDate object to set dateLabel contents

self.dateLabel.text = [dateFormatter stringFromDate:item.dateCreated]; }

In BNRItemsViewController.m, add the following code to tableView:didSelectRowAtIndexPath: so that BNRDetailViewController has its item before viewWillAppear: gets called.

NSArray *items = [[BNRItemStore sharedStore] allItems]; BNRItem *selectedItem = items[indexPath.row];

// Give detail view controller a pointer to the item object in row detailViewController.item = selectedItem;

3.3how data is passed between view controllers?

Having all of the data in the root view controller and passing subsets of that data to the next UIViewController (like you just did) is a clean and efficient way of performing this task.

让root view controller 拥有所有数据,然后传递给下一个UIViewController是一个有效和干净的方式传递这些数据。

3.4 Appearing and disappearing views

Whenever a UINavigationController is about to swap views, it sends out two messages: viewWillDisappear: and viewWillAppear:.

当UINavigationController将要切换view时,它会发送两个消息viewWillDisappear和viewWillAppear。

The UIViewController that is about to be popped off the stack is sent the message viewWillDisappear:. The UIViewController that will then be on top of the stack is sent viewWillAppear:.

那个将要从stack 中popped 的UIViewController被发送为viewWillDisappear。那个将要添加到stack 顶部的UIViewController将会被发送viewWillAppear。

When a BNRDetailViewController is popped off the stack, you will set the properties of its item to the contents of the text fields.

当一个BNRDetailViewController从stack删除的时候,它就会设置它的item属性为text field 的内容。

When implementing these methods for views appearing and disappearing, it is important to call the superclass's implementation – it might have some work to do and needs to be given the chance to do it.

当实现这些方法的时候,调用superclass 的实现很重要。它可能有一些工作要做,你应该给它这个机会。

- (void)viewWillDisappear:(BOOL)animated

{
[super viewWillDisappear:animated];

// Clear first responder [self.view endEditing:YES];

// "Save" changes to item

BNRItem *item = self.item;

item.itemName = self.nameField.text; item.serialNumber = self.serialNumberField.text; item.valueInDollars = [self.valueField.text intValue];

3.4.1

Notice the use of endEditing:. When the message endEditing: is sent to a view, if it or any of its subviews is currently the first responder, it will resign its first responder status, and the keyboard will be dismissed. (The argument passed determines whether the first responder should be forced into retirement. Some first responders might refuse to resign, and passing YES ignores that refusal.)

主要到endEditing得使用。

当endEditing 被发给一个view ,那么这个view 以及它的任意subviews 如果是 currently first  responder,它将resign  first responder 的状态,并且keyboard将会消失。

Now the values of the BNRItem will be updated when the user taps the Back button on the UINavigationBar.
当用户tap  back button ,那么BNRItem将会更新。
When BNRItemsViewController appears back on the screen, it is sent the message viewWillAppear:. Take this opportunity to reload the UITableView so the user can immediately see the changes.
当BNRItemsViewController显示到屏幕上时,它会被发送一个viewWillAppear的消息。这是一个重新加载UITableView数据的机会。
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.tableView reloadData]; }

很困惑如何保存到[BNRItemStore sharedStore]的。 
4 . UINavigationBar
Every UIViewController has a navigationItem property of type UINavigationItem. However, unlike UINavigationBar, UINavigationItem is not a subclass of UIView, so it cannot appear on the screen.
每一个UIViewController都有一个UINavigationItem类型的navigationItem 属性。与UINavigationBar不同的是UINavigationItem并不是UIView 的子类,所以它不能显示在屏幕上。
Instead, the navigation item supplies the navigation bar with the content it needs to draw.
取而代之的是navigation item提供了navigation bar 需要绘制 的内容。
When a UIViewController comes to the top of a UINavigationController's stack, the UINavigationBar uses the UIViewController's navigationItem to configure itself
当一个UIViewController在UINavigationController'的顶部时,这个UINavigationBar用UIViewController的navigationItem来配置自己。

By default, a UINavigationItem is empty.
默认情况下,一个UINavigationItem是空的。
At the most basic level, a UINavigationItem has a simple title string.
UINavigationItem有一个简单地标题字符串。
When a UIViewController is moved to the top of the navigation stack and its navigationItem has a valid string for its title property, the navigation bar will display that string
当UIViewController被移动到navigation stack 顶部时,它的navigationItem有一个有效的string,那么navigation bar将会显示这个 string。
In BNRItemsViewController.m, modify init to set the navigationItem's title to read Homepwner.
- (instancetype)init
{
self = [super initWithStyle:UITableViewStylePlain]; if (self) {
UINavigationItem *navItem = self.navigationItem; navItem.title = @"Homepwner";
}
return self; }

It would be nice to have the BNRDetailViewController's navigation item title be the name of the BNRItem it is displaying. Obviously, you cannot do this in init because you do not yet know what its item will be.
明显的,你不能在init 方法中赋值,因为这时,你还不知道它的item是什么。
, the BNRDetailViewController will set its title when it sets its item property. In BNRDetailViewController.m, implement setItem:, replacing the synthesized setter method for item.
你可以重写setItem,在setItem中重写该方法。
- (void)setItem:(BNRItem *)item
{
_item = item;
self.navigationItem.title = _item.itemName; }

4.1 There are three customizable areas for each UINavigationItem: a leftBarButtonItem, a rightBarButtonItem, and a titleView.
每个UINavigationItem有三个通用的区域:leftBarButtonItem,rightBarButtonItem,titleView。
The left and right bar button items are pointers to instances of UIBarButtonItem, which contains the information for a button that can only be displayed on a UINavigationBar or a UIToolbar.
左边和右边的bar button items 有指针指向UIBarButtonItem的实例。该实例包含了只能在UINavigationBar或者是UIToolbar上显示的button 信息。

Like UINavigationItem, UIBarButtonItem is not a subclass of UIView.
UIBarButtonItem像UINavigationItem也不是UIView 的子类。
Instead, UINavigationItem encapsulates information that UINavigationBar uses to configure itself.
UINavigationItem概况了UINavigationBar配置自己需要的信息。
Similarly, UIBarButtonItem is not a view, but holds the information about how a single button on the UINavigationBar should be displayed.
相似的,UIBarButtonItem也不是个view,但是拥有怎样在UINavigationBar显示的一个button的信息。
(A UIToolbar also uses instances of UIBarButtonItem to configure itself.)
一个UIToolBar 也是用UIBarButtonItem的实例来配置自己。
The third customizable area of a UINavigationItem is its titleView.
第三个适应区域是它的titleView。 
You can either use a basic string as the title or have a subclass of UIView sit in the center of the navigation item. You cannot have both.
你可以用一个基本的string作为titile或者有一个UIView 的子类在navigation item 的中心。你不能同时有这两个。

A bar button item has a target-action pair that works like UIControl's target-action mechanism: when tapped, it sends the action message to the target.
一个bar button item  有一个target-action pair就像UIcontrol 的target-action 机制:当点击时,它发送一个action 消息给target.

let's add another UIBarButtonItem to replace the Edit button in the table view header. In BNRItemsViewController.m, edit the init method.
navItem.leftBarButtonItem = self.editButtonItem;
Where does editButtonItem come from?
这个editButtonItem从哪来的?
UIViewController has an editButtonItem property, and when sent editButtonItem, the view controller creates a UIBarButtonItem with the title Edit.
Even better, this button comes with a target- action pair: it sends the message setEditing:animated: to its UIViewController when tapped.
这个button有一个target-action pair:当点击的时候它发送setEditing:animated给UIViewController。

5 bug

bug:Cannot find executable for CFBundle 0x8f92720 </Applications/xcode5/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk/System/Library/AccessibilityBundles/CertUIFramework.axbundle> (not loaded)

解决办法:Temporary workaround: click iOS Simulator > Reset Content and Settings... and run again.
这个错误会随机出现。这应该是Xcode 的一个错误吧。

iOS Programming UINavigationController的更多相关文章

  1. iOS Programming Autorotation, Popover Controllers, and Modal View Controllers

    iOS Programming Autorotation, Popover Controllers, and Modal View Controllers  自动旋转,Popover 控制器,Moda ...

  2. iOS Programming UIStoryboard 故事板

    iOS Programming UIStoryboard In this chapter, you will use a storyboard instead. Storyboards are a f ...

  3. iOS Programming State Restoration 状态存储

    iOS Programming State Restoration 状态存储 If iOS ever needs more memory and your application is in the ...

  4. iOS Programming UISplitViewController

    iOS Programming UISplitViewController  The iPad, on the other hand, has plenty of screen space to pr ...

  5. iOS Programming Web Services and UIWebView

    iOS Programming Web Services and UIWebView The work is divided into two parts. The first is connecti ...

  6. iOS Programming Camera 1

     iOS Programming Camera  1 1 Displaying Images and UIImageView 1.1  put an instance of UIImageView o ...

  7. Head First iOS Programming

    内部分享: Head First iOS Programming http://www.slideshare.net/tedzhaoxa/head-first-ios-programming-4606 ...

  8. iOS Programming Recipe 6: Creating a custom UIView using a Nib

    iOS Programming Recipe 6: Creating a custom UIView using a Nib JANUARY 7, 2013 BY MIKETT 12 COMMENTS ...

  9. iOS Programming Controlling Animations 动画

    iOS Programming Controlling Animations 动画 The word "animation" is derived from a Latin wor ...

随机推荐

  1. 【IOS】启动画面

    总述: 两种方式,一种是使用系统自带的.按规则定义启动图片名称就可以,显示为1秒,要想延长时间,用[nsthread ​ sleepForTimeInterval:5.0] ,还有一种就是自己定义ui ...

  2. Bash Shell 解析路径获取文件名称和文件夹名

    前言 还是今天再写一个自己主动化打包脚本.用到了从路径名中获取最后的文件名称.这里记录一下实现过程. 当然,最后我也会给出官方的做法.(ps:非常囧,实现完了才发现原来Bash Shell有现成的函数 ...

  3. 2016/05/11 Thinkphp 3.2.2 验证码 使用 及校验

    先新建一个公共控制器,用于放置验证码的实例化代码(不用新建控制器也行,任意公共控制器都可以). 例如:PublicController.class.php 4 5 6 7 8 9 10 11 12 1 ...

  4. 2016/4/5 Ajax ①用户名 密码 登陆 注册 ② 判断用户名是否已存在 ③点击按钮出现民族选项下拉菜单 ④DBDA类 加入Ajaxquery方法 数组变字符串 字符串拆分

    ①登陆   注册    查表匹配    0405Ajax.php   ②判断用户名是否存在 <!DOCTYPE html> <html lang="en"> ...

  5. 再谈HBase八大应用场景

    HBase概述 HBase是一个分布式存储.数据库引擎,可以支持千万的QPS.PB级别的存储,这些都已经在生产环境验证,并且在广大的公司已经验证.特别是阿里.小米.京东.滴滴内部都有数千.上万台的HB ...

  6. HDU-ACM“菜鸟先飞”冬训系列赛——第9场

    Problem A 题意 一对兔子每月生一对兔子,兔子在\(m\)月后成熟,问\(d\)月后有多少兔子 分析 可以发现,第i月的兔子数量取决于第i-1月与i-m月,故 \(a[i]=a[i-1]+a[ ...

  7. HDU3092:Least common multiple(素数筛选+完全背包)

    题意 给出\(n\)和\(m\),将\(n\)拆成任意个数,求它们的最大的\(lcm\) 分析 1.可以证明\(n=p1^{s1}*p2^{s2}*...*pn^{sn}\)时\(lcm\)最大(其中 ...

  8. bzoj 2142: 礼物【中国剩余定理+组合数学】

    参考:http://blog.csdn.net/wzq_qwq/article/details/46709471 首先推组合数,设sum为每个人礼物数的和,那么答案为 \[ ( C_{n}^{sum} ...

  9. nginx下配置虚拟主机

    linux 虚拟机下配置虚拟主机 nginx.conf 文件不动, 在 conf.d 或者 conf 目录下 新建项目.conf server { listen 80; server_name loc ...

  10. Centos 下php安装配置xdebug扩展

    2018年05月02日 19:54:42 杨汉松 阅读数:44   1.下载安装xdebug 获取xdebug wget http://www.xdebug.org/files/xdebug-2.3. ...