V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
Yo_oY
V2EX  ›  iDev

iOS6中怎么知道一个ViewControllor从后台到前台(从栈里出来)?

  •  
  •   Yo_oY ·
    yoyoworms · 2013-04-29 02:54:36 +08:00 via iPad · 4844 次点击
    这是一个创建于 4230 天前的主题,其中的信息可能已经有所发展或是发生改变。
    在AViewControllor里调用了 [self presentViewControllor: BViewControllor .....],于是AViewControllor相当于到了后台,BViewControllor相当于到了前台。
    之后在BViewControllor执行[self dismissViewControllor ......],这时AViewControllor会恢复到前台。

    想问一下,此时我怎么知道AViewControllor已经恢复了,有没有类似ViewDidLoad这样的函数会自动执行?
    因为我在A里执行了一个任务,载入B的时候暂停,想在A恢复到前台时自动恢复这个任务。

    开发环境为iOS6,谢谢!
    19 条回复    1970-01-01 08:00:00 +08:00
    txx
        1
    txx  
       2013-04-29 03:09:13 +08:00   ❤️ 1
    appear = =
    PrideChung
        2
    PrideChung  
       2013-04-29 03:41:58 +08:00   ❤️ 3
    1.你应该在AViewController里面调用 dismissViewControllerAnimated:completion: 而不是BViewController。

    2.viewDidAppear太泛用了,你可以在AViewController里面添加一个方法
    - (void)dismissBViewController
    {
    [self dismissViewControllerAnimated:YES completion:nil];

    // 做其他事情
    }

    然后在创建 BViewController 的时候把 AViewController 作为 delegate 传给BViewController,需要dismiss的时候让 BViewController 调用 AViewController 的 dismissBViewController 方法。
    alexrezit
        3
    alexrezit  
       2013-04-29 08:26:47 +08:00   ❤️ 1
    @PrideChung
    别闹, A 里面调用就把 A 给 dismiss 了.

    比较常用的方法还是 -viewWillDisappear: 和 -viewDidAppear: 里面写. @PrideChung 说的 delegate 也是一个办法, 不过不如前者灵活, 换个视图逻辑就得重写很多代码了.
    Hysteria
        4
    Hysteria  
       2013-04-29 08:59:07 +08:00   ❤️ 1
    难道presentViewController这个方法所带的completion block不是在controller出现完毕之后调用的么= =
    PrideChung
        5
    PrideChung  
       2013-04-29 14:16:37 +08:00
    @alexrezit
    咱俩谁别闹?A里面调用就把 A 给 dismiss 了? 吐槽别人之前能不能请你先做个试验看看
    https://github.com/PrideChung/Demos/tree/master/PresentingViewController

    至少先查查文档吧。
    https://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#jumpTo_42

    The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, it automatically forwards the message to the presenting view controller.
    alexrezit
        6
    alexrezit  
       2013-04-29 14:40:01 +08:00
    @PrideChung
    我错了... 我承认! 以前一直用 B dismiss 的因为比较方便. = =
    allenhsu
        7
    allenhsu  
       2013-04-29 15:55:29 +08:00
    同意 @PrideChung 的意见
    allenhsu
        8
    allenhsu  
       2013-04-29 15:59:01 +08:00
    想换行,不小心 cmd + enter 直接发出去了 =。=

    dismiss 的时候,will/didAppear 会被调用,但是 push/pop 的时候同样会被调用,所以仅仅是一个可以的方案,不是最佳方案。

    一般需要 modal present 的 vc,较好的方式是定义 protocol,通过 delegate 回调,可以参考 UIImagePickerController 和 UIImagePickerControllerDelegate
    vixvix
        9
    vixvix  
       2013-04-29 22:06:04 +08:00
    A presentViewControllor B
    B dismissViewControllor
    这是没有问题的,文档上面就写的很清除:
    The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, it automatically forwards the message to the presenting view controller.

    你在B调用 dismiss的时候,这个dismiss会被传递到"the presenting view controller", 也就是A, 就等于A dismiss B.
    PrideChung
        10
    PrideChung  
       2013-04-30 03:45:53 +08:00
    @vixvix

    我以为第一句话就说得够清楚了。
    The presenting view controller is responsible for dismissing the view controller it presented.

    一次能成功的代码不代表一直能成功,我告诉你一种可能会出问题的情况。

    如果BViewController在进行一些很耗时的操作,它设了一个回调,执行下面这行代码:
    [self dismissViewControllerAnimated:YES completion:nil]; // 耗时操作完成后打算dismiss自己

    期间因为业务需要,BViewController 上面又弹出了一个 CViewController,之后 BViewController 的回调触发了,结果CViewController 被dismiss了,BViewController却还在。因为这时系统发现 BViewController 的 presentedViewController属性不为nil,就不把你的 dismissViewController 自动forward到AViewController了。

    如果你觉得上面的话太抽象,我更新了我的Demo来演示这种情况。
    https://github.com/PrideChung/Demos/tree/master/PresentingViewController
    jun1st
        11
    jun1st  
       2013-04-30 16:05:08 +08:00
    @alexrezit 你不完全错,记得是在iOS5之前,需要presentingViewController来Dismiss,在5之后,可以直接Dismiss
    xuan_lengyue
        12
    xuan_lengyue  
       2013-04-30 16:08:37 +08:00
    显然是 viewWillAppear 和 viewWillDisappear,实在不行在 B dismiss 的时候发布 Notification,在 A 里监听。
    zhigang1992
        13
    zhigang1992  
       2013-05-01 11:26:52 +08:00
    isMovingFromParentViewController

    isMovingToParentViewController
    alexrezit
        14
    alexrezit  
       2013-05-01 11:31:17 +08:00
    @jun1st
    错了就是错了, 这个咱得承认, 要对自己说的话负责.
    ShiningRay
        15
    ShiningRay  
       2013-05-01 13:51:10 +08:00
    楼主可是在暴走漫画画过不少作品的那位?
    Yo_oY
        16
    Yo_oY  
    OP
       2013-05-01 18:32:23 +08:00 via iPad
    @ShiningRay 不是哈
    jun1st
        17
    jun1st  
       2013-05-03 12:54:31 +08:00
    @alexrezit 你去看看iOS 5和6
    walkingway
        18
    walkingway  
       2013-05-03 13:34:48 +08:00
    @alexrezit 的意思是当A弹出B,B又弹出C的时候,这时候B调用dismiss,不会传递到A,而是直接把C给dimiss掉了。简单的说就是B已经占了资源了,当接到释放命令的时候,就必须的先交出自己的,自己没有占有资源的时候才能尝试向上一级发出申请。
    alexrezit
        19
    alexrezit  
       2013-05-03 15:25:04 +08:00
    @jun1st
    @walkingway
    我知道. =.=
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3574 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:09 · PVG 08:09 · LAX 16:09 · JFK 19:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.