Apple definió claramente cómo subclasificar UIViewen el documento.
Consulte la lista a continuación, especialmente eche un vistazo a initWithFrame:y layoutSubviews. El primero está destinado a configurar el marco de su UIViewmientras que el segundo está destinado a configurar el marco y el diseño de sus subvistas.
También recuerde que initWithFrame:se llama solo si está creando instancias UIViewprogramáticamente. Si lo está cargando desde un archivo plumín (o un guión gráfico), initWithCoder:se utilizará. Y en initWithCoder:el marco aún no se ha calculado, por lo que no puede modificar el marco que configuró en Interface Builder. Como se sugiere en esta respuesta , puede pensar en llamar initWithFrame:desde initWithCoder:para configurar el marco.
Finalmente, si carga su UIViewdesde una plumilla (o un guión gráfico), también tiene la awakeFromNiboportunidad de realizar inicializaciones de marcos y diseños personalizados, ya que cuando awakeFromNibse llama se garantiza que cada vista en la jerarquía no se haya archivado e inicializado.
Del documento de NSNibAwaking(ahora reemplazado por el documento de awakeFromNib):
Los mensajes a otros objetos se pueden enviar de forma segura desde dentro de wakekeFromNib, momento en el cual se garantiza que todos los objetos no están archivados e inicializados (aunque no necesariamente despiertos, por supuesto)
También vale la pena señalar que con la distribución automática no debe establecer explícitamente el marco de su vista. En su lugar, se supone que debe especificar un conjunto de restricciones suficientes, de modo que el motor de diseño calcule automáticamente el marco.
Directamente de la documentación :
Métodos para anular
Inicialización
initWithFrame:Se recomienda que implemente este método. También puede implementar métodos de inicialización personalizados además de, o en lugar de, este método.
initWithCoder: Implemente este método si carga su vista desde un archivo plum de Interface Builder y su vista requiere una inicialización personalizada.
layerClassImplemente este método solo si desea que su vista use una capa de animación principal diferente para su almacén de respaldo. Por ejemplo, si está utilizando OpenGL ES para hacer su dibujo, debería anular este método y devolver la clase CAEAGLLayer.
Dibujo e impresión
drawRect:Implemente este método si su vista dibuja contenido personalizado. Si su vista no hace ningún dibujo personalizado, evite anular este método.
drawRect:forViewPrintFormatter: Implemente este método solo si desea dibujar el contenido de su vista de manera diferente durante la impresión.
Restricciones
requiresConstraintBasedLayout Implemente este método de clase si su clase de vista requiere restricciones para funcionar correctamente.
updateConstraints Implemente este método si su vista necesita crear restricciones personalizadas entre sus subvistas.
alignmentRectForFrame:, frameForAlignmentRect:Poner en práctica estos métodos para anular cómo sus puntos de vista están alineados con otros puntos de vista.
Diseño
sizeThatFits:Implemente este método si desea que su vista tenga un tamaño predeterminado diferente al que normalmente tendría durante las operaciones de cambio de tamaño. Por ejemplo, puede usar este método para evitar que su vista se reduzca hasta el punto en que las subvistas no se puedan mostrar correctamente.
layoutSubviews Implemente este método si necesita un control más preciso sobre el diseño de sus subvistas que la restricción o los comportamientos de autorizar.
didAddSubview:, willRemoveSubview:Poner en práctica estos métodos según sea necesario para realizar un seguimiento de las adiciones y eliminaciones de subvistas.
willMoveToSuperview:, didMoveToSuperviewImplemente estos métodos según sea necesario para rastrear el movimiento de la vista actual en su jerarquía de vistas.
willMoveToWindow:, didMoveToWindowPoner en práctica estos métodos, según sea necesario para seguir el movimiento de la vista a una ventana diferente.
Manejo de eventos:
touchesBegan:withEvent:, touchesMoved:withEvent:, touchesEnded:withEvent:, touchesCancelled:withEvent:Poner en práctica estos métodos, si usted necesita para manejar eventos de toque directamente. (Para la entrada basada en gestos, use reconocedores de gestos).
gestureRecognizerShouldBegin: Implemente este método si su vista maneja eventos táctiles directamente y puede querer evitar que los reconocedores de gestos adjuntos activen acciones adicionales.
Gabriele Petronella
fuente
layoutSubviews?Esto todavía aparece en Google. A continuación se muestra un ejemplo actualizado para swift.
La
didLoadfunción le permite poner todo su código de inicialización personalizado. Como otros han mencionado,didLoadse llamará cuando una vista se cree mediante programacióninit(frame:)o cuando el deserializador XIB combine una plantilla XIB en su vista a través deinit(coder:)fuente
drawmétodo?Hay un resumen decente en la documentación de Apple , y esto está bien cubierto en el curso gratuito de Stanford disponible en iTunes. Presento mi versión TL; DR aquí:
Si su clase se compone principalmente de subvistas, el lugar correcto para asignarlas es en los
initmétodos. Para las vistas, hay dosinitmétodos diferentes a los que se podría llamar, dependiendo de si su vista se instancia desde el código o desde una plumilla / guión gráfico. Lo que hago es escribir mi propiosetupmétodo, y luego llamarlo desde los métodosinitWithFrame:yinitWithCoder:.Si está haciendo un dibujo personalizado, de hecho desea anular
drawRect:en su vista. Sin embargo, si su vista personalizada es principalmente un contenedor para subvistas, probablemente no necesite hacer eso.Solo anule
layoutSubViewssi desea hacer algo como agregar o eliminar una subvista dependiendo de si está en orientación vertical u horizontal. De lo contrario, debería poder dejarlo solo.fuente
layoutSubViews, funcionó.layoutSubviewsestá destinado a establecer el marco en vistas secundarias, no en la vista en sí.Por lo general
UIView, el constructor designado esinitWithFrame:(CGRect)framey usted debe establecer el marco allí (o adentroinitWithCoder:), posiblemente ignorando el valor del marco pasado. También puede proporcionar un constructor diferente y establecer el marco allí.fuente
awakeFromNib