我在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”。
答案 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
不再引用它。多次告诉textView
到removeFromSuperview()
不会有帮助,因为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-该类重新加载了