programar programacion para mac library lenguaje español developer desarrollo con apple aplicaciones iphone objective-c ios

iphone - programacion - swift apple



Cómo enmascarar UITableViewCells debajo de un encabezado transparente de UITableView (9)

@Alex Markman: su respuesta es excelente y me fue muy útil, pero descubrí que cuando se desplaza en los dispositivos de retina, las celdas no se desplazan sin problemas. Descubrí que está causado por el parámetro de locations la capa durante el proceso de renderizado:

mask.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:location];

Modifiqué ligeramente tu código. Tal vez alguien lo encontrará útil:

- (void)maskCellFromTop:(CGFloat)margin { self.layer.mask = [self visibilityMaskFromLocation:margin]; self.layer.masksToBounds = YES; } - (CAGradientLayer *)visibilityMaskFromLocation:(CGFloat)location { CAGradientLayer *mask = [CAGradientLayer layer]; mask.frame = CGRectMake( self.bounds.origin.x, location+self.bounds.origin.y, self.bounds.size.width, self.bounds.size.height-location); mask.colors = @[ (id)[[UIColor colorWithWhite:1 alpha:1] CGColor], (id)[[UIColor colorWithWhite:1 alpha:1] CGColor] ]; return mask; }

Quiero que el encabezado enmascare las celdas, pero no el fondo.

Tengo un UITableView con encabezados transparentes y celdas similares al Centro de notificaciones de Apple (cuando se desliza hacia abajo en la barra de estado de su iPhone). No puedo descubrir cómo enmascarar las celdas para que no aparezcan debajo del encabezado cuando se desplaza.

He intentado cambiar los contenidos de la vista de tabla y he intentado cambiar el marco de la vista de encabezado a un origen negativo.


La versión Swift 3 no me funcionó porque agregué el UITableViewController como una subvista. Así que tuve que hacer algunos cambios en la extensión del scrollview.

Esto también debería funcionar con UITableViewController que se han enviado desde otro ViewController (Nota: no probado)

extension NavNotitionTableViewController { override func scrollViewDidScroll(_ scrollView: UIScrollView) { for cell in tableView.visibleCells { let calculatedY = cell.frame.origin.y - scrollView.contentOffset.y; if let customCell = cell as? NavNotitionTableViewCell { if(calculatedY < 44 && calculatedY > 0){ let hideAmount = 44 - calculatedY; if let customCell = cell as? NavNotitionTableViewCell { customCell.maskCell(fromTop: hideAmount) } }else if (calculatedY > 0){ //All other cells customCell.maskCell(fromTop: 0) }else if (calculatedY < 0){ customCell.maskCell(fromTop: cell.frame.height); } } } } }

En este ejemplo, primero obtengo el origen del cuadro Y de la celda y distraigo el contenido de scollViewsOffsetY.

La altura de mi sección personalizada es 44. Así que defino el valor de hideAmount para la máscara.

Las funciones celulares están intactas:

public func maskCell(fromTop margin: CGFloat) { layer.mask = visibilityMask(withLocation: margin / frame.size.height) layer.masksToBounds = true } private func visibilityMask(withLocation location: CGFloat) -> CAGradientLayer { let mask = CAGradientLayer() mask.frame = bounds mask.colors = [UIColor.white.withAlphaComponent(0).cgColor, UIColor.white.cgColor] let num = location as NSNumber mask.locations = [num, num] return mask }


O, si todo lo que necesitas es que tu interfaz de usuario se vea bien, podrías

cambia tu vista de tabla para no tener encabezados de sección flotantes

En dos pasos rápidos y fáciles (iOS 6):

  1. Cambie su estilo UITableView a UITableViewStyleGrouped. (Puede hacerlo desde Storyboard / NIB, o por medio de un código).

  2. A continuación, establezca la vista de fondo de su vista de tabla en una vista vacía, así que [en un método como viewDidAppear o incluso en el método cellForRow (aunque preferiría el primero)].

yourTableView.backgroundView = [[UIView alloc] initWithFrame:listTableView.bounds];

Voila, ahora tiene su vista de tabla, pero sin los encabezados de sección flotante. ¡Sus encabezados de sección ahora se desplazan junto con las celdas y se resuelven sus problemas de UI desordenados!

Intenta esto y déjame saber cómo va. Feliz codificación :)

EDITAR: para iOS 7, simplemente cambie el estilo de vista de tabla a '' UITableViewStyleGrouped '' y cambie el color del tinte de la vista a ''color claro''.


Tengo dos soluciones posibles, sin código, solo la idea:

  1. No es genérico, debería funcionar con los ajustes de Apple / Design Apple en el Centro de notificaciones.

Haga que el encabezado de la sección sea opaco, ''clone'' el patrón de fondo de la tabla como fondo del encabezado de la sección. Coloque el patrón de fondo en función del desplazamiento del encabezado de la sección.

