我已经调试了一天,所以我不知道是什么导致了我的应用程序中的错误。如果有人能帮助我解决这个问题,那将非常好。。
因此,我从一个类名为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
现在看起来不漂亮。我现在正在研究该功能。
最后感谢您的帮助。
答案 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
做出反应的视图。
您应该重新考虑如何创建手动视图,由于目前似乎有点令人费解,我无法真正提出正确的解决方案,但是您需要使用笔尖创建方法...或创建它手动。
更新似乎其他人找到了正确的解决方案。我希望我的回答至少可以在以后帮助您再次诊断此类问题,以便您将沮丧的时间从一天缩短到可能只有一半:)
希望有帮助。