在touchesBegan

时间:2018-11-27 18:30:33

标签: ios swift

我在didMove(to view :)方法中添加了一个名为textView的UITextView,并想在touchedBegan方法中删除。但是removeFromSuperview()不起作用。 textView的超级视图为nil,但self.view的子视图仍然包含textView。

如果我在didMove中调用textView.removeFromSuperview(以查看:),则会将其从self.view中删除。

即使我设置textView.isHidden = true,textView仍在屏幕上。

这是代码。

import UIKit
import SpriteKit

class InputScene: GameScene,UITextViewDelegate {

    var textView: UITextView!{
    willSet {
        //willSet the subview: Optional([])
        //willSet the subview: Optional([<UITextView: 0x7f94b80c1800; frame = (20 198.667; 374 200); text = ''; clipsToBounds = YES; gestureRecognizers = <NSArray: 0x600001a05cb0>; layer = <CALayer: 0x600001418a00>; contentOffset: {0, 0}; contentSize: {374, 192}; adjustedContentInset: {0, 0, 0, 0}>])
        print("willSet the subview: \(self.view?.subviews)")
        return
    }
}
    var transLabel = SKLabelNode(text: "Go to Game Scene.")

    override func didMove(to view: SKView) {
        // Set the textView
        backgroundColor = .white
        textView = UITextView(frame: CGRect(x: 150, y: 0, width: self.size.width-40, height: 200))
        textView.center = CGPoint(x: self.size.width/2, y: self.size.height/3)
        textView.backgroundColor = UIColor.red

        // Add subview and show that it has been added
        self.view?.addSubview(textView)

        // Print self.view's for the first time.
        //The subviews: [<UITextView: 0x7fbe3984f600; frame = (20 198.667; 374 200); text = ''; clipsToBounds = YES; gestureRecognizers = <NSArray: 0x600001c5da40>; layer = <CALayer: 0x60000124af40>; contentOffset: {0, 0}; contentSize: {374, 192}; adjustedContentInset: {0, 0, 0, 0}>]
        //The subviews: [<UITextView: 0x7fbe3984f600; frame = (20 198.667; 374 200); text = ''; clipsToBounds = YES; gestureRecognizers = <NSArray: 0x600001c5da40>; layer = <CALayer: 0x60000124af40>; contentOffset: {0, 0}; contentSize: {374, 192}; adjustedContentInset: {0, 0, 0, 0}>, <UITextView: 0x7fbe3a84cc00; frame = (20 198.667; 374 200); text = ''; clipsToBounds = YES; gestureRecognizers = <NSArray: 0x600001c58d20>; layer = <CALayer: 0x600001244f00>; contentOffset: {0, 0}; contentSize: {374, 192}; adjustedContentInset: {0, 0, 0, 0}>]
        print("The subviews: \(view.subviews)")

        // Add transfer label
        transLabel.position = CGPoint(x: size.width/2, y: size.height/2)
        transLabel.fontColor = UIColor.black
        addChild(transLabel)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let touch = touches.first else {
            return
        }
        if transLabel.contains(touch.location(in: self)) {
                self.textView.removeFromSuperview()
                self.textView.isHidden = true

            // Print the textView's superview
            // The textView's superview: nil
            print("The textView's superview: \(String(describing: textView.superview))")

            // Print the self.view's subview for the second time.
            // The self.view's subview still contains the textView
            // The subviews: Optional([<UITextView: 0x7fc60b8a9000; frame = (20 198.667; 374 200); text = ''; clipsToBounds = YES; gestureRecognizers = <NSArray: 0x60000332a280>; layer = <CALayer: 0x600003d30ce0>; contentOffset: {0, 0}; contentSize: {374, 192}; adjustedContentInset: {0, 0, 0, 0}>])
            print("The subviews: \(String(describing: self.view?.subviews))")
            textView.removeFromSuperview()
            view?.presentScene(SKScene(fileNamed: "GameScene"))
        }
    }
}

打印的“子视图”加倍的问题是因为在呈现场景时didMoveToView被触发了两次。这是因为Xcode首先设置场景的虚拟版本,然后才设置真实场景。不会造成任何错误。

我试图将textView设置为弱,但根本没有出现。

即使我没有查看过?.presentScene(SKScene(fileNamed:“ GameScene”)),textView仍然无法删除。我尝试将InputScene设置为SKScene的子类,而不是GameScene的子类,但这无济于事。

我尝试在touchesBegan方法中打印textView的描述,结果self.views的子视图不是预期的“ textView”。

2 个答案:

答案 0 :(得分:0)

您没有解释的是如何出现两个文本视图。显然有两种文本视图,因为我们可以在以下日志中看到它们:

// The subviews: [<UITextView: 0x7fbe3984f600 ....
// The subviews: Optional([<UITextView: 0x7fc60b8a9000....

那些是两个不同的地址值,因此它们是两个不同的文本视图。暗示是在某个时候(也许您的问题中未显示?),您正在向self.view添加另一个文本视图。

如果是这样,并且每次添加文本视图时都设置了textView的值,则会丢失对第一个文本视图的引用。让我们假设您是对的,并且您不小心这样做了两次:

textView = UITextView(frame: CGRect(x: 150, y: 0, width: self.size.width-40, height: 200))
self.view?.addSubview(textView)

现在,第二次这样做,您可以有效地将第一个文本视图从textView的引用位置弹出,并将其替换为第二个。因此,现在如何将第一个文本视图告诉removeFromSuperview()?请记住,textView不再引用它。多次告诉textViewremoveFromSuperview()不会有帮助,因为textView不再引用第一个文本视图。

答案 1 :(得分:0)

如果您是对的,并且两次添加了textView,则一个简单的解决方案是检查textView是否为nil,基于此,您可以决定是否需要添加

首先将textView声明为nil

var textView: UITextView?

然后您可以致电

if textView != nil{
    textView = UITextView(frame: CGRect(x: 150, y: 0, width: self.size.width-40, height: 200))
    textView.center = CGPoint(x: self.size.width/2, y: self.size.height/3)
    textView.backgroundColor = UIColor.red

    // Add subview and show that it has been added
    self.view?.addSubview(textView)
}

修改

我刚刚使用了您的代码,我想设法找到了导致该问题的原因。 不幸的是,我不是SpriteKit专家,所以我们必须等待一个人来获得解决方案,因为现在我正在定义问题。

简而言之-view?.presentScene(SKScene(fileNamed: "GameScene"))重新渲染了GameScene

这就是我所做的-

我已经在类中设置了一个计数器来跟踪didMove函数,但事实证明,每次点击一次presentScene调用之后,该计数器都会被重置。

然后我添加了一个必需的init来跟踪此情况,结果证明presentScene /(tap)导致必需的init再次运行,因此在调用presentScene时将重新加载整个类。

重要的是要告诉我,当我在班级范围之外定义计数器时,他会像往常一样保持正常状态-这样可以增强上述功能。

在您的情况下,它只是在删除textview之后立即添加的-并且检查它是否为nil并没有帮助,因为它为nil-该类重新加载了

启动时- On launch 轻按一次{-enter image description here