我需要动态地在我的应用中为labels
添加点按功能(以打开网站),我在考虑在class
内创建静态功能。我想在我的应用的任何ViewController
中启动该功能。
我使用Swift 3完成了这个:
class Launcher {
static func openWeb(label: UILabel, url: String) {
func tapFunction(sender:UITapGestureRecognizer) {
if #available(iOS 10.0, *) {
UIApplication.shared.open(URL(string: url)!, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(URL(string: url)!)
}
}
let tap = UITapGestureRecognizer(target: self, action: #selector(tapFunction))
label.isUserInteractionEnabled = true
label.addGestureRecognizer(tap)
if #available(iOS 10.0, *) {
UIApplication.shared.open(URL(string: url)!, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(URL(string: url)!)
}
}
}
但是不起作用,因为我在action: #selector(tapFunction)
错误:Argument of '#selector' cannot refer to local function 'tapFunction(sender:)'
如果我在使用ViewController
的{{1}}代码中使用此功能,请执行以下操作
内部action: #selector(myView.tapFunction)
viewDidLoad
let tap = UITapGestureRecognizer(target: self, action: #selector(MyViewController.tapFunction))
mylabel.isUserInteractionEnabled = true
mylabel.addGestureRecognizer(tap)
ViewController
我想将此最后一个代码转换为func tapFunction(sender:UITapGestureRecognizer) {
if #available(iOS 10.0, *) {
UIApplication.shared.open(URL(string: url)!, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(URL(string: url)!)
}
}
内的静态函数,以便在任何Class
中调用它。谢谢
答案 0 :(得分:2)
应该与实例通信的方法不能是静态/类方法。这就是静态/类方法的含义;它是关于类 - 故事中没有实例。因此,你提出的建议是不可能的,除非你把静态方法交给它应该与之交谈的实例。
就我个人而言,一个可打开的URL开放标签听起来像一个标签子类,然后这个功能就是该标签的实例方法。
答案 1 :(得分:2)
尝试使用扩展程序
解决此问题
extension UILabel {
func openWeb(url: String) {
let tap = UITapGestureRecognizer(target: self, action: #selector(tapFunction))
self.isUserInteractionEnabled = true
self.addGestureRecognizer(tap)
openURL(url: url)
}
func tapFunction(sender:UITapGestureRecognizer) {
openURL(url: "")
}
func openURL(url: String) {
if #available(iOS 10.0, *) {
UIApplication.shared.open(URL(string: url)!, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(URL(string: url)!)
}
}
}
let label = UILabel()
label.openWeb(url: "123")
要将链接存储到标签中,您可以使用与标签对象的关联。
答案 2 :(得分:1)
首先,您的方法存在一些常见问题。选择器通过消息传递工作。例如。 with UITapGestureRecognizer(target:, action:)
调用方法的消息(action
)将发送到变量(target
)。
当您创建本地函数时,该函数是封闭函数的成员而不是包含的类或实例,因此您的方法明确无法工作。
即使它可以工作,它也会违反OOP和MVC设计原则。 Label
不应该负责在点击时发生的事情,就像书的标题不负责打开书一样。
考虑到所有这些,这就是我解决问题的方法:
extension UIViewController {
func addTapGesture(to view: UIView, with selector: Selector) {
view.isUserInteractionEnabled = true
view.addGestureRecognizer(UITapGestureRecognizer(target: view, action: selector))
}
}
extension UIApplication {
func open(urlString: String) {
if #available(iOS 10.0, *) {
open(URL(string: urlString)!, options: [:], completionHandler: nil)
} else {
openURL(URL(string: urlString)!)
}
}
}
class YourVC: UIViewController {
var aLabel: UILabel? = nil
func addTapGesture() {
addTapGesture(to: aLabel!, with: #selector(tapGestureActivated))
}
func tapGestureActivated(gesture: UITapGestureRecognizer?) {
UIApplication.shared.open(urlString: "YourURLHere")
}
}
这抽象了样板,在使用时很简单,同时仍然正确地分离出Type责任并使用可在其他地方重复使用的通用功能。