Ios 从视图层次结构中删除子视图并将其核化的正确方法是什么?

Ios 从视图层次结构中删除子视图并将其核化的正确方法是什么?,ios,cocoa-touch,uiview,subview,Ios,Cocoa Touch,Uiview,Subview,我有一个包含多个子视图的父UIView。我需要定期删除子视图并将其从系统中完全删除。正确的方法是什么?我试过这个: UIView *v = [self.containerView viewWithTag:[n integerValue]]; [v removeFromSuperview]; 得到了一个奇怪的结果。以前存在的视图也消失了。发生了什么事?这是正确的总体思路。那些其他的UIView消失了,它们与这个UIView有什么关系?它们是此视图的子视图吗?它们是否在要删除的视图的deallo

我有一个包含多个子视图的父UIView。我需要定期删除子视图并将其从系统中完全删除。正确的方法是什么?我试过这个:

UIView *v = [self.containerView viewWithTag:[n integerValue]];

[v removeFromSuperview];

得到了一个奇怪的结果。以前存在的视图也消失了。发生了什么事?

这是正确的总体思路。那些其他的UIView消失了,它们与这个UIView有什么关系?它们是此视图的子视图吗?它们是否在要删除的视图的dealloc方法中解除锁定

你确定你的标签是唯一的吗


Sujal

它们只是从显示中消失,还是从显示和视图层次中消失?调试器向您显示了什么?

cell.contentView是否可能与要删除的子视图具有相同的标记?根据viewWithTag删除:

接收方层次结构中的视图 这和标签相符。接受者是 包括在搜索中

如果是这种情况,则可能是您无意中从单元格中删除了cell.contentView。如果n为零,并且单元格的contentview没有为其设置任何标记,则默认为0并导致出现这种情况。

尝试以下操作:

UIView *v = [self.containerView viewWithTag:[n integerValue]];
v.hidden = YES;
[self.containerView bringSubviewToFront:v];
[v removeFromSuperview];
我刚刚从UIView类文档中注意到的另一件事——请参见最后一句:

从SuperView移除 取消接收器与其superview和窗口的链接,并将其从响应器链中移除

  • (无效)从SuperView中移除
讨论 如果接收器的superview不是nil,则此方法释放接收器。如果计划重用该视图,请确保在调用此方法之前保留该视图,并确保在使用完该视图或将其添加到另一个视图层次结构后根据需要释放该视图

显示时切勿调用此方法。

更新:现在是2014年,在不隐藏子视图的情况下删除子视图效果非常好。原始海报的代码应按原样工作:

UIView *v = [self.containerView viewWithTag:[n integerValue]];
[v removeFromSuperview];

这将删除v及其作为子视图附加的任何视图,留下containerView和v的任何同级视图。

从视图中删除所有子视图:

for(UIView *subview in [view subviews]) {
   [subview removeFromSuperview];
}
如果只想删除某些特定视图,请执行以下操作:

for(UIView *subview in [view subviews]) {
  if([subview isKindOfClass:[UIButton class]]) {
     [subview removeFromSuperview];
 } else {
     // Do nothing - not a UIButton or subclass instance
 }
}
也可以按标记值删除子视图:

for(UIView *subview in [view subviews]) {
    if(subview.tag==/*your subview tag value here*/) {
        [subview removeFromSuperview];

    } else {
        // Do nothing - not a UIButton or subclass instance
    }
}

Swift 3.0:

let viewToRemove = mySuperView.viewWithTag(myTag)
viewToRemove?.removeFromSuperview()

Swift 4:扩展UIView

extension UIView {
    public func removeAllSubviews() {
        for subview in self.subviews {
            subview.removeFromSuperview()
        }
    }
}

