上下文: 我創建的UIView(爲helloView)的子類顯示一些文本和一個按鈕在我MainViewController視圖的頂部。 這個子類在MainVC viewDidLoad
初始化,並添加到視圖:view.addSubview(helloView)
self.removeFromSuperview()UIView子類內
目的:爲helloView具有一個UIButton(continueButton)與目標dimissHelloView
。此方法只需簡單地調用self.removeFromSuperView()
即可輕鬆獲取屏幕上的helloView。
問題:用戶與按鈕的交互會中斷代碼並返回一個零指針異常(意外地發現零,同時展開可選值)。儘管SO和Google搜索有幾個小時,但我無法通過自己的按鈕子視圖找到解除視圖的正確方法。
以前的疑難解答:當調用removeFromSuperview時,看起來superview爲零,但如果我使用斷點並在控制檯中調用它,則不是。
代碼:忽略屬性和約束塊,按鈕創建和目標操作在底部。
import UIKit
class HelloView: UIView {
var helloText: String = ""
var continueButton: UIButton!
override init(frame: CGRect) {
super.init(frame: frame)
didLoad()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
didLoad()
}
func didLoad(){
self.translatesAutoresizingMaskIntoConstraints = false
setContinueButton()
self.addSubview(continueButton)
}
override func didMoveToSuperview() {
setConstraints()
}
func setConstraints(){
//remove any previous constraints
for constraint in superview!.constraints {
if constraint.firstItem as! UIView == self && constraint.secondItem as? UIView == superview {
superview!.removeConstraint(constraint)
}
}
// Hello View basic constraints
let xAxisConstraint = NSLayoutConstraint(item: self, attribute: .CenterX, relatedBy: .Equal, toItem: superview, attribute: .CenterX, multiplier: 1, constant: 0)
let yAxisConstraint = NSLayoutConstraint(item: self, attribute: .CenterY, relatedBy: .Equal, toItem: superview, attribute: .CenterY, multiplier: 1, constant: 0)
// check device orientation and add constraints consequently
if UIDeviceOrientationIsLandscape(UIDevice.currentDevice().orientation) {
let widthConstraint = NSLayoutConstraint(item: self, attribute: .Width, relatedBy: .Equal, toItem: superview, attribute: .Width, multiplier: 1, constant: -100)
let heightConstraint = NSLayoutConstraint(item: self, attribute: .Height, relatedBy: .Equal, toItem: superview, attribute: .Height, multiplier: 1, constant: -150)
superview!.addConstraints([xAxisConstraint, yAxisConstraint, widthConstraint, heightConstraint])
}
if UIDeviceOrientationIsPortrait(UIDevice.currentDevice().orientation){
let widthConstraint = NSLayoutConstraint(item: self, attribute: .Width, relatedBy: .Equal, toItem: superview, attribute: .Width, multiplier: 1, constant: -100)
let heightConstraint = NSLayoutConstraint(item: self, attribute: .Height, relatedBy: .Equal, toItem: superview, attribute: .Height, multiplier: 1, constant: -300)
superview!.addConstraints([xAxisConstraint, yAxisConstraint, widthConstraint, heightConstraint])
}
// Continue Button constraints
let centerXConstraint = NSLayoutConstraint(item: continueButton, attribute: .CenterX, relatedBy: .Equal, toItem: self, attribute: .CenterX, multiplier: 1, constant: 0)
let bottomConstraint = NSLayoutConstraint(item: continueButton, attribute: .Bottom, relatedBy: .Equal, toItem: self, attribute: .Bottom, multiplier: 1, constant: -8)
self.addConstraints([centerXConstraint, bottomConstraint])
}
func setContinueButton(){
continueButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
continueButton.setTitle("Continue", forState: .Normal)
continueButton.setTitleColor(UIColor.whiteColor(), forState: .Normal)
continueButton.addTarget(self, action: #selector(HelloView.dismissHelloView), forControlEvents: .TouchUpInside)
continueButton.translatesAutoresizingMaskIntoConstraints = false
}
func dismissHelloView(){
print(superview!)
self.removeFromSuperview()
}
}
非常感謝@zpasternack,我沒有意識到didMoveToSuperview被調用removeFromSuperview!爲提前回報添加警戒聲明解決了問題。 –