如何引用 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 来解决操场控件的非交互性问题,但结果是,窗口只是在操场后面闪现。

在对NSProcessNSBundleNSApplication 进行一些探索并观察系统 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 本身?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查 Playground 的 swift 版本?

永远不会调用 Deinit 方法 - Swift Playground

如何在 Playground 中导入 Swift 包?

如何在 Playground 中使用 Swift 包管理器

如何使用 Swift 在 Playground 中获取用户交互事件

如何将数据从 Playground 页面传递到 Swift Playgrounds 中的另一个 Playground 页面?