我试图根据这个问题从.xb文件中加载视图:
Assign xib to the UIView in Swift
我的设置如下:
从我正在加载视图的XIB文件中包含一个单独的UIVIEW
SuffVIEW.SWIFT——StripView.xib的UIVIEW的“所有者”,包含StripView.xib的每个组件的引用/ IbExchange
swift-视图控制器,它加载一个StripView实例并处理大部分逻辑/数据源/委托的内容。
这一切在xcode6beta4中运行良好,然而,升级到xcode6beta5(最新的)中断。在应用程序启动时,我只是得到一个空白的黑色屏幕。应用程序的所有其他部分似乎工作正常。只有当我试图将uipickerview(由stripview拥有)的委托或数据源设置为stripviewcontroller时,才会出现此错误。
代码段:
class StripViewController: SWRevealViewController, RSColorPickerViewDelegate, UIPickerViewDataSource, UIPickerViewDelegate, BLEDelegate, UIActionSheetDelegate, UITextFieldDelegate {
var stripView: StripView!
var colorPicker: RSColorPickerView!
var connectBtn:UIButton!
var connectionSpinner:UIActivityIndicatorView!
var tapRecognizer:UITapGestureRecognizer!
init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// use UIView extension as per https://stackoverflow.com/questions/24370061/assign-xib-to-the-uiview-in-swift
stripView = UIView.loadFromNibNamed("StripView") as StripView
self.view.addSubview(stripView)
// nav bar setup //
self.title = "Strip \(self.tabBarController.selectedIndex+1)"
let leftNav:UIView = UIView(frame: CGRectMake(0,0,100,40))
self.connectBtn = UIButton(frame: CGRectMake(0,0,95,40))
connectBtn.frame = CGRectMake(0,0,connectBtn.bounds.size.width,connectBtn.bounds.size.height)
connectBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left
connectBtn.setTitle("Connect", forState: UIControlState.Normal)
connectBtn.setTitleColor(UIColor(red: 0.0, green: 122.0/255.0, blue: 1.0, alpha: 1.0), forState: UIControlState.Normal)
connectBtn.addTarget(self, action: "connectButtonPressed:", forControlEvents: UIControlEvents.TouchDown)
leftNav.addSubview(connectBtn)
self.connectionSpinner = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
connectionSpinner.frame = CGRectMake(connectBtn.frame.minX + connectBtn.bounds.size.width, connectBtn.frame.minY + 10, connectionSpinner.bounds.size.width, connectionSpinner.bounds.size.height)
connectionSpinner.hidesWhenStopped = true
leftNav.addSubview(connectionSpinner)
let leftNavItem:UIBarButtonItem = UIBarButtonItem(customView: leftNav)
self.navigationItem.leftBarButtonItem = leftNavItem
// set up color picker
colorPicker = RSColorPickerView(frame: CGRectMake(20, 78, 160, 160))
self.view.addSubview(colorPicker)
colorPicker.delegate = self
// set up mode picker
// THESE APPEAR TO BE THE OFFENDING LINES —
// COMMENTING THEM OUT DISPLAYS THE VIEW AS EXPECTED
self.stripView.modePicker.dataSource = self;
self.stripView.modePicker.delegate = self;
// set up notifications
NSNotificationCenter.defaultCenter().addObserver(self, selector: "colorFieldDidChange:", name: "ColorFieldDidChangeNotification", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
// set up UI and populate fields
self.stripView.setAnimSpeed()
// set up BLE
BLEManager.instance.ble.delegate = self
}
[...]
再一次,冒犯的字眼似乎是:
self.stripView.modePicker.dataSource = self;
self.stripView.modePicker.delegate = self;
如果我把它们注释掉,其他的都会正常显示。我甚至尝试将委托/数据源移动到stripview.swift(不是stripviewcontroller),但我看到了相同的结果。
下面是实现uipickerviewdatasource和uipickerviewdelegate方法的strippviewcontroller部分:
func numberOfComponentsInPickerView(pickerView: UIPickerView!) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView!, numberOfRowsInComponent component: Int) -> Int {
return DataModel.instance.ModeNames.count
}
func pickerView(pickerView: UIPickerView!, titleForRow row: Int, forComponent component: Int) -> String! {
return DataModel.instance.ModeNames[row]
}
func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int) {
// send mode to arduino
println("--- sending mode select command ---")
var buf:[UInt8] = [0x00, 0x00, 0x00, 0x00]
buf[0] = Modes.instance.SET_MODE
buf[1] = UInt8(DataModel.instance.ModeOpcodes[DataModel.instance.ModeNames[row]]!)
let data:NSData = NSData(bytes: buf, length: 4)
BLEManager.instance.ble.write(data)
}
swift语言处理委托/数据源或从xib加载视图的方式有什么变化吗?
编辑:
我已经将问题缩小到了作为数据源使用的数据模型singleton。这段代码(datamodel.swift)看起来是这样的,按照https://github.com/hpique/SwiftSingleton实现了一个基本的单例模式:
class DataModel {
// setup singleton
class var instance: DataModel {
struct Static {
static let instance : DataModel = DataModel()
}
return Static.instance
}
// modes
// eventually may replace this with a more flexible data structure
// for now, we just need names
let ModeNames: Array<String> = ["Light All", "Rainbow"]
let ModeOpcodes: Dictionary<String, UInt8> = [DataModel.instance.ModeNames[0]: Modes.instance.LIGHT_ALL, DataModel.instance.ModeNames[1]: Modes.instance.RAINBOW];
}
用strippiewcontroller中定义的变量替换此实例可以使工作正常。作为一个单身汉,有些事情似乎让人失望。思想?也许单例没有被正确地实例化?
最佳答案
很容易忽略的一件事是将数据源和委托连接到视图控制器本身。除了按ctrl键拖动出口外,还需要按ctrl键将数据源和委托从连接检查器拖动到脚本中视图顶部的小视图控制器图标。
关于xcode - 尝试设置委托(delegate)/数据源时的空白/黑色 View ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25212384/