4 Stimmen

Unterklassen von UIButton, die aus Nibs geladen werden, werden nicht richtig initialisiert

Ich habe eine sehr einfache Unterklasse von UIButton:

@interface MyButton : UIButton
@end

@implementation MyButton

- (id) initWithCoder:(NSCoder *)decoder
{
    if (!(self = [super initWithCoder:decoder]))
        return nil;

    NSLog(@"-[%@ initWithCoder:%@]", self, decoder);

    return self;
}

@end

Im Interface Builder füge ich einen UIButton hinzu, setze seinen Button-Typ auf Abgerundetes Rechteck und seine Klassenidentität auf MyButton .

Bei der Ausführung erhalte ich das folgende Protokoll:

-[<MyButton: 0x5b23970; baseClass = UIButton; frame = (103 242; 114 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x5b23a90>> initWithCoder:<UINibDecoder: 0x6819200>]

aber die Schaltfläche ist keine runde rechteckige Schaltfläche mehr.

Beobachtet sowohl unter iOS 3.2 als auch unter iOS 4.

Ist dies ein Fehler oder übersehe ich etwas Offensichtliches?

Eine Instanz von MyButton programmatisch erstellen ist keine akzeptable Antwort, danke.

4voto

DarkDust Punkte 87647

Programmatisch instanziieren Sie eine Schaltfläche mit +[UIButton buttonWithType:] die eigentlich eine Fabrik ist, die eine Unterklasse von UIButton zurückgibt. Wenn Sie also von UIButton ableiten, leiten Sie eigentlich nicht von Ihrer runden, rechteckigen Button-Klasse ab ( UIRoundedRectButton ), sondern von einer generischen Schaltflächenklasse. Es ist jedoch nicht erlaubt, eine Unterklasse von UIRoundedRectButton AFAIK, da es eine interne Klasse ist.

Es scheint problematisch zu sein, von UIButton abzuleiten, ich habe gesehen, eine Menge Leute empfohlen, von UIControl stattdessen abzuleiten und die Zeichnung selbst zu implementieren.

Aber vielleicht finden Sie diese Artikel hilfreich:

Wie überschreibt man -drawrect in der UIButton-Unterklasse?

http://www.cocoabuilder.com/archive/cocoa/284622-how-to-subclass-uibutton.html

http://www.cimgf.com/2010/01/28/fun-with-uibuttons-and-core-animation-layers/

Ich weiß auch nicht, warum Sie von UIButton ableiten wollen, aber wenn Sie eine Anpassung vornehmen wollen, bei der keine anderen Methoden überschrieben werden müssen, könnte es hilfreich sein, die Tatsache zu nutzen, dass Sie so etwas tun können:

- (id)initWithCoder:(NSCoder *)decoder {
   // Decode the frame
   CGRect decodedFrame = ...;
   [self release];
   self = [UIButton buttonWithType:UIButtonTypeRoundedRect];
   [self setFrame:decodedFrame];
   // Do the custom setup to the button
   return self;
}

0voto

Rob Rix Punkte 358

Ich bin nicht sicher, ob dies für Ihre Bedürfnisse akzeptabel ist, aber ich ziehe es vor, die -awakeFromNib 代わりに -initWithCoder: unter diesen Umständen. Löst dies das Problem, das Sie sehen?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X