代表出于某种原因为空

时间:2018-10-25 16:31:30

标签: ios swift

我已经调试了一天,所以我不知道是什么导致了我的应用程序中的错误。如果有人能帮助我解决这个问题,那将非常好。

因此,我从一个类名为UIView的{​​{1}}文件创建了一个自定义Nib ManualScreen 基本上是xibsetup()扩展名,仅从UIView文件加载。我想将按钮点击从我的视图发送到Nib。我没有直接将此视图添加到ViewController中,因为当ViewController移动到另一个选项时,我需要删除此ManualScreen视图并在其位置添加另一个视图。

Segment Control

class ManualScreen: UIView { var mManualViewListener:ManualViewListener! required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } override init(frame: CGRect) { super.init(frame: CGRect.zero) xibSetup() } @IBOutlet weak var counterLabel: UILabel!{ didSet { print("labelView: \(String(describing: counterLabel))") } } @IBAction func addButton(_ sender: UIButton) { if(mManualViewListener != nil){ ->>>this is always nil for some reason print("insdie the listener counting") mManualViewListener.addCount() }else{ print("listener is nil") } } func addListener(manualViewListener:ManualViewListener){ print("adding listener") mManualViewListener = manualViewListener } } 已在UIView中初始化,并且此Viewcontroller还实现了我的Viewcontroller协议。在delegate中初始化customView时,通过执行

将此Viewcontroller添加为Viewcontroller
delegate

我的委托协议是

var manualScreen = ManualScreen()
manualScreen.addListener(manualViewListener: self)

设置了侦听器后,我应该可以使用protocol ManualViewListener { func addCount() } 从我的视图向ViewController发送一些事件(此处为按钮触摸)。但是它说我的manualViewListener.addcount()总是零。

我在这里只写了一小部分代码,因为编写所有内容都不可行。如果有人想查看整个应用程序,请点击manualViewListener链接到我正在工作的东西。 https://github.com/Rikenm/Auto-Counter-iOS

现在看起来不漂亮。我现在正在研究该功能。

最后感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

您的问题在这里

override init(frame: CGRect) {    
    super.init(frame: CGRect.zero)   

    xibSetup()  // this is the problem maker 
}

您在其上方添加了一个相同类的新视图,并确保它的侦听器对象与在此处实例化的屏幕视图为零

mManualScreen = ManualScreen()
mManualScreen.addListener(manualViewListener: self)

//

  extension UIView{

    func xibSetup() {
        let view = loadFromNib()
        addSubview(view)
        stretch(view: view)
    }

//    2. Loads the view from the nib in the bundle
    /// Method to init the view from a Nib.
    ///
    /// - Returns: Optional UIView initialized from the Nib of the same class name.
    func loadFromNib<T: UIView>() -> T {
        let selfType = type(of: self)
        let bundle = Bundle(for: selfType)
        let nibName = String(describing: selfType)
        let nib = UINib(nibName: nibName, bundle: bundle)

        guard let view = nib.instantiate(withOwner: self, options: nil).first as? T else {
            fatalError("Error loading nib with name \(nibName) ")
        }

        return view
    }
  }

相反,您需要

var mManualViewListener:ManualViewListener! 

static func loadFromNib() -> ManualScreen {

   let view = Bundle.main.loadNibNamed("ManualScreen", owner: self, options: nil)?.first  as! ManualScreen
    return view
}

使用

mManualScreen = ManualScreen.loadFromNib()

mManualScreen.addListener(manualViewListener: self)

答案 1 :(得分:2)

问题是您要创建2个单独的ManualScreen实例。您的方法xibSetup创建并返回另一个 ManualScreen实例,并将其添加为附加到详细视图控制器的第一个ManualScreen的子视图。如果您在addManualScreen()的{​​{1}}内设置一个断点并检查DetailViewController的子视图,则会看到另一个子视图。

因此,您要将mManualScreen委托属性设置为mManualViewListener,但是将额外的ManualScreen(不应创建)作为{{1 }}正在拦截该动作,并且那个视图没有附加ManualScreen

您应该修复视图实例化,以仅创建xibSetup()的一个实例,然后才能解决问题。

答案 2 :(得分:0)

我尝试在您的代码中添加几个断点。看来您添加视图的方式有点(很多?)。

设置断点

首先,我在第89行的addManualScreen方法中添加了一个断点:

containerView.addSubview(mManualScreen)

ManualScreen本身的另一个断点,函数addButton,第51行:

if(mManualViewListener != nil){

第一个断点命中

好的,断点一击。此时的mManualScreen是什么?

po mManualScreen

除其他事项外,为我们提供对象ID Auto_Counter.ManualScreen: 0x7fcfebe018d0

代表设置了吗?

po mManualScreen.mManualViewListener

实际上是:some : <Auto_Counter.DetailViewController: 0x7fcfeb837fb0>

第二个断点命中

确定,当我点击+按钮时,第二个断点被击中。仍然设置mManualListener吗?

po mManualViewListener

不,我们得到nil

然后让我们看一下对象本身

po self

给我们

Auto_Counter.ManualScreen: 0x7fcfe8d4b300

等等,那不是相同的对象ID!

问题

现在看看xibSetup

func xibSetup() {
    let view = loadFromNib()
    addSubview(view)
    stretch(view: view)
}

在这里创建第二个/内部视图!这就是对您的@IBAction做出反应的视图。

解决方案

您应该重新考虑如何创建手动视图,由于目前似乎有点令人费解,我无法真正提出正确的解决方案,但是您需要使用笔尖创建方法...或创建它手动。

更新似乎其他人找到了正确的解决方案。我希望我的回答至少可以在以后帮助您再次诊断此类问题,以便您将沮丧的时间从一天缩短到可能只有一半:)

希望有帮助。