2014-06-08 21 views
10

Ich kann etwas wirklich dumm tun, aber ich kann nicht in der Lage sein, Interface Builder verwenden, um IBOutlet-Variablen mit benutzerdefinierten Ansichten zu verbinden, aber nur in Swift.Swift, Iboutlet und benutzerdefinierte Steuerelemente

Ich habe eine Klasse namens MyView erstellt, die von UIView erstreckt. In meinem Controller habe ich eine MyView-Variable (deklariert als @IBOutlet var newView: MyView). Ich gehe in IB und ziehe eine UIView auf das Fenster und gebe ihr eine Klasse von MyView.

Immer wenn ich in Objective C etwas Ähnliches gemacht habe, kann ich dann auf die View Controller-Schaltfläche oben im App-Fenster klicken, die Variable auswählen und sie zum Steuerelement ziehen, um beide miteinander zu verbinden. Wenn ich es in Swift versuche, weigert es sich zu erkennen, dass die Ansicht da ist.

Wenn ich die Klasse der Variablen in der Steuerung zu UIView ändern, funktioniert es gut. Aber nicht mit meiner benutzerdefinierten Ansicht.

Hat jemand anderes dieses Problem? Und ist es ein Feature oder nur meine Idiotie?

-Code für Controller

import UIKit 

class ViewController: UIViewController { 

    @IBOutlet var newView:MyView 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 
} 

-Code für Ansicht

import UIKit 

class MyView: UIView { 

    init(frame: CGRect) { 
     super.init(frame: frame) 
     // Initialization code 
    } 

    /* 
    // Only override drawRect: if you perform custom drawing. 
    // An empty implementation adversely affects performance during animation. 
    override func drawRect(rect: CGRect) 
    { 
     // Drawing code 
    } 
    */ 

} 
+0

Ich habe dieses Problem auch, ich denke, das ist ein Fehler, und Sie sollten es melden. –

Antwort

11

Ich habe ein ähnliches Problem gehabt, und ich denke, es ist teilweise ein Caching-Problem und teilweise nur ein Xcode6/Swift Ausgabe. Der erste Schritt, den ich fand, war, sicherzustellen, dass die View-Controller-SWIFT-Datei im Assistenten-Editor geladen wird, wenn "Automatisch" gewählt wird.

Mit Xcode feststellen, dass beide Dateien verknüpft sind, konnte ich manchmal control-ziehen von der Ansicht/Schaltfläche/etc. von der IB in die .Swift-Datei, musste aber oft von dem leeren Kreis in der Rinne der @IBOutlet var newView:MyView Zeile zu der Ansicht ziehen, die ich wollte, dass sie zusammenpasst.

Wenn Sie die Datei nicht erhalten können in der Assistant Editor laden dann fand ich, dass die folgende tun würde oft arbeiten:

  1. Entfernen Sie die benutzerdefinierte Klasse aus der IB Ansicht
  2. Reinigen Sie das Projekt (cmd + K)
  3. Schließen/öffnen Xcode
  4. Möglicherweise wieder sauber?
  5. die benutzerdefinierte Klasse hinzufügen die Ansicht zurück
  6. Hoffe, es funktioniert :)

Wenn das Sie auf halbem Weg zu bekommen scheint/nirgends einen Kommentar hinzufügen, und ich werde sehen, ob es etwas, was ich tat auslöst

+1

Thanks.None davon tatsächlich das direkte Problem behoben (Ziehen von einem vorhandenen @IBOutlet in die benutzerdefinierte Ansicht im IB-Fenster), stellte jedoch einen alternativen Ansatz - Ziehen aus dem MyView im IB-Fenster in den Assistenten-Editor, der erstellt (und Links) das relevante IBOutlet. Dies scheint den gleichen Gesamtbedarf zu erreichen. – hobart

+0

Haken aus dem leeren Kreis in der Gosse hat den Trick! Vielen Dank! – jomafer

3

In meinem Fall import UIKit fehlte, nach dem Hinzufügen dieser Zeile konnte ich wieder ein IBOutlet aus dem Storyboard erstellen.

0

Ich hatte ein ähnliches Problem zu dem in diesem Thread beschrieben. Vielleicht hast du vielleicht eine Lösung gefunden, aber niemand, dem das in Zukunft begegnet.Ich habe den Schlüssel gefunden ist, die "erforderlich init" Funktion wie folgt zu verwenden:

