transformar transferir reiniciar pasar mac iniciar convertir como cambiar archivos ios objective-c uiscrollview autolayout uicollectionview

ios - reiniciar - transferir archivos de mac a windows 10



iOS 7: consejos de diseƱo (6)

Tengo el siguiente diseño en mi controlador de vista. Quiero poder desplazarme verticalmente con el encabezado deslizándose fuera de la vista y UISegmentedControl pegado a la parte superior de la vista, más allá de eso, el desplazamiento restante debe ser manejado por la Vista de Colección.

Sin embargo, estoy un poco confundido en cuanto a cuál es el mejor enfoque para implementar este diseño.

Intenté algunas implementaciones con resultados mixtos:

  1. UIScrollView con UICollectionView como subvistas: UIScrollView como vista principal con el encabezado, control segmentado y vistas de colección como controles secundarios. El problema con este enfoque es que el desplazamiento anidado no parece funcionar correctamente. Para poder desplazar el UIScrollView, el tap debe estar fuera del área CollectionView, de lo contrario solo CollectionView se desplaza y el encabezado y el control segmentado no se mueven.

  2. Encabezado y control segmentado en la celda de encabezado: Intenté otro enfoque utilizando un solo CollectionView. Agregué el encabezado y el Control segmentado como subvistas de una sola celda de encabezado de la vista de colección. Cuando se modificó el valor de control segmentado, cambio la propiedad del origen de datos de CollectionView para lograr las 3 vistas requeridas para la vista de colección. Visualmente todo funciona a la perfección. El único problema aquí es la condición de carrera cuando se cambia rápidamente entre la primera, segunda y tercera pestañas. Cargué los datos de un servicio web, si el servicio web lleva tiempo y todavía estoy cargando los datos y cambio rápidamente las pestañas, entonces encuentro errores donde los datos devueltos son para una vista de colección diferente a la que está seleccionada actualmente, mucho de problemas de sincronización fuera de servicio.

  3. Actualizar el valor constante para Restricción de autodiseño: Otro enfoque que probé es cambiar el valor constante de la restricción de diseño automático aplicada a la vista "Encabezado". Luego agregué un gesto a la vista del controlador de vista para seguir el desplazamiento, mientras el usuario se desplaza verticalmente. Ajusto la constante de la restricción de diseño automático para que la celda del "encabezado" aparezca fuera de la vista. De nuevo, esto no parece funcionar tan bien, pero supongo que puedo modificarlo, pero parece una especie de truco.

¿Hay una mejor manera de implementar este diseño?


# 2 parece una buena solución: los gestos de desplazamiento serán más consistentes con lo que esperan los usuarios, ya que es una sola vista de desplazamiento. (Estoy de acuerdo en que # 3 suena como un hack). Puede hacer que el encabezado sea "adhesivo" con algunos atributos de diseño personalizados .

El único problema aquí es la condición de carrera cuando se cambia rápidamente entre la primera, segunda y tercera pestañas.

Este es un problema común con la carga asincrónica cuando se cambian las vistas (especialmente cuando está cargando datos en celdas individuales, que se están reutilizando a medida que se desplaza). Es importante que al recibir los datos siempre verifique si el receptor todavía lo está esperando; es decir, debe verificar el valor de control segmentado antes de cambiar la fuente de datos de respaldo. También podrías:

  • Utilice objetos de origen de datos separados para los diferentes segmentos, y cada uno gestione su propia obtención de datos para que no se mezclen.
  • Cancele las solicitudes pendientes, si puede, al cambiar rápidamente las pestañas, para evitar solicitudes de red innecesarias.
  • Datos de caché para evitar volver a buscar cada vez que cambia de pestañas.

Creo que quieres la misma funcionalidad que tiene la página de perfil de pinterest . Para implementar dicha funcionalidad de manera sencilla, debe hacer lo siguiente.

Paso 1 : agregue UIView como tableHeaderView a aquellos que presumen mientras se desplazan hacia arriba.

self.tableHeaderView = yourView

Paso 2 : agregue UISegmentControl en la vista de encabezado de sección.

