chenyd9027
honobono bear@#%*#@
采纳率66.7%
2016-01-05 03:46 阅读 1.8k

iOS app error - Can't add self as subview

iOS app error - Can't add self as subview
已被困扰要疯了,求助如何解决

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

4条回答 默认 最新

  • wlm527 王王没想到 2016-01-05 11:43

    同一时间同时push多个controller在返回的时候会爆这样的错误,其本质的根源是push动画没有完成你就急着去push下一个controller。

    解决的办法如下:

    通过创建一个导航控制器的分类,将原有的push方法覆盖,再重写load方法,在里面exchange新的push和原始的push

    iphone - iOS app error - Can't add self as subview - Stack Overflow

    #import "UINavigationController+Consistent.h"

    #import

    /// This char is used to add storage for the

    isPushingViewController property.

    staticcharconst*constObjectTagKey="ObjectTag";

    @interfaceUINavigationController()

    @property(readwrite,getter = isViewTransitionInProgress) BOOL

    viewTransitionInProgress;

    @end
    @implementationUINavigationController(Consistent)

    -(void)setViewTransitionInProgress:(BOOL)property {

    NSNumber *number = [NSNumbernumberWithBool:property];

    objc_setAssociatedObject(self,ObjectTagKey, number , OBJC_ASSOCIATION_RETAIN);

    }
    -(BOOL)isViewTransitionInProgress {

    NSNumber *number =objc_getAssociatedObject(self, ObjectTagKey);

    return[number boolValue];

    }
    //注意上面是设置对象关联

    #pragmamark -InterceptPop,Push,PopToRootVC

    /// @name Intercept Pop, Push, PopToRootVC

    • (NSArray*)safePopToRootViewControllerAnimated:(BOOL)animated{

    if(self.viewTransitionInProgress)returnnil;

    if(animated){

    self.viewTransitionInProgress =YES;

    }
    //-- This is not a recursion, due to method swizzling thecall below calls the originalmethod.

    return[self

    safePopToRootViewControllerAnimated:animated];

    }

    • (NSArray*)safePopToViewController:(UIViewController*)viewController animated:(BOOL)animated {

    if(self.viewTransitionInProgress)returnnil;

    if(animated){

    self.viewTransitionInProgress =YES;

    }
    //-- This is not a recursion, due to method swizzling thecall below calls the originalmethod.

    return[selfsafePopToViewController:viewController animated:animated];

    }

    • (UIViewController*)safePopViewControllerAnimated:(BOOL)animated{

    if(self.viewTransitionInProgress)returnnil;

    if(animated){

    self.viewTransitionInProgress =YES;

    }
    return[selfsafePopViewControllerAnimated:animated];

    }

    • (void)safePushViewController:(UIViewController*)viewController animated:(BOOL)animated {

    self.delegate=self;

    //-- If we are already pushing a view controller, we dont

    push another one.

    if(self.isViewTransitionInProgress == NO) {

    //-- This is not a recursion, due to method swizzling thecall below calls the originalmethod.

    [selfsafePushViewController:viewController animated:animated];

    if(animated){

    self.viewTransitionInProgress = YES;

    }
    }
    }
    // This is confirmed to be App Store safe.

    // If you feel

    uncomfortable to use Private API, you could also use the delegate method

    navigationController:didShowViewController:animated:.

    • (void)safeDidShowViewController:(UIViewController*)viewController animated:(BOOL)animated {

    //-- This is not a recursion. Due to method swizzling this

    is calling the original method.

    [selfsafeDidShowViewController:viewController animated:animated];

    self.viewTransitionInProgress =NO;

    }
    // If the user doesnt complete the swipe-to-go-back gesture,

    we need to intercept it and set the flag to NO again.

    • (void)navigationController:(UINavigationController*)navigationController willShowViewController:(UIViewController*)viewController animated:(BOOL)animated {

    id tc =navigationController.topViewController.transitionCoordinator;

    [tcnotifyWhenInteractionEndsUsingBlock:^(id context) {

    self.viewTransitionInProgress =NO;

    //--Reenable swipe back gesture.

    self.interactivePopGestureRecognizer.delegate= (id)viewController;

    [self.interactivePopGestureRecognizer setEnabled:YES];

    }];
    //-- Method swizzling wont work in the case of a delegate

    so:

    //-- forward this method to the original delegate if there

    is one different than ourselves.

    if(navigationController.delegate!= self) {

    [navigationController.delegatenavigationController:navigationController

    willShowViewController:viewController

    animated:animated];

    }
    }

    • (void)load {

    //-- Exchange the original implementation with our custom

    one.

    method_exchangeImplementations(class_getInstanceMethod(self,@selector(pushViewController:animated:)),

    class_getInstanceMethod(self,@selector(safePushViewController:animated:)));

    method_exchangeImplementations(class_getInstanceMethod(self,@selector(didShowViewController:animated:)),

    class_getInstanceMethod(self,@selector(safeDidShowViewController:animated:)));

    method_exchangeImplementations(class_getInstanceMethod(self,@selector(popViewControllerAnimated:)),

    class_getInstanceMethod(self,@selector(safePopViewControllerAnimated:)));

    method_exchangeImplementations(class_getInstanceMethod(self,@selector(popToRootViewControllerAnimated:)),

    class_getInstanceMethod(self,@selector(safePopToRootViewControllerAnimated:)));

    method_exchangeImplementations(class_getInstanceMethod(self,@selector(popToViewController:animated:)),

    class_getInstanceMethod(self,@selector(safePopToViewController:animated:)));

    }

    @end
    //+ (void)load在类被加载的时候就会被执行,所以即使没有引入头文件或者主动调用他也会被执行。

    点赞 1 评论 复制链接分享
  • wlm527 王王没想到 2016-01-05 11:44

    同一时间同时push多个controller在返回的时候会爆这样的错误,其本质的根源是push动画没有完成你就急着去push下一个controller。

    解决的办法如下:

    通过创建一个导航控制器的分类,将原有的push方法覆盖,再重写load方法,在里面exchange新的push和原始的push

    iphone - iOS app error - Can't add self as subview - Stack Overflow

    #import "UINavigationController+Consistent.h"

    #import

    /// This char is used to add storage for the

    isPushingViewController property.

    staticcharconst*constObjectTagKey="ObjectTag";

    @interfaceUINavigationController()

    @property(readwrite,getter = isViewTransitionInProgress) BOOL

    viewTransitionInProgress;

    @end
    @implementationUINavigationController(Consistent)

    -(void)setViewTransitionInProgress:(BOOL)property {

    NSNumber *number = [NSNumbernumberWithBool:property];

    objc_setAssociatedObject(self,ObjectTagKey, number , OBJC_ASSOCIATION_RETAIN);

    }
    -(BOOL)isViewTransitionInProgress {

    NSNumber *number =objc_getAssociatedObject(self, ObjectTagKey);

    return[number boolValue];

    }
    //注意上面是设置对象关联

    #pragmamark -InterceptPop,Push,PopToRootVC

    /// @name Intercept Pop, Push, PopToRootVC

    • (NSArray*)safePopToRootViewControllerAnimated:(BOOL)animated{

    if(self.viewTransitionInProgress)returnnil;

    if(animated){

    self.viewTransitionInProgress =YES;

    }
    //-- This is not a recursion, due to method swizzling thecall below calls the originalmethod.

    return[self

    safePopToRootViewControllerAnimated:animated];

    }

    • (NSArray*)safePopToViewController:(UIViewController*)viewController animated:(BOOL)animated {

    if(self.viewTransitionInProgress)returnnil;

    if(animated){

    self.viewTransitionInProgress =YES;

    }
    //-- This is not a recursion, due to method swizzling thecall below calls the originalmethod.

    return[selfsafePopToViewController:viewController animated:animated];

    }

    • (UIViewController*)safePopViewControllerAnimated:(BOOL)animated{

    if(self.viewTransitionInProgress)returnnil;

    if(animated){

    self.viewTransitionInProgress =YES;

    }
    return[selfsafePopViewControllerAnimated:animated];

    }

    • (void)safePushViewController:(UIViewController*)viewController animated:(BOOL)animated {

    self.delegate=self;

    //-- If we are already pushing a view controller, we dont

    push another one.

    if(self.isViewTransitionInProgress == NO) {

    //-- This is not a recursion, due to method swizzling thecall below calls the originalmethod.

    [selfsafePushViewController:viewController animated:animated];

    if(animated){

    self.viewTransitionInProgress = YES;

    }
    }
    }
    // This is confirmed to be App Store safe.

    // If you feel

    uncomfortable to use Private API, you could also use the delegate method

    navigationController:didShowViewController:animated:.

    • (void)safeDidShowViewController:(UIViewController*)viewController animated:(BOOL)animated {

    //-- This is not a recursion. Due to method swizzling this

    is calling the original method.

    [selfsafeDidShowViewController:viewController animated:animated];

    self.viewTransitionInProgress =NO;

    }
    // If the user doesnt complete the swipe-to-go-back gesture,

    we need to intercept it and set the flag to NO again.

    • (void)navigationController:(UINavigationController*)navigationController willShowViewController:(UIViewController*)viewController animated:(BOOL)animated {

    id tc =navigationController.topViewController.transitionCoordinator;

    [tcnotifyWhenInteractionEndsUsingBlock:^(id context) {

    self.viewTransitionInProgress =NO;

    //--Reenable swipe back gesture.

    self.interactivePopGestureRecognizer.delegate= (id)viewController;

    [self.interactivePopGestureRecognizer setEnabled:YES];

    }];
    //-- Method swizzling wont work in the case of a delegate

    so:

    //-- forward this method to the original delegate if there

    is one different than ourselves.

    if(navigationController.delegate!= self) {

    [navigationController.delegatenavigationController:navigationController

    willShowViewController:viewController

    animated:animated];

    }
    }

    • (void)load {

    //-- Exchange the original implementation with our custom

    one.

    method_exchangeImplementations(class_getInstanceMethod(self,@selector(pushViewController:animated:)),

    class_getInstanceMethod(self,@selector(safePushViewController:animated:)));

    method_exchangeImplementations(class_getInstanceMethod(self,@selector(didShowViewController:animated:)),

    class_getInstanceMethod(self,@selector(safeDidShowViewController:animated:)));

    method_exchangeImplementations(class_getInstanceMethod(self,@selector(popViewControllerAnimated:)),

    class_getInstanceMethod(self,@selector(safePopViewControllerAnimated:)));

    method_exchangeImplementations(class_getInstanceMethod(self,@selector(popToRootViewControllerAnimated:)),

    class_getInstanceMethod(self,@selector(safePopToRootViewControllerAnimated:)));

    method_exchangeImplementations(class_getInstanceMethod(self,@selector(popToViewController:animated:)),

    class_getInstanceMethod(self,@selector(safePopToViewController:animated:)));

    }

    @end
    //+ (void)load在类被加载的时候就会被执行,所以即使没有引入头文件或者主动调用他也会被执行。

    点赞 1 评论 复制链接分享
  • CSDNXIAOC Robot-C 2016-01-05 03:49

    http://stackoverflow.com/questions/22421845/ios-app-crash-on-multiple-segue-at-the-same-time-going-to-other-segue-while-o/22928000#22928000

    http://stackoverflow.com/questions/19560198/ios-app-err......
    答案就在这里:iOS app error - Can't add self as subview
    ----------------------你好,人类,我是来自CSDN星球的问答机器人小C,以上是依据我对问题的理解给出的答案,如果解决了你的问题,望采纳。

    点赞 评论 复制链接分享
  • fandyvon 寒江独 2016-01-05 07:39

    同求答案图片说明

    点赞 评论 复制链接分享

相关推荐