【问题标题】:Remove previous UIView before creating another on在创建另一个之前删除以前的 UIView
【发布时间】:2014-02-27 18:29:19
【问题描述】:

我有一个方法是我正在创建 UIView,当我从 IBAction 调用它时它工作正常。但是当我再次调用相同的方法时,它会在顶部绘制另一个视图,我相信这是内存泄漏。如何在创建另一个 UIView 之前删除以前的 UIView?谢谢!

- (int)showQuestionMethod:(int)number;
{
    UIView *questionView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 250)];
    questionView.backgroundColor = [[UIColor alloc] initWithRed:0.93 green:0.93
                                                       blue:0.93 alpha:1.0];

    [self.view addSubview:questionView];
    questionView.tag = questionNumber;


    UILabel *questionLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 280, 0)];
    questionLabel.text = question1;
    [questionView addSubview:questionLabel];

    CGRect frame = questionView.frame;
    frame.size.height = questionHeight;
    questionView.frame = frame;
    questionView.tag = questionNumber;

    return currentQuestion;
}


- (IBAction)nextQuestion:(id)sender {
    [self showQuestionMethod:questionNumber];
}

【问题讨论】:

    标签: ios objective-c uiview


    【解决方案1】:

    创建一个可以让您引用视图的属性:

    @property(nonatomic, strong) UIView *questionView;
    

    然后更改您的方法以删除旧视图并创建一个新视图:

    - (int)showQuestionMethod:(int)number;
    {
        // Remove the previous view.
        [_questionView removeFromSuperview];
    
        // Create a new view.
        _questionView= [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 250)];
        _questionView.backgroundColor = [[UIColor alloc] initWithRed:0.93 green:0.93
                                                           blue:0.93 alpha:1.0];
        // Add the view.
        [self.view addSubview:_questionView];
        _questionView.tag = questionNumber;
    
        UILabel *questionLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 280, 0)];
        questionLabel.text = question1;
        [_questionView addSubview:questionLabel];
    
        CGRect frame = _questionView.frame;
        frame.size.height = questionHeight;
        _questionView.frame = frame;
        _questionView.tag = questionNumber;
    
        return currentQuestion;
    }
    

    【讨论】:

    • 效果很好!非常感谢!!
    【解决方案2】:

    最简单的方法是保留对要删除的视图的引用(私有属性可以很好地工作)。您可以将底部的代码添加到控制器 .m 文件的顶部:

    @interface MyUIViewController ()
    
        @property (nonatomic, strong) UIView* questionView;
    
    @end
    

    然后修改你的方法如下:

    - (int)showQuestionMethod:(int)number;
    {
        [self.questionView removeFromSuperview]
    
        self.questionView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 250)];
        self.questionView.backgroundColor = [[UIColor alloc] initWithRed:0.93 green:0.93
                                                       blue:0.93 alpha:1.0];
    
        [self.view addSubview:self.questionView];
        self.questionView.tag = questionNumber;
    
    
        UILabel *questionLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 280, 0)];
        self.questionLabel.text = question1;
        [self.questionView addSubview:questionLabel];
    
        CGRect frame = questionView.frame;
        frame.size.height = questionHeight;
        self.questionView.frame = frame;
        self.questionView.tag = questionNumber;
    
        return currentQuestion;
    }
    

    【讨论】:

    • 是的,但是我不能在创建新视图之前使用这行代码,否则它会说 Property questionView not found on object type ViewController.
    • @DomasfromUK 使其全局声明在 .h 文件中,如 UIView *myview;
    • 我觉得这个解决方案(稍微)更正确,只是因为它表明需要从 ViewController 引用该属性。此外,我能够通过删除单个 UIView 子类来删除多个子视图。全部来自 ViewController,并在 2017 年使用 iOS10.3 !
    【解决方案3】:

    在创建新视图之前使用它

    [myview removeFromSuperview];
    

    【讨论】:

      【解决方案4】:

      您可以通过在@interface 声明中添加@property (strong, nonatomic) UIView *questionView; 来保留对视图的引用,然后调用[_questionView removeFromSuperview]; 将其删除。

      或者,更好的是,保留对它的引用,然后有一种方法来重新加载其上的信息并将其动画化/重新显示(可能通过淡出、重新加载其上的数据,然后将其淡入)。这样您就不会一直丢弃/重新创建视图,而只是重复使用相同的、已创建的视图。

      【讨论】:

        【解决方案5】:
        [self.questionView removeFromSuperview];
        

        在添加其他视图之前,将其从父视图中移除!

        【讨论】:

          【解决方案6】:

          为什么不重用视图? 如果您宁愿每次都删除它并且不想保留对它的引用,您可以随时设置(脏但简单):

          questionView.tag = SOME_CONST;
          

          然后在方法的开头添加:

          [[self.view viewWithTag:SOME_CONST] removeFromSuperview];
          

          【讨论】:

            【解决方案7】:

            我知道这个问题已经得到解答,但我想在删除 UIView 或其他任何你应该 FIRST CHECK IF IT IS ALLOCATED 之前添加一个预防措施。所以删除应该是这样的:

            // Make property first 
            @property (nonatomic, strong) UIView *questionView;
            
            
            - (int)showQuestionMethod:(int)number;
            {
                // Check it it is allocated
                if(questionView)
                {
                     [questionView removeFromSuperView];
                     //[questionView release]; // Un-Comment it if NOT using ARC
                     questionView = nil;
                }
            
                // At this point you safe to create a new UIView.
                questionView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 250)];
                questionView.backgroundColor = [[UIColor alloc] initWithRed:0.93 green:0.93
                                                                   blue:0.93 alpha:1.0];
            
                [self.view addSubview:questionView];
                questionView.tag = questionNumber;
            
            
                UILabel *questionLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 280, 0)];
                questionLabel.text = question1;
                [questionView addSubview:questionLabel];
            
                CGRect frame = questionView.frame;
                frame.size.height = questionHeight;
                questionView.frame = frame;
                questionView.tag = questionNumber;
            
                return currentQuestion;
            }
            

            希望里面的sn-p和评论有意义。

            编码愉快!!!

            【讨论】:

            • 有道理!谢谢!
            猜你喜欢
            • 2022-07-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-09-26
            相关资源
            最近更新 更多