删除子视图和视图控制器?

Posted

技术标签:

【中文标题】删除子视图和视图控制器?【英文标题】:Removing Subview and View Controller? 【发布时间】:2014-03-29 01:30:17 【问题描述】:

我正在通过以下方式添加子视图”

SettingsViewController *SVC = [[SettingsViewController alloc] initWithNibName:@"SettingsViewController" bundle:[NSBundle mainBundle]];
[self.parentViewController addChildViewController:SVC];
[self.view addSubview:SVC.view];

我的子视图是 300 x 360 并且在屏幕上居中。当我尝试删除它时会出现问题(正在释放)。

当我在这个新视图中按下关闭按钮时,我得到了非常糟糕的访问权限。添加我的视图的正确方法是什么?我有一个 SettingsViewController.xib 链接到一个 .h 和 .m 文件。

这是我的设置视图中的关闭按钮的外观:

-(IBAction)close:(id)sender 
   [self.view removeFromSuperview];
   [self removeFromParentViewController];

但即使我注释掉里面的所有内容,只要触发按钮,应用程序就会崩溃。

这是我的 .h 文件的样子:

#import <UIKit/UIKit.h>

@interface SettingsViewController : UIViewController

@property (nonatomic, strong) IBOutlet UIView *alertView;
@property (nonatomic, strong) IBOutlet UIButton *closeButton;
@property (nonatomic, strong) IBOutlet UILabel *musicLabel;
@property (nonatomic, strong) IBOutlet UILabel *soundFXLabel;
@property (nonatomic, strong) IBOutlet UILabel *vibrateLabel;
- (IBAction)close:(id)sender;
@end

还有我的实现文件:

    #import "SettingsViewController.h"

@interface SettingsViewController ()

@end

@implementation SettingsViewController
@synthesize alertView;

    - (void)viewDidLoad
    
    [super viewDidLoad];
    self.view.alpha = 0;
    self.alertView.layer.cornerRadius = 10.0f;
    self.alertView.layer.borderColor = [UIColor whiteColor].CGColor;
    self.alertView.layer.borderWidth = 4.0f;
    self.closeButton.layer.cornerRadius = 5.0f;
    self.closeButton.titleLabel.font = [UIFont fontWithName:@"SourceSansPro-Bold" size:20];
    self.musicLabel.font = [UIFont fontWithName:@"SourceSansPro-Bold" size:30];
    self.soundFXLabel.font = [UIFont fontWithName:@"SourceSansPro-Bold" size:30];
    self.vibrateLabel.font = [UIFont fontWithName:@"SourceSansPro-Bold" size:30];


    [UIView animateWithDuration:0.3
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^
                         self.view.alpha = 1;
                     
                     completion:^(BOOL finished)
                         //Display Players View

                     ];
    

    - (IBAction)close:(id)sender 
        //[self.view removeFromSuperview];
        //[self removeFromParentViewController];
    

    - (void)didReceiveMemoryWarning
    
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
    

    @end

最后但并非最不重要的是,这是我的故事板/xib 订单的快照:

【问题讨论】:

您的关闭和/或删除代码是什么样的? 您确定您的不良访问权限不是来自连接到您更改名称或删除的变量的插座吗? @MichaelDautermann 刚刚更新了我的答案 “当你注释掉里面的所有东西”?这是否意味着即使触摸带有“removeFromParentViewController”和“removeFromSuperview”注释的“close”按钮,您仍然会崩溃?您是否将 两个 IBActions(其中一个是伪造的或不存在的)连接到您的关闭按钮?检查您的 xib 文件... 嗨,迈克尔,只是为了确保我解开 xib 中的所有内容并重新连接所有内容,但我仍然收到错误消息。通过注释掉,我的意思是 close 方法中的所有内容。 【参考方案1】:

为您的 SettingsViewController 创建一个属性,您可以在其中添加并在创建它的位置分配它。

// in .h file or private category on top 
    @property (nonatomic, strong) SettingsViewController *settingsController;

// your usual code + assigning controller    
    SettingsViewController *SVC = [[SettingsViewController alloc] initWithNibName:@"SettingsViewController" bundle:[NSBundle mainBundle]];
    [self.parentViewController addChildViewController:SVC];
    [self.view addSubview:SVC.view];
    self.settingsController = SVC;

旁注:这种行为的原因是在 ViewController 的 .view 属性添加到您的视图之后,控制器被释放(现在只有 .view 是活动的)。因此,当您尝试在视图中点击按钮时,没有 SettingsViewController 来回调这些事件,因此会崩溃。当您创建属性并分配它时,控制器就会存在。

【讨论】:

感谢您的解释和建议!它完全按照它应该的方式工作,现在我明白了!谢谢! +1 不要忘记您应该在子视图控制器上调用didMoveToParentViewController(如果您正在制作动画,请在动画的完成块中执行此操作,如果您没有制作任何动画, 做完addSubview) 后立即做。同样,删除它时,请在启动 removeFromParentViewController 之前调用 willMoveToParentViewController:nil

以上是关于删除子视图和视图控制器?的主要内容,如果未能解决你的问题,请参考以下文章

从父级删除后保留的子视图控制器

删除子视图中的核心数据后更新表视图

如何正确删除 SFSafariViewController 作为子视图控制器?

删除子视图并将控制权发回

从子视图中删除视图不会调用 willRemoveSubview

text 此代码剪切使得添加或删除子视图控制器更容易。