- (UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section{ return your_segmentcontrolView; }

Paso 3 : agregue UICollectionView en la primera fila de la primera sección.

Al implementar la siguiente forma, puede obtener la funcionalidad deseada.

Espero que esto te ayude



Todo lo que puedo decir es que necesita subclase UIView y convertirlo en delegado de UIGestureRecognizerDelegate y UICollectionViewDelegate, luego en su subclase UIView, haga lo siguiente, no puedo dar más información sobre esto porque el código, aunque es propiedad de mí mismo, es patentada hasta el punto de probablemente enfurecer a bastantes organizaciones para las que he usado esto, así que aquí está la salsa secreta:

CGPoint contentOffset = [scrollView contentOffset]; CGFloat newHeight = [_headerView maxHeight] - contentOffset.y; CGRect frame = [_headerView frame]; if (newHeight > [_headerView maxHeight]) { frame.origin.y = contentOffset.y; frame.size.height = [_headerView maxHeight]; [_headerView setFrame:frame]; } else if (newHeight < [_headerView minHeight]) { frame.origin.y = contentOffset.y; frame.size.height = [_headerView minHeight]; [_headerView setFrame:frame]; } else { frame.origin.y = contentOffset.y; frame.size.height = newHeight; [_headerView setFrame:frame]; } if ([_delegate respondsToSelector:@selector(scrollViewDidScroll:)]) { return [_delegate scrollViewDidScroll:scrollView]; }

Debe crear una subclase de otra UIView que se defina como el encabezado de este UiCollectionView personalizado. Luego, debe declarar la vista de encabezado personalizado de UIView dentro de la subvista personalizada del delegado UIView / UICollectionView, y luego establecer el encabezado de esa subvista personalizada dentro de UICollctionViewdelegate. A continuación, debe insertar esta subclase compuesta de UIView / UIcollectionView en su UIViewController. Oh sí, y en su layoutSubViews, asegúrese de hacer los cálculos de altura que pasan a través de una subclase de doble capa. Por lo tanto, tendrá los siguientes archivos:

  1. UIVew este es el delegado de UICollectionView y lo que mencioné antes

  2. UIView esto es un UISCrollViewDelegate y esta es la vista de encabezado

  3. UIViewController que extrae el UIView subclasificado en el número 1

  4. Subclase UIView del número 1 que extrae el número 2 y lo establece como su encabezado

En la parte número 4, asegúrese de hacer algo como esto:

- (CGFloat)maxHeight { if (SCREEN_WIDTH == 414) { return 260; }else if (SCREEN_WIDTH == 375) { return 325; }else { return 290; } } - (CGFloat)minHeight { if (SCREEN_WIDTH == 414) { return 90; }else if (SCREEN_WIDTH == 375) { return 325; }else { return 290; } }

Esto luego pasará a la subclase UIView que es una subclase compuesta como ya expliqué. La idea es capturar el encabezado maxHeight of you en la subclase de este encabezado UIView (número 2 arriba), y luego pasarlo a la subclase UIView principal que intercepta estos valores en el scrollViewDidScroll.

Último tidbit de información, asegúrese de configurar su layoutSubviews en todos los métodos para interceptar eventos de desplazamiento. Por ejemplo, en el número 1 anterior, el método layoutsubviews es el siguiente:

- (void)layoutSubviews { CGRect frame = [_headerView frame]; frame.size.width = [self frame].size.width; [_headerView setFrame:frame]; [super layoutSubviews]; }

Esto es todo lo que puedo darte, desearía poder publicar más, pero esto debería darte una idea de cómo se hace en entornos de producción para las aplicaciones más importantes que ves en la naturaleza.

Una cosa más a tener en cuenta. Cuando comiences a recorrer el camino de implementaciones intensas como esta, no te sorprendas al descubrir que, por ejemplo, un controlador de vista único en una aplicación que funciona con métodos como los que he explicado tendrá entre 30 y 40 subclases personalizadas. que son subclases por derecho propio o subclases compuestos o subclases de mis propias subclases o mis propias subclases. Te lo digo para que te hagas una idea de la cantidad de código que se necesita para hacer esto bien, no para asustarte, sino para hacerte saber que puede llevarte un tiempo acertar y no darte una patada en el culo. si toma un tiempo para hacer el trabajo. ¡¡Buena suerte!!


Un enfoque alternativo que podrías considerar:

Use una UITableView para contener su UI

  • Cree una UITableView y configure su encabezado como headerView de UITableView.
  • Use un header de sección para contener segmentedControl.
  • Coloque su collectionView dentro de una sola UITableViewCell. O, alternativamente, puede usar el footerView de UITableView para contener el gridView.

Al usar SectionHeader, esto debería permitir que el encabezado se desplace fuera de la vista, pero luego el sectionHeader se pegará debajo de la barra de navegación o la parte superior del contentView hasta que otra sección aparezca a la vista (y en su caso solo tendrá una sección).


  • Agregue vista de encabezado, vista de cuerpo (sosteniendo la vista de segmento y la vista de colección) en la vista de desplazamiento.
  • Inicialmente, establezca la propiedad userInteractionEnabled en "NO" para la vista de colección.
  • Sigue el insecto de la vista de desplazamiento siempre.
  • Si la coordenada y del insecto desplazado es mayor que el alto de la vista del encabezado, establezca la propiedad userInteractionEnabled en "YES" para que luego se pueda desplazar la vista de recopilación.
  • Si el usuario se desplaza fuera de la vista de desplazamiento y trata de bajar la vista de encabezado, es decir, la vista de desplazamiento y el insecto de la coordenada Y es menor que el alto de la vista de encabezado, cambie inmediatamente el modo de iteración del usuario de la vista de colección y permita al usuario desplazarse por la vista de desplazamiento hasta la cima