覆盖函数视图将出现(u动画:Bool)
{
超级。视图将显示(动画)
如果让topController=UIApplication.topViewController(){
如果topController.isKind(of:ProviderHome.self)
{
让arrOfSuview=self.view.subview
如果arrOfSuview.count>1
{
打印(“子视图的Davender Arr:\(arrOfSuview)”)
对于0..1中的i
{
打印(“子视图的Davender Arr:\(arrOfSuview)”)

对于0中的i..我尝试删除的视图的所有同级都会立即从屏幕上显示。什么?所有同级都有唯一的标记,这是我引用视图的方式。我喜欢这一点,而不是接受的答案。这似乎是一种更直接的方法-而且您非常彻底地包括了选择某人可能想要的任何选项delete.+1.hmm…事实上,现在我已经尝试运行了这个,它不起作用。我正在使用isKindOfClass选项。我的UIView中有UILabels和UISlider,我正在尝试删除所有滑块,所以我有:
if([subview isKindOfClass:[UISlider class]])
所有的东西都返回了真值,包括标签,所以所有的东西都被删除了。我试着用isMemberOfClass替换isKindOfClass,但也不起作用。UISliders有什么特别的地方会使这不起作用吗?我发现了我的问题,我有一个打字错误,花了我很长时间才找到。代码很好用正如这里显示的那样。@我检查了这一点和它的工作原理。在我的视图中,我有两个标签、两个滑块和一个按钮。它只删除滑块。对于(UIView*subview In[self.view subview]){if([subview iskindof class:[UISlider class]]){[subview removeFromSuperview];}else{//Do nothing-不是UIButton或子类实例}是的,就像我说的,我有一个拼写错误把它搞砸了。你的代码很好,我修复了拼写错误,效果很好。ominous在显示时从不调用此方法。非常简单,就像Blackberry所说的那样(UIView*s在[视图子视图]中)[s从SuperView中移除];早在09年,如果你在隐藏子视图之前删除了它,你会得到一些奇怪的结果。或者至少这是我看到的,原始海报也是如此。UIView类引用中曾经有这样的警告,现在已经被另一个警告所取代。我想说,原始海报删除子视图的方法现在可能是错误的ect,不需要任何额外的代码。(他只是删除了一个子视图)
extension UIView {
    public func removeAllSubviews() {
        self.subviews.forEach { $0.removeFromSuperview() }
    }
}
    override func viewWillAppear(_ animated: Bool)
    {
        super.viewWillAppear(animated)

        if let topController = UIApplication.topViewController() {

            if topController.isKind(of: ProviderHome.self)
            {
                let arrOfSuview = self.view.subviews

                if arrOfSuview.count > 1
                {
                    print("Davender Arr of subviews : \(arrOfSuview)")

                    for i in 0..<arrOfSuview.count
                    {
                        let objSub = arrOfSuview[i]

                        if objSub.tag == 101
                        {
                          objSub.removeFromSuperview()
                        }

                    }



                }


                NotificationCenter.default.addObserver(self, selector: #selector(ProviderHome.handelPushNotification), name: NSNotification.Name(rawValue: "handelPush"), object: nil)

                NotificationCenter.default.addObserver(self, selector: #selector(ProviderHome.handelLocalNotification), name: NSNotification.Name(rawValue: "handelLocal"), object: nil)
            }
        }


    }

@objc func handelPushNotification(_ notification: NSNotification)  {


        let arrOfSuview = self.view.subviews

        if arrOfSuview.count > 1
        {
            print("Davender Arr of subviews : \(arrOfSuview)")

            for i in 0..<arrOfSuview.count
            {
                let objSub = arrOfSuview[i]

                if objSub.tag == 101
                {
                    objSub.removeFromSuperview()
                }

            }

        }

        if notification.userInfo != nil
        {


            let dict = notification.userInfo as! Dictionary<String, Any>

            let d = dict["data"] as! Dictionary<String, Any>

            let action = d["gcm.notification.label"] as! String

            print("current message id :- ", action)

            self.getNotificationId = action

            if getNotificationId != ""
            {
               //call the api for getting Data

                AppDelegate.sharedInstance().myCurrentnotificationId = getNotificationId

                //working code
                let storyboard = UIStoryboard(name: "Provider", bundle: nil)
                let vc = storyboard.instantiateViewController(withIdentifier: "CommonPopUpsVC") as! CommonPopUpsVC
                vc.modalPresentationStyle = .overFullScreen
                vc.view.frame = self.view.frame
                vc.view.tag = 101
                self.view.addSubview(vc.view)
                self.present(vc, animated: true, completion: nil)

            }


       }
    }