我将A类中的选择器传递给B类中的方法,最终从A类触发委托方法PressedButtonForMethodA
。但是,我认为我的选择器出了问题,因为代理人都没有方法或ClassB的PressedButtonForMethodA()
(ClassB.PressedButtonForMethodA()仅用于调试目的)正在执行。使用Swift 3和NO故事板。这就是我在快捷的游乐场里所拥有的:
import UIKit
import PlaygroundSupport
class classA: UIViewController, ClassBDelegate {
private func setNavbarButtons() {
let myBarButton = classB()
myBarButton.delegate = self
let myBarButtonItem = myBarButton.setup("Press This", #selector(PressedButtonForMethodA))
self.navigationItem.rightBarButtonItem = myBarButtonItem
}
func PressedButtonForMethodA() {
NSLog("Method A in Class A fired!") // <<--THIS METHOD NOT BEING CALLED
}
}
protocol ClassBDelegate {
func PressedButtonForMethodA()
}
class classB: UIView {
var delegate: ClassBDelegate?
func setup(_ title: String, _ selectorAction: Selector) -> UIBarButtonItem {
let shadow = NSShadow()
shadow.shadowColor = UIColor.clear
let attributesNormal = [
NSForegroundColorAttributeName : UIColor.white,
NSShadowAttributeName : shadow,
NSFontAttributeName : UIFont.boldSystemFont(ofSize: 12.0)
]
let button = UIButton(type: .custom)
let buttonTitleAttributesNormal = NSAttributedString(string: title,
attributes: attributesNormal)
button.setAttributedTitle(buttonTitleAttributesNormal, for: UIControlState.normal)
let buttonTextSize = button.intrinsicContentSize
button.frame = CGRect(x: 0, y: 0, width: buttonTextSize.width, height: buttonTextSize.height)
button.addTarget(self, action: selectorAction, for: .touchUpInside)
let barButtonItem = UIBarButtonItem(customView: button)
return barButtonItem
}
func PressedButtonForMethodA() {
NSLog("Method A in Class B fired!") // <<-- THIS METHOD NOT FIRED EITHER
delegate?.PressedButtonForMethodA()
}
}
答案 0 :(得分:2)
let myBarButtonItem = myBarButton.setup("Press This", #selector(PressedButtonForMethodA))
应该是
let myBarButtonItem = myBarButton.setup("Press This", #selector(myBarButton.PressedButtonForMethodA))
在设置方法中,当您从ClassB传递选择器时,您将从ClassA传递选择器,因为您在此处添加了self
作为目标:
button.addTarget(self, action: selectorAction, for: .touchUpInside)
答案 1 :(得分:2)
完成编辑:
我对此有了更多的考虑,并且通过几种方式进行了解决,并提出了两个合理的选择。不确定这两种方法是否会被认为是“更好”,但我想我会倾向于方法#1。我认为它更加独立,并且不需要委托符合。 (忽略我的另一个答案,如果你已经看到了......我将两者合二为一。)
方法#1
classB是一个UIBarButtonItem子类。调用setup()传递标题,Selector / Action(自我内部的一个函数)和一个对self的引用(它将用作按钮Action的目标)。
class ClassAB: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setNavbarButtons()
}
private func setNavbarButtons() {
let myBarButton = classB()
myBarButton.setup("Press Me AB", #selector(ClassAB.PressedButtonForMethodAB), self)
self.navigationItem.rightBarButtonItem = myBarButton
}
func PressedButtonForMethodAB() {
NSLog("Method AB in Class AB fired!")
}
}
class classB: UIBarButtonItem {
func setup(_ title: String, _ selectorAction: Selector, _ target: Any) {
let shadow = NSShadow()
shadow.shadowColor = UIColor.clear
let attributesNormal = [
NSForegroundColorAttributeName : UIColor.white,
NSShadowAttributeName : shadow,
NSFontAttributeName : UIFont.boldSystemFont(ofSize: 12.0)
]
let button = UIButton(type: .custom)
let buttonTitleAttributesNormal = NSAttributedString(string: title, attributes: attributesNormal)
button.setAttributedTitle(buttonTitleAttributesNormal, for: UIControlState.normal)
let buttonTextSize = button.intrinsicContentSize
button.frame = CGRect(x: 0, y: 0, width: buttonTextSize.width, height: buttonTextSize.height)
// my navbar is white...
button.backgroundColor = UIColor.blue
// target and action both assigned by the creator (in this case, ClassAB)
button.addTarget(target, action: selectorAction, for: .touchUpInside)
customView = button
}
}
方法#2
classC是一个UIBarButtonItem子类。调用setup()传递标题,并将self指定为classC的委托。在classC中,按钮Action是一个类级别的函数,它依次调用已定义的委托函数。
class ClassAC: UIViewController, ClassCDelegate {
override func viewDidLoad() {
super.viewDidLoad()
setNavbarButtons()
}
private func setNavbarButtons() {
let myBarButton = classC()
myBarButton.setup("Press Me AC")
myBarButton.delegate = self
self.navigationItem.rightBarButtonItem = myBarButton
}
func PressedButtonForMethodAC() {
NSLog("Method AC in Class AC fired!")
}
}
protocol ClassCDelegate {
func PressedButtonForMethodAC()
}
class classC: UIBarButtonItem {
var delegate: ClassCDelegate?
func setup(_ title: String) {
let shadow = NSShadow()
shadow.shadowColor = UIColor.clear
let attributesNormal = [
NSForegroundColorAttributeName : UIColor.white,
NSShadowAttributeName : shadow,
NSFontAttributeName : UIFont.boldSystemFont(ofSize: 12.0)
]
let button = UIButton(type: .custom)
let buttonTitleAttributesNormal = NSAttributedString(string: title, attributes: attributesNormal)
button.setAttributedTitle(buttonTitleAttributesNormal, for: UIControlState.normal)
let buttonTextSize = button.intrinsicContentSize
button.frame = CGRect(x: 0, y: 0, width: buttonTextSize.width, height: buttonTextSize.height)
// my navbar is white...
button.backgroundColor = UIColor.blue
// target is self, selector action is inside self... *that* is where we'll call back to the delegate
button.addTarget(self, action: #selector(classC.classCTap), for: .touchUpInside)
customView = button
}
func classCTap() {
NSLog("tap inside ClassC ... call back to delegate method")
delegate?.PressedButtonForMethodAC()
}
}