【问题标题】:How to remove UIView or UIButton from superview inside UIScrollView in swift如何快速从 UIScrollView 中的超级视图中删除 UIView 或 UIButton
【发布时间】:2016-11-28 06:32:01
【问题描述】:

我执行以下代码将 UIView 和 UIButton 作为标签添加到 UIScrollView 中。将数据附加到 UIScrollView 中一切正常。问题是如何删除 UIScrollView 中的 UIView 和 UIButton。我确实删除了,但它并没有从 UI 中消失。请帮我看看怎么办。

这里是创建 UIView & UIButton 作为标签

    var xOffset: CGFloat = 0;
    var i = 0;
    for location in locationNameStrs {
        let myString: NSString = location as NSString
        let size: CGSize = myString.sizeWithAttributes([NSFontAttributeName: UIFont(name: "HelveticaNeue", size: 13)!])
        outletView = UIView(frame: CGRectMake(xOffset, 10, size.width + 40, 40))
        outletView.tag = i
        outletStrs = UIButton(frame: CGRectMake(0, 5, outletView.frame.size.width, 25))
        outletStrs.setTitle(location, forState: .Normal)
        outletStrs.titleLabel?.textAlignment = NSTextAlignment.Center
        outletStrs.backgroundColor = UIColor(red:0.00, green:0.45, blue:0.74, alpha:1.0)
        outletStrs.layer.cornerRadius = 12.5
        outletStrs.tag = i
        outletStrs.addTarget(self, action: #selector(self.removeTags(_:)), forControlEvents: UIControlEvents.TouchUpInside)
        outletStrs.titleLabel?.font = UIFont(name: "HelveticaNeue", size: 13)!

        let closeImg = UIImageView (frame: CGRectMake(outletStrs.frame.size.width - 30, 0, 25, 25))
        closeImg.image = UIImage(named: "close")
        closeImg.contentMode = UIViewContentMode.Right
        outletStrs.addSubview(closeImg)
        outletView.addSubview(outletStrs)

        tagScrollView.addSubview(outletView)
        xOffset = xOffset + size.width + 50
        i = i + 1
    }

    tagScrollView.contentSize = CGSizeMake(xOffset + 50, 50)

这里是删除,但问题是那些没有从 UI 中消失

func removeTags(sender: UIButton) {
    let ok = UIAlertAction(title: "OK", style: .Default) { (action:UIAlertAction!) in
        if self.locationNameStrs.contains(self.locationNameStrs[sender.tag]) {
            self.locationNameStrs.removeAtIndex(sender.tag)
            self.outletView.removeFromSuperview()
            self.outletStrs.removeFromSuperview()
            self.closeImg.removeFromSuperview()
            self.addButton.removeFromSuperview()
            self.displayOutletTags()
        }
    }
}

【问题讨论】:

  • 您是否通过调试器/控制台输出验证了if 分支确实正在执行?此外,除了顶级 outletView 之外,删除任何内容都没有任何意义。它会带走所有的子视图。
  • 此外,if 逻辑也没有意义,因为您要询问数组是否包含其自己的成员之一。唯一的选择是让sender.tag 越界,这会使您的程序崩溃。
  • @BaseZen 你能建议我怎么做吗?
  • 你能把整个项目放在 GitHub 上还是按照惯例。 UI错误的问题在于问题的来源太多。然后我可以在修复它之后总结答案。
  • @BaseZen 我找到了解决方案。

标签: ios swift uiview uiscrollview uibutton


【解决方案1】:

您没有正确使用警报 API。您忽略了将其显示在屏幕上的重要部分——视图控制器本身。你需要:

func removeTags(sender: UIButton) {
    let alertBox = UIAlertController(title: "Removing tags", message: "I will now remove some tags.", preferredStyle: .Alert)
    let okAction = UIAlertAction(title: "OK", style: .Default) { (action:UIAlertAction!) in
        guard sender.tag < self.locationNameStrs.count else {
            print("Invalid tag index \(sender.tag)!")
            return
        }
        self.locationNameStrs.removeAtIndex(sender.tag)
        self.outletView.removeFromSuperview()
        self.dislayOutletTags()
    }
    alertBox.addAction(okAction)
    self.presentViewController(alertBox, animated: true, completion: nil)
}

没有警报,因为您似乎不希望这样:

func removeTags(sender: UIButton) {
    guard sender.tag < self.locationNameStrs.count else {
        print("Invalid tag index \(sender.tag)!")
        return
    }
    self.locationNameStrs.removeAtIndex(sender.tag)
    self.outletView.removeFromSuperview()
    self.dislayOutletTags()
}

您不应该遍历滚动视图来删除您找到的每个视图。这是脆弱而尴尬的设计。您已经在跟踪添加的视图,因此请按名称将其删除。

您的解决方案中的isKindOfClass() 毫无意义,因为根据定义,视图的子视图都是UIView 的子类。

同样,您的 if 语句毫无意义,因为您正在查看数组中的一个项目,并询问该数组是否包含它。

【讨论】:

  • 你没有提到要删除哪个 UIView。
  • 它明确删除了outletView,正如您在代码中看到的那样。结果,作为子视图添加到outletView 的所有内容都会被自动删除。试试看。
  • 如果我渲染你的代码,点击的 UIView 不能移动。其他第一个/最后一个 UIView 被删除。
  • 然后您需要跟踪哪个被点击,将其存储在类属性中(self.outletView 或其他),以便可以从您的removeTags 方法中删除它。您没有提供足够的上下文,因此您有责任自己修复该部分。答案只是为了帮助您制作正确的UIAlertController,并消除有关isKindOfClass.contains 的冗余。其余的由您负责,除非您想在另一个问题中发布整个课程代码。可能最适合代码审查论坛获得全面的批评。
【解决方案2】:
if self.locationNameStrs.contains(self.locationNameStrs[sender.tag]) {
    self.locationNameStrs.removeAtIndex(sender.tag)
    for view in self.tagScrollView.subviews {
        if view.isKindOfClass(UIView) {
            view.removeFromSuperview()
        }
    }
    self.displayOutletTags()
}

以上编码解决了我的要求。

【讨论】:

  • 风格仍然很糟糕,并显示出一些误解。请参阅上文了解如何正确使用警报控制器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多