尝试设置委托/数据源时的空白/黑色视图

时间:2014-08-08 21:16:07

标签: xcode swift xcode6

我正在尝试根据此问题从.xib文件加载视图: Assign xib to the UIView in Swift

我的设置如下:

  • StripView.xib - 我从中加载视图的.xib文件,包含单个UIView
  • StripView.swift - StripView.xib中UIView的“所有者”,包含StripView.xib中每个组件的引用/ IBOutlets
  • StripViewController.swift - 视图控制器,它加载StripView实例并处理大部分逻辑/数据源/委托内容。

这在Xcode 6 Beta 4中运行良好,然而,升级到Xcode 6 Beta 5(最新版)中断。在应用程序启动时,我只是得到一个空白的黑屏。该应用程序的所有其他部分似乎工作正常。只有当我尝试将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),但我看到了相同的结果。

这是StripViewController的一部分,它实现了UIPickerViewDataSource和UIPickerViewDelegate方法:

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加载的方式是否有所改变?


编辑: 我已经将问题缩小到我用作数据源的DataModel单例。该代码(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];
}

用StripViewController中定义的变量替换它的实例会导致工作正常。关于它是一个单身人士的事似乎是在抛弃一切。思考?也许单身人士没有被正确地实例化?

1 个答案:

答案 0 :(得分:0)

容易忽视的一件事是将数据源和委托连接到视图控制器本身。除了按住Ctrl键拖动插座外,还需要按住Ctrl键拖动数据源并从连接检查器委托到故事板视图顶部的小视图控制器图标。