required init(coder aDecoder: NSCoder) { 
    print("DrawerView: required init") 
    super.init(coder: aDecoder)! 
    screenSize = UIScreen.mainScreen().bounds 
    screenWidth = screenSize.width 
    screenHeight = screenSize.height 
    self.userInteractionEnabled = true 
    addCustomGestureRecognizer() 
} 

Dies ist die komplette Klasse meiner benutzerdefinierten Ansicht:

Import UIKit Import Foundation

Klasse DrawerView : UIView {

var screenSize: CGRect! 
var screenWidth: CGFloat! 
var screenHeight: CGFloat! 

var drawerState: Int = 0 

override init (frame : CGRect) { 
    print("DrawerView: main init") 
    super.init(frame : frame) 
} 

override func layoutSubviews() { 
    print("DrawerView: layoutSubviews") 
    super.layoutSubviews() 
} 

convenience init() { 
    self.init(frame:CGRect.zero) 
} 

required init(coder aDecoder: NSCoder) { 
    print("DrawerView: required init") 
    super.init(coder: aDecoder)! 
    screenSize = UIScreen.mainScreen().bounds 
    screenWidth = screenSize.width 
    screenHeight = screenSize.height 
    self.userInteractionEnabled = true 
    addCustomGestureRecognizer() 
} 

func addCustomGestureRecognizer(){ 
    print("DrawerView: addCustomGestureRecognizer") 
    let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(self.handleDrawerSwipeGesture(_:))) 
    swipeDown.direction = UISwipeGestureRecognizerDirection.Down 
    self.addGestureRecognizer(swipeDown) 
    let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(self.handleDrawerSwipeGesture(_:))) 
    swipeUp.direction = UISwipeGestureRecognizerDirection.Up 
    self.addGestureRecognizer(swipeUp) 
    print("DrawerView self: \(self)") 
} 

func minimizeDrawer(){ 
    UIView.animateWithDuration(0.25, delay: 0.0, options: .CurveEaseOut, animations: { 
     //   let height = self.bookButton.frame.size.height 
     //   let newPosY = (self.screenHeight-64)*0.89 
     //   print("newPosY: \(newPosY)") 
     self.setY(self.screenHeight*0.86) 
     }, completion: { finished in 
      self.drawerState = 0 
      for view in self.subviews { 
       if let _ = view as? UIButton { 
        let currentButton = view as! UIButton 
        currentButton.highlighted = false 
       } else if let _ = view as? UILabel { 
        let currentButton = view as! UILabel 
        if self.tag == 99 { 
         currentButton.text = "hisotry" 
        } else if self.tag == 999 { 
         currentButton.text = "results" 
        } 
       } 
      } 
    }) 
} 

func handleDrawerSwipeGesture(gesture: UIGestureRecognizer) { 
    print("handleDrawerSwipeGesture: \(self.drawerState)") 
    if let swipeGesture = gesture as? UISwipeGestureRecognizer { 
     switch self.drawerState{ 
     case 0: 
      if swipeGesture.direction == UISwipeGestureRecognizerDirection.Down { 
       // nothing to be done, mini and swiping down 
       print("mini: !") 
      } else { 
       // mini and swiping up, should go to underneath city box 
       UIView.animateWithDuration(0.25, delay: 0.0, options: .CurveEaseOut, animations: { 
        let toYPos:CGFloat = 128 + 64 + 8 
        self.setY(toYPos) 
        }, completion: { finished in 
         self.drawerState = 1 
         for view in self.subviews { 
          if let _ = view as? UIButton { 
           let currentButton = view as! UIButton 
           currentButton.highlighted = true 
          } else if let _ = view as? UILabel { 
           let currentLabel = view as! UILabel 
           currentLabel.text = "close" 
          } 
         } 

       }) 
      } 
      break; 
     case 1: 
      if swipeGesture.direction == UISwipeGestureRecognizerDirection.Down { 
       // open and swiping down 
       self.minimizeDrawer() 
      } else { 
       // open and swiping up, nothing to be done 
      } 
      break; 
     default: 
      break; 
     } 
    } 
} 

}

Hoffe, das hilft ...

Verwandte Themen