  1. Genereico, pero probablemente mas problemas de rendimiento. Debería funcionar bien con pocas células.

Agrega una máscara alfa a todas las capas de celdas. Mueve la máscara alfa dependiendo de la posición de la celda.

(Utilice el método delegado scrollViewDidScroll para mantener el patrón de fondo / compensación de máscara alfa).


Terminé estableciendo la altura del encabezado de la sección al mínimo, y anulando las vistas de diseño de UITableView para colocar el encabezado en la vista de tabla del supervisor de tabla, ajustando el origen del marco hacia arriba según su altura.


Una pequeña edición sobre la respuesta de Alex Markman, donde podría omitir la creación de una subclase para un UITableViewCell. El beneficio de este enfoque es que puede usarlo para múltiples UITableViewCells diferentes.

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { for (UITableViewCell *cell in self.tableView.visibleCells) { CGFloat hiddenFrameHeight = scrollView.contentOffset.y + self.navigationController.navigationBar.frame.size.height - cell.frame.origin.y; if (hiddenFrameHeight >= 0 || hiddenFrameHeight <= cell.frame.size.height) { [self maskCell:cell fromTopWithMargin:hiddenFrameHeight]; } } } - (void)maskCell:(UITableViewCell *)cell fromTopWithMargin:(CGFloat)margin { cell.layer.mask = [self visibilityMaskForCell:cell withLocation:margin/cell.frame.size.height]; cell.layer.masksToBounds = YES; } - (CAGradientLayer *)visibilityMaskForCell:(UITableViewCell *)cell withLocation:(CGFloat)location { CAGradientLayer *mask = [CAGradientLayer layer]; mask.frame = cell.bounds; mask.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithWhite:1 alpha:0] CGColor], (id)[[UIColor colorWithWhite:1 alpha:1] CGColor], nil]; mask.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:location], [NSNumber numberWithFloat:location], nil]; return mask; }


Versión Swift

func scrollViewDidScroll(_ scrollView: UIScrollView) { for cell in tableView.visibleCells { let hiddenFrameHeight = scrollView.contentOffset.y + navigationController!.navigationBar.frame.size.height - cell.frame.origin.y if (hiddenFrameHeight >= 0 || hiddenFrameHeight <= cell.frame.size.height) { maskCell(cell: cell, margin: Float(hiddenFrameHeight)) } } } func maskCell(cell: UITableViewCell, margin: Float) { cell.layer.mask = visibilityMaskForCell(cell: cell, location: (margin / Float(cell.frame.size.height) )) cell.layer.masksToBounds = true } func visibilityMaskForCell(cell: UITableViewCell, location: Float) -> CAGradientLayer { let mask = CAGradientLayer() mask.frame = cell.bounds mask.colors = [UIColor(white: 1, alpha: 0).cgColor, UIColor(white: 1, alpha: 1).cgColor] mask.locations = [NSNumber(value: location), NSNumber(value: location)] return mask; }


Versión limpia de Swift 3:

extension YourViewController: UIScrollViewDelegate { func scrollViewDidScroll(_ scrollView: UIScrollView) { for cell in tableView.visibleCells { let hiddenFrameHeight = scrollView.contentOffset.y + navigationController!.navigationBar.frame.size.height - cell.frame.origin.y if (hiddenFrameHeight >= 0 || hiddenFrameHeight <= cell.frame.size.height) { if let customCell = cell as? CustomCell { customCell.maskCell(fromTop: hiddenFrameHeight) } } } } } class CustomCell: UITableViewCell { public func maskCell(fromTop margin: CGFloat) { layer.mask = visibilityMask(withLocation: margin / frame.size.height) layer.masksToBounds = true } private func visibilityMask(withLocation location: CGFloat) -> CAGradientLayer { let mask = CAGradientLayer() mask.frame = bounds mask.colors = [UIColor.white.withAlphaComponent(0).cgColor, UIColor.white.cgColor] let num = location as NSNumber mask.locations = [num, num] return mask } }

Acabo de usar esto y funciona como un encanto. Quiero agradecer a todos en el post! ¡Hasta votos por todas partes!


Intente hacer una subclase de UITableviewCell y agregue estos métodos

- (void)maskCellFromTop:(CGFloat)margin { self.layer.mask = [self visibilityMaskWithLocation:margin/self.frame.size.height]; self.layer.masksToBounds = YES; } - (CAGradientLayer *)visibilityMaskWithLocation:(CGFloat)location { CAGradientLayer *mask = [CAGradientLayer layer]; mask.frame = self.bounds; mask.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithWhite:1 alpha:0] CGColor], (id)[[UIColor colorWithWhite:1 alpha:1] CGColor], nil]; mask.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:location], [NSNumber numberWithFloat:location], nil]; return mask; }

y agregar este método delegado en UITableView

#pragma mark - UIScrollViewDelegate - (void)scrollViewDidScroll:(UIScrollView *)scrollView { for (iNotifyTableViewCell *cell in self.visibleCells) { CGFloat hiddenFrameHeight = scrollView.contentOffset.y + [iNotifyHeaderView height] - cell.frame.origin.y; if (hiddenFrameHeight >= 0 || hiddenFrameHeight <= cell.frame.size.height) { [cell maskCellFromTop:hiddenFrameHeight]; } } }

* Tenga en cuenta que [iNotifyHeaderView height] es la altura de HeaderView . y use #import <QuartzCore/QuartzCore.h> para la celda personalizada.