2014-10-28 14 views
6

Próbuję zaimplementować prostą podklasę UIButton, która jest IBDesminable. Chcę możliwość ustawienia koloru dla każdego stanu kontrolki z Kreatora interfejsów. Wiem, że jest to możliwe dzięki słowu kluczowemu IBInspectable. Mam problemy z awarią IB podczas używania KVO na własności państwowej. IBDesignable debugger zawiesza się na deinit. Czy ktoś wie, jak mogę pracować razem z KVO i IBDesminem?IBDesignable Podklasa UIButton

@IBDesignable 
class UIButtonActionButton: UIButton { 

    @IBInspectable var defaultColour: UIColor = UIColor.blueColor() { 
     didSet { 
      self.setNeedsDisplay() 
     } 
    } 

    @IBInspectable var selectedColour: UIColor = UIColor.blueColor() 

    @IBInspectable var disabledColour: UIColor = UIColor.grayColor() 

    required init(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     self._setup() 
    } 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     self._setup() 
    } 


    private func _setup(){ 
     self.addObserver(self, forKeyPath: "state", options: NSKeyValueObservingOptions.New, context: nil) 
     self.layer.cornerRadius = 5.0 
     self.layer.masksToBounds = true 
    } 

    override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) { 
     self.setNeedsDisplay() 
    } 

    override func drawRect(rect: CGRect) { 
     super.drawRect(rect) 
     let context = UIGraphicsGetCurrentContext() 

     if self.highlighted { 
      CGContextSetFillColorWithColor(context, selectedColour.CGColor) 
      CGContextFillRect(context, self.bounds) 
     } else if self.state == UIControlState.Disabled { 
      CGContextSetFillColorWithColor(context, disabledColour.CGColor) 
      CGContextFillRect(context, self.bounds) 
     } else { 
      CGContextSetFillColorWithColor(context, defaultColour.CGColor) 
      CGContextFillRect(context, self.bounds) 
     } 
    } 

    deinit { 
     self.removeObserver(self, forKeyPath: "state", context: nil) 
    } 

} 

Odpowiedz

6

miałem coś podobnego problemu była metoda init() który spowodował awarię po refactoring mojego kodu działa jak czar. Może to pomoże:

#if !TARGET_INTERFACE_BUILDER 
required init(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder) 
    self._setup() 
} 
#endif 

override func prepareForInterfaceBuilder() { 
    self._setup() 
} 
+1

Dzięki za tip Daniela. Próbowałem powyższego, a teraz skarżą się, że moje właściwości IBInspectable nie są zgodne z kodami kluczowymi. Tak więc uciekłem się do używania makra do dodawania/usuwania obserwatora tylko podczas pracy. Zaakceptowanie tej odpowiedzi dla końcówki MACRO. –

6

Dla Xcode 7.2 wspólny kod @IBDesignable UIButton Subclass wygląda następująco:

import UIKit 

@IBDesignable class MyButton: UIButton { 

    //this init fires usually called, when storyboards UI objects created: 
    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     self.setupViews() 
    } 

    //This method is called during programmatic initialisation 
    override init(frame: CGRect) { 
     super.init(frame: frame) 
     setupViews() 
    } 


    func setupViews() { 
     //your common setup goes here 
    } 

    //required method to present changes in IB 
    override func prepareForInterfaceBuilder() { 
     super.prepareForInterfaceBuilder() 
     self.setupViews() 
    } 
} 
+0

Zauważyłem, że jeśli usuniesz wywołanie "setupViews()' '' w '' 'init (frame:)' '', konfiguracja nadal działa w IB i aplikacji. Czy jest jakiś powód, dla którego musimy wywołać setup z tego init? –

+0

@PaulVanWieren ciekawe. Jak pamiętam, to nie działa. Ustaw punkt przerwania wewnątrz 'setupViews()' i sprawdź, kto go nazywa :) – skywinder

+5

@PaulVanWieren - Metoda init (frame :) jest używana przy tworzeniu widoków w kodzie. Widoki utworzone w storyboardach i stalach używają metody init (koder :). Nie jest wymagana żadna metoda init (frame :), jeśli nie zamierzasz tworzyć widoków w kodzie, ale zwykle jest ona dołączana do kompletności. –