如何引用 Swift Playground 本身?
Posted
技术标签:
【中文标题】如何引用 Swift Playground 本身?【英文标题】:How to reference Swift Playground itself? 【发布时间】:2014-06-08 16:11:19 【问题描述】:来自How to create a button programmatically?
self 在 swift playground 中不起作用:
button.addTarget(self, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside)
错误:
游乐场执行失败:错误::42:13:错误:使用 未解析的标识符“自我”
我还尝试创建一个带有 buttonAction 方法的类,它可以编译,但是当我单击按钮时,控制台中没有任何内容
import UIKit
class myself
func buttonAction(sender:UIButton!)
println("Button tapped")
var s = myself()
// Create View
var f = CGRect(x:0,y:0,width:200,height:200)
var view = UIView(frame:f)
// Create Button
var b = UIButton(frame: f)
b.setTitle("Hello", forState: UIControlState.Normal)
b.addTarget(s, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside)
view.addSubview(b)
view
【问题讨论】:
那是你的完整代码吗?您不能在某种类方法之外引用self
@BergQuester 是的,我知道自己,这就是我要求替代方案的原因:如何引用我定义 buttonAction func 的操场?我也尝试自己创建一个类,但是当我单击按钮时它不打印任何内容(请参阅代码更新)
我认为这是不可能的,因为现在 swift playground 无法模拟输入。在这种情况下触摸事件
明白了。是的,游乐场实际上不是互动的。是的,在某些情况下您可以及时来回擦洗,但实际上无法与控件进行交互。
@BergQuester 真可惜我哭了:(
【参考方案1】:
不幸的是,playground 中的控件不是交互式的。
前几天,我尝试通过为 Mac 操场创建并显示 NSWindow
来解决操场控件的非交互性问题,但结果是,窗口只是在操场后面闪现。
在对NSProcess
、NSBundle
、NSApplication
进行一些探索并观察系统 Activity Monitor 之后,我能说的最好的情况是,操场实际上会编译您的代码,将其加载到存根应用程序中,然后执行,操场捕获结果并显示它们,然后存根应用程序退出或等待下一次执行。这意味着当您看到结果时,代码已不再执行。
如果您好奇,可以在操场上尝试下面的代码,看看我的意思。如果您打开活动监视器并过滤PlaygroundStub_OSX
,您可以看到运行代码启动的进程。它经常处于“无响应”状态。我还包含了代码探测部分结果的屏幕截图。
import Cocoa
var app = NSApplication.sharedApplication()
app.hidden
var procInfo = NSProcessInfo.processInfo()
procInfo.processName
procInfo.arguments
var bundle = NSBundle.mainBundle()
bundle.bundlePath
var window = NSWindow(contentRect: NSRect(x: 30, y: 30, width: 400, height: 400), styleMask: NSTitledWindowMask, backing: .Buffered, defer: false)
var view = NSView(frame: NSRect(x: 0, y: 0, width: 300, height: 300))
var textField = NSTextField(frame: NSRect(x: 30, y: 30, width: 100, height: 20))
textField.stringValue = "Test"
view.addSubview(textField)
var button = NSButton(frame: NSRect(x: 30, y: 60, width: 100, height: 30))
button.highlight(true)
var buttonCell:NSButtonCell = button.cell() as NSButtonCell
buttonCell.bezelStyle = NSBezelStyle.RoundedBezelStyle
view.addSubview(button)
window.contentView.addSubview(view)
window.makeKeyAndOrderFront(nil)
更新
我能够在 Swift 操场上获得一个半功能的 OS X 窗口,并将代码放在 github repo 中。我不确定是否可以使用基于交互式 UIKit 的视图。
【讨论】:
【参考方案2】:现在 Xcode 7.3 支持此功能。您需要声明一个 ObjectiveC 对象或使用 @objc
关键字作为目标公开一个函数:
class Responder : NSObject
func action()
print("Button pressed!")
let containerView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 375.0, height: 667.0))
XCPlaygroundPage.currentPage.liveView = containerView
let responder = Responder()
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
button.backgroundColor = UIColor.greenColor()
button.setTitle("TEST", forState: .Normal)
button.addTarget(responder, action: #selector(Responder.action), forControlEvents: .TouchUpInside)
containerView.addSubview(button)
【讨论】:
这行得通!但是,您应该在描述中添加两件事。 1) 导入 XCPlayground 2) 在助手编辑器中显示元素。 如何在action()方法中调用containerView变量【参考方案3】:我用 Cocoa 成功地做到了这一点。
让你的类成为 NSObject 的子类。在您的类中创建一个 NSWindow 并将按钮和操作移动到您的类中。然后你可以将按钮的目标设置为self。
用 UIKit 试试,如果它有效,请告诉我们。
【讨论】:
以上是关于如何引用 Swift Playground 本身?的主要内容,如果未能解决你的问题,请参考以下文章
永远不会调用 Deinit 方法 - Swift Playground
如何使用 Swift 在 Playground 中获取用户交互事件
如何将数据从 Playground 页面传递到 Swift Playgrounds 中的另一个 Playground 页面?