without ios uiview uikit subclass init

ios - without - uiviewcontroller swift



iOS: subclase UIView init o initWithFrame:? (3)

Hice una subclase de UIView que tiene un marco fijo. Entonces, ¿puedo simplemente anular init lugar de initWithFrame: :? P.ej:

- (id)init { if ((self = [super initWithFrame:[[UIScreen mainScreen] bounds]])) { self.backgroundColor = [UIColor clearColor]; } return self; }

La documentación de Xcode para -initWithFrame: dice: "Si crea un objeto de vista mediante programación, este método es el inicializador designado para la clase UIView . Las subclases pueden anular este método para realizar cualquier inicialización personalizada pero deben llamar a super al comienzo de su implementación. "

¿Qué significa "inicializador designado"?


El inicializador designado es el que todos los demás inicializadores deben llamar. UIView y las subclases son un tanto inusuales ya que en realidad tienen dos de estos inicializadores: -initWithFrame: y -initWithCoder: según cómo se cree la vista. Debería sobrescribir -initWithFrame: si está instanciando la vista en código, y -initWithCoder: código -initWithCoder: si lo está cargando desde un plumín. O bien, puede poner su código en el tercer método y anular ambos inicializadores de manera que llamen a su tercer método. De hecho, esa es a menudo la estrategia recomendada.

Entonces, por ejemplo, puede crear una subclase UIView, ClueCharacter , que tenga su propio método de inicialización: -initWithPerson:place:thing: A continuación, crea tu vista de esta manera:

Obj-C:

ClueCharacter *mustard = [[ClueCharacter alloc] initWithPerson:@"Col. Mustard" place:kInTheStudy thing:kTheRope];

Rápido:

var mustard = ClueCharacter("Col. Mustard", place: kInTheStudy, thing: kTheRope)

Está bien, pero para inicializar la parte del objeto UIView, su método debe llamar al inicializador designado:

Obj-C:

-(id)initWithPerson:(NSString*)name place:(CluePlace)place thing:(ClueWeapon)thing { if ((self = [super initWithFrame:CGRectMake(0, 0, 150, 200)])) { // your init stuff here } }

Rápido:

func init(name: String, place : CluePlace, thing : ClueWeapon) { if (self = super.init(CGRectMake(0, 0, 150, 200))) { // your init stuff here } }

Si desea llamar al inicializador de su subclase, está bien siempre que llame a -initWithFrame: en la implementación.


En una clase Objective-C con múltiples inicializadores, el inicializador designado es el que hace el trabajo significativo. Entonces, a menudo tienes una clase con algunos iniciadores, por ejemplo:

- (id)initWithRect:(CGRect)someRect; - (id)initWithRect:(CGRect)someRect setDefaultColour:(BOOL)setDefaultColour; - (id)initWithRect:(CGRect)someRect setDefaultColour:(BOOL)setDefaultColour linkTo:(id)someOtherObject;

En ese caso, normalmente (pero no siempre) diría que el tercero fue el inicializador designado e implementará los otros dos como, por ejemplo,

- (id)initWithRect:(CGRect)someRect { return [self initWithRect:someRect setDefaultColour:NO]; } - (id)initWithRect:(CGRect)someRect setDefaultColour:(BOOL)setDefaultColour { return [self initWithRect:someRect setDefaultColour:setDefaultColour linkTo:nil]; }

Si una clase tiene solo un inicializador, ese es el inicializador designado.

En su caso, para seguir las mejores prácticas, debe implementar initWithFrame: y también un init: vainilla init: que invoca initWithFrame: con sus dimensiones normales. La convención normal es que puede agregar nuevas variaciones en init en subclases, pero no debe eliminarlas, y que siempre hace el trabajo de inicialización real en el inicializador designado. Esto permite que cualquier método de inicialización de la clase principal que no proporcione nuevas implementaciones todavía funcione apropiadamente con su subclase.


en UIView llamando a [super init] es exactamente igual a [super initWithFrame:CGRectZero]