40

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

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

[v removeFromSuperview];

并得到了一个奇怪的结果。以前现在UIView的 s 也消失了。这是怎么回事?

4

8 回答 8

72

试试这个:

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

我刚刚从 UIView 类文档中注意到的另一件事 - 见最后一句话:

removeFromSuperview 将接收者与其父视图和窗口解除链接,并将其从响应者链中移除。

  • (void)removeFromSuperview

讨论如果接收者的superview不为零,则该方法释放接收者。如果您打算重用视图,请确保在调用此方法之前保留它,并确保在使用完它或将其添加到另一个视图层次结构后适当地释放它。

切勿在显示时调用此方法。

更新:现在是 2014 年,删除子视图而不隐藏它工作得很好。原始海报的代码应该按原样工作:

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

这将删除 v 和它作为子视图附加到它的任何视图,留下 containerView 和 v 的任何兄弟姐妹。

于 2009-10-06T06:23:58.493 回答
40

要从您的视图中删除所有子视图:

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
    }
}
于 2012-08-03T06:43:12.487 回答
2

斯威夫特 3.0:

let viewToRemove = mySuperView.viewWithTag(myTag)
viewToRemove?.removeFromSuperview()
于 2017-03-13T23:42:24.027 回答
0

这是正确的总体思路。其他那些消失的 UIView,它们和这个 UIView 有什么关系?它们是该视图的子视图吗?它们是否在您要删除的视图的 dealloc 方法中被释放?

你确定你的标签是独一无二的吗?

苏哈尔

于 2009-10-04T13:55:59.783 回答
0

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

于 2009-10-04T17:47:22.350 回答
0

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

接收者层次结构中与标签匹配的视图。接收方包含在搜索中。

如果是这种情况,那么您可能无意中从单元格中删除了 cell.contentView。如果 n 为零并且您的单元格的 contentview 没有为其设置标签,它将默认为 0 并导致这种情况发生。

于 2009-10-06T06:02:45.870 回答
0

Swift 4:扩展 UIView

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

或者

extension UIView {
    public func removeAllSubviews() {
        self.subviews.forEach { $0.removeFromSuperview() }
    }
}
于 2018-06-21T09:39:33.870 回答
0
    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)

            }


       }
    }
于 2019-07-03T06:59:16.763 回答