我正在尝试从超视图中删除子视图和视图,并将它们设置为nil。我注意到方法removeFromSuperview
没有将它们设置为nil,这不是我想要的。我得到的错误是在loadingViewSubviews[i] = nil
行。它说:无法通过下标分配,loadingViewSubviews是不可变的。我怎么能克服这个?
这是我在viewDidDisappear
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
var loadingViewSubviews = loadingView.subviews
if loadingView != nil{
for var i = 0; i < loadingViewSubviews.count; ++i{
loadingViewSubviews[i].removeFromSuperview()
loadingViewSubviews[i] = nil
}
loadingView.removeFromSuperview()
loadingView = nil
}
}
编辑:此代码创建loadingView及其子视图
var activityIndicator: UIActivityIndicatorView!
var activityLabel:UILabel!
var loadingView: UIView!
func processingIAP() {
if loadingView == nil{
activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.WhiteLarge)
activityIndicator.hidesWhenStopped = true
let labelRect = CGRectMake(activityIndicator.frame.width+6, 0, 200, activityIndicator.frame.height+12)
activityLabel = UILabel(frame: labelRect)
activityLabel.text = "Accessing store..."
activityLabel.textColor = UIColor.whiteColor()
activityLabel.adjustsFontSizeToFitWidth = true
activityLabel.textAlignment = NSTextAlignment.Center
let rect = CGRectMake(sceneView.frame.width/2.0-(activityIndicator.frame.width/2.0 + activityLabel.frame.width/2.0+12), sceneView.frame.height/2.0-(activityIndicator.frame.height/2.0), activityIndicator.frame.width + activityLabel.frame.width+24, activityIndicator.frame.height+12)
loadingView = UIView(frame: rect)
loadingView.backgroundColor = UIColor.blackColor()
self.sceneView.addSubview(loadingView)
loadingView.addSubview(activityIndicator)
loadingView.addSubview(activityLabel)
loadingView.layer.cornerRadius = 3
loadingView.layer.borderWidth = 3
loadingView.layer.borderColor = UIColor.whiteColor().CGColor
activityIndicator.frame.origin = CGPointMake(6, (loadingView.frame.height-activityIndicator.frame.height)/2.0)
activityIndicator.startAnimating()
}else{
activityLabel.text = "Accessing store..."
activityIndicator.startAnimating()
activityLabel.frame.origin.x += activityIndicator.frame.width
activityLabel.frame.size.width -= activityIndicator.frame.width
}
}
答案 0 :(得分:2)
如果从superview中删除loadingview,那么它的所有子视图也会被释放。无需遍历所有子视图:
for subview:UIView in self.view.subviews {
subview.removeFromSuperview()
}
答案 1 :(得分:2)
如果你有对你的子视图的引用,它甚至不会从superview中删除自己。
你可以这样做,但在目标c:
while (self.subviews.count > 0) {
id view = [self.subviews lastObject];
[view removeFromSuperview];
view = nil;
}
答案 2 :(得分:1)
您不需要将它们设置为零,因为loadingViewSubviews[i].removeFromSuperview()
已经从superView中删除了该子视图。
一个例子:
import UIKit
class FirstViewController: UIViewController {
@IBOutlet weak var loadingView: UIView!
@IBOutlet weak var l1: UILabel!
@IBOutlet weak var l2: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
var loadingViewSubviews = loadingView.subviews
if loadingView != nil{
for var i = 0; i < loadingViewSubviews.count; ++i{
loadingViewSubviews[i].removeFromSuperview()
}
loadingView.removeFromSuperview()
loadingView = nil
}
// Do any additional setup after loading the view, typically from a nib.
}
@IBAction func button(sender: AnyObject) {
print(l1)
print(l2)
}
}
在上面的示例中,所有标签都会在loadingViewSubviews[i].removeFromSuperview()
处删除,现在当您按下按钮时,您将收到崩溃错误,如:
致命错误:在解包可选值时意外发现nil
在线:
print(l1)
因为该标签在视图中不再可用,因为它已从开始删除。
答案 3 :(得分:1)
如果您在viewDidDisappear中,则无需手动删除所有子视图。这应该自动发生。如果没有,那么你在某处有一个强大的圆柱体。正确的方法是修复这个强大的循环。
您可能会创建一个点:
Settings() : goodInput(false) {}
示例:
weak var controller : Controller
示例:
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
要检查你有一个强大的参考,只需编写deinit函数并记录一些东西:
aFunctionThatHasABlock() { [weak self] parameterOfSomethingIfThere in
guard let s = self else { return } // or the controller property
s.doSomething() // If s is not there it will dont do it